problem using PwmOut functions after using a constructor

19 Jun 2011

I am trying to setup the pwm outputs, i've used a constructor to assign the hardware as there's a few variations of pin assignments and a few generic input functions being used. here's the code:

in .h file

\#include "mbed.h"
class SC_Encoder : public Encoder
{
    private:
    ..

    ..
    /* output hardware */
    PwmOut* channel_s;
    PwmOut* channel_c;
    ..
 
    ..
     void reset();
};

in .cpp file

#include "mbed.h"
#define pwmperiod 0.000125
SC_Encoder::SC_Encoder()
{
    /*
        Set up the hardware for this encoder
    */  
    channel_s = new PwmOut(p24);
    channel_c = new PwmOut(p25);

    reset();
}

void SC_Encoder::reset()
{  
    /*
        Reset internal variables to default states
    */
    ..

    ..
    channel_s.period(pwmperiod);
     
}

The problem is that that the period function is returning an error on compile.

expression must have a class type(E153)

The PWM outputs can be set using the = operator when the period function is commented out and i can compile the code.

any ideas as to what I'm doing wrong?

Thanks, Chris

19 Jun 2011

To dereference a member field of a pointer type such as channel_s or channel_c, you must use -> instead of .

    channel_s->period(pwmperiod);

Another solution might be to not even use pointers for these members. You could do something like this instead:

#include "mbed.h"

class SC_Encoder
{
public:
    SC_Encoder();
    
    private:
    /* output hardware */
    // NOTE: Not using pointers here anymore
    PwmOut channel_s;
    PwmOut channel_c;
    void reset();
};

// NOTE: channel_s and channel_c are initialized on the next line instead of in the body of the method
SC_Encoder::SC_Encoder() : channel_s(p24), channel_c(p25)
{
    reset();
}

void SC_Encoder::reset()
{  
    /*
        Reset internal variables to default states
    */
    channel_s.period(0.1f);
}

int main() 
{
    SC_Encoder TestEncoder();
    
    for(;;)
    {
    }
}
19 Jun 2011

Thanks, I understand a little more about pointers now. Changing . to -> got the problem sorted.

If i was to use the alternative method would i be able to pass the PWM output to a function like so:

   set_channel_state( channel_s, channel_s_mode, 0.5);  

void SC_Encoder::set_channel_state( PwmOut output, Dig_Channel_Mode mode, float pwm_value )    
{

or am I right to be using pointers to do this?

19 Jun 2011

If you passed the PWMOut object to a function like this then you would be passing shallow copies of the objects since they are passed by value and not by reference. However, you can switch them to references in C++ by making this change to the method:

void SC_Encoder::set_channel_state( PwmOut& output, Dig_Channel_Mode mode, float pwm_value )

The & symbol after the type in the function declaration converts it to a reference. You don't have to change the way you make the call.

There is nothing wrong with the use of pointers. However, when doing embedded programming, I try to minimize my use of dynamic memory allocation (the use of the new operator and malloc function) so that is the benefit of the alternate approach that I showed you.