timeout attach to C++ function

31 Jan 2011

If I use the timeout with a c function I get the address of the function to call with &f.

If I try to do this inside a C++ class to get the function address I get the error :

"Nonstandard form for taking the address of a member function ... I think I get a pointer to a object ?

How can I get the pointer to the class member function to attach the timeout?

Regards, Peter

31 Jan 2011

Hi Peter,

For attaching a member function to a Timeout or Ticker (assuming this is what you mean), you need to pass both the pointer to the member function, and the pointer to the object you want to call it on. The pointer to the object could be "this" if you are attaching it within a method of the class itself.

I've just added another example to the Handbook:

And you can see the full API for the attach function here:

Hope this is what you were after.

Simon

31 Jan 2011

You need to use

&CLASSNAME::FUNCTIONNAME

for the address, and need to supply a pointer to the object in question too (there are always overloaded functions in the mbed classes for that).

31 Jan 2011

Hi, my code for a beeper:

Beep.h:

#ifndef MBED_BEEP_H
#define MBED_BEEP_H
  
#include "mbed.h"
 
namespace mbed {
 
/* Class: Beep
 *  A class witch uses pwm to controle a beeper to generate sounds.
 */
class Beep {
 
public:
    
/* Constructor: Beep
 *  Creates a new beeper object.
 * 
 * Variables:
 *  pin - The pin which is connected to the beeper.
 */
 Beep (PinName pin);
 
/* Function: beep
 *  Beep with given frequency and duration.
 *
 * Variables: 
 *  frequency - The frequency to use.
 *  time - The turation to beep.
 */
void beep (float frequency, float time);
 
void nobeep(); 

private :    
     PwmOut _pwm;
    
 };
 
 }
#endif

Beep.c

#include "beep.h"
#include "mbed.h"

using namespace mbed;
    // constructor         
    Beep::Beep(PinName pin) : _pwm(pin) {
        _pwm.write(0.0);     // after creating it have to be off       
    }
    
    // switch off
    void Beep::nobeep() {
        _pwm.write(0.0); 
        }

    // beep
    void Beep::beep(float freq, float time) {
        Timeout toff;
        _pwm.period(1.0/freq);
        _pwm.write(0.5);            // 50% duty cycle - beep on
        toff.attach(this,&Beep::nobeep, time);   // time to off
        }

The Timeout is not called. If I use the nobeep function the beep end.

Peter

31 Jan 2011

Hi, I found the bug. The Timeout have to be declared outside the function beep. It have to be active after the end of the function.

#include "beep.h"
#include "mbed.h"

using namespace mbed;
    // constructor         
    Beep::Beep(PinName pin) : _pwm(pin) {
        _pwm.write(0.0);     // after creating it have to be off       
    }
    
    // switch off
    void Beep::nobeep() {
        _pwm.write(0.0); 
        }

    Timeout toff;

    // beep
    void Beep::beep(float freq, float time) {
        
        _pwm.period(1.0/freq);
        _pwm.write(0.5);            // 50% duty cycle - beep on
        toff.attach(this,&Beep::nobeep, time);   // time to off
        }

will work.

Peter

31 Jan 2011

Yes, each stack-allocated object gets destroyed automatically at the end of the defining function. You either need to define it globally (like you did) or dynamically via new.

31 Jan 2011

Hi Peter,

Some additional notes for completeness.

In your last example, the code will work because you have declared a global timeout object called toff. But note it may not actually be the ideal approach as you may actually really want to make it a member of the Beep class, just like the PwmOut object. Having a global object means it is shared by any and all instances of the Beep class, which (although you might not see them in this case) could cause problems if that is not what was intended.

If you make the Timeout a member of the class, like PwmOut, every instance of this object would include a Timeout object.

So for example, you could do the following:

Beep.h

#ifndef MBED_BEEP_H
#define MBED_BEEP_H
  
#include "mbed.h"

class Beep {
public:
    Beep (PinName pin);
    void beep (float frequency, float time); 
    void nobeep(); 

private :    
    PwmOut _pwm;
    Timeout _toff;
 };

#endif

and

Beep.cpp

#include "Beep.h"
#include "mbed.h"

Beep::Beep(PinName pin) : _pwm(pin) {
    _pwm.write(0.0);     // after creating it have to be off       
}
    
void Beep::nobeep() {
    _pwm.write(0.0); 
}

void Beep::beep(float freq, float time) {
        
    _pwm.period(1.0/freq);
    _pwm.write(0.5);            // 50% duty cycle - beep on
    _toff.attach(this,&Beep::nobeep, time);   // time to off
}

Now you can see that it is attaching to the timeout which is part of the Beep object, so you can create as many Beep's as you want :)

Hope that is useful.

Simon

01 Feb 2011

Thanks Simon. I have published the code as Beep and attach Javadoc doku, but I don't see my doku.

Import librarybeep

Make noise with a piezo buzzer. Use a pwm pin.

Peter

01 Feb 2011

Peter Drescher wrote:

I have published the code as Beep and attach Javadoc doku, but I don't see my doku.

You could try 2 things:

  • the comment right above the class should start with /** (the comment at the beginning of the file will be ignored AFAIK)
  • start the text of you comment in the second line, maybe it confuses the doc-extraction tool when you write text there

Apart from that it looks fine.