Go Down

Topic: Passing class-member function to another class (Read 539 times) previous topic - next topic


I'm creating a project to turn on & off my home's heat tapes (to melt snow on the roof to prevent ice dams) daily using the TimeAlarms.h library.
I'd like to create a HeatTape class that manages everything internally, including passing the onTickHandler (which is a function called by alarmRepeat). I'd like to define the onTickHandler within the HeatTape class because it uses a variable set within the class.
In my code below, I'd like to pass the HeatTapeClass::turnOn and HeatTapeClass::TurnOff functions to Alarm.alarmRepeat, but can not seem to do so. I've tried many variations including &HeatTape::turnOn without success.

Any suggestions are appreciated.

Code: [Select]

#include <Time.h>
#include <TimeAlarms.h>
class HeatTapeClass {

    // Properties
    char name[10];
    byte powerPin;
    byte programPin;
    byte hourOnLocation;
    byte minuteOnLocation;
    byte hourOffLocation;
    byte minuteOffLocation;
    AlarmId startAlarm;
    AlarmId endAlarm;

    // Methods
    void init(char *theName,
              byte thePowerPin,
              byte theProgramPin,
              byte theHourOnLocation,
              byte theMinuteOnLocation,
              byte theHourOffLocation,
              byte theMinuteOffLocation
              ) {
      strcpy(name, theName);
      powerPin = thePowerPin;
      programPin = theProgramPin;
      hourOnLocation = theHourOnLocation;
      minuteOnLocation = theMinuteOnLocation;
      hourOffLocation = theHourOffLocation;
      minuteOffLocation = theMinuteOffLocation;
      startAlarm = Alarm.alarmRepeat( getHourOn(),
                                      00, // seconds
                                      turnOn // <----- how do I pass the HeatTapeClass::turnOn function here?

      endAlarm = Alarm.alarmRepeat(   getHourOff(),
                                      00, // seconds

    boolean isOn() {
      return digitalRead(powerPin);
    void turnOn() {
      digitalWrite(powerPin, HIGH);

    void turnOff() {
      digitalWrite(powerPin, LOW);

    void toggleOnOff() {
      digitalWrite(powerPin, !(isOn()));

    boolean isProgramEnabled() {
      return digitalRead(programPin);
    void enableProgram() {
      digitalWrite(progamPin, HIGH);
    void disableProgram() {
      digitalWrite(programPin, LOW);

    byte getHourOn()    { return EEPROM.read(hourOnLocation); };
    byte getMinuteOn()  { return EEPROM.read(minuteOnLocation); };
    byte getHourOff()   { return EEPROM.read(hourOffLocation); };
    byte getMinuteOff() { return EEPROM.read(minuteOffLocation); };
    void setHourOn(byte value)    { EEPROM.write(hourOnLocation, value); };
    void setMinuteOn(byte value)  { EEPROM.write(minuteOnLocation, value); };
    void setHourOff(byte value)   { EEPROM.write(hourOffLocation, value); };
    void setMinuteOff(byte value) { EEPROM.write(minuteOffLocation, value); };


   From very distant memory, you can only pass a static function as a callback function, static functions are associated with the class, not any individual instance (object) of the class so you will not have access to your object variables, only status variables.

   As all your doing is turning pins on and off, I might suggest that you take off your perfectly valid but may be out of context 'object orientated' hat and put on your microcontroller 'how can i get this done in 2k memory' hat and have another look at what your trying to do.

   Just a suggestion and there is nothing wrong with trying to do it in objects other than in this case your are inventing problems for yourself - i.e. how do I use half a dozen layers of complexity to change a pin.

Duane B



Objects are fine to use, micro controllers are no reason not to take advantage of the C++ offerings.
This topic may help you, http://www.parashift.com/c++-faq-lite/pointers-to-members.html


   Quoting from the link provided by the previous poster -


[33.2] How do I pass a pointer-to-member-function to a signal handler, X event callback, system call that starts a thread/task, etc?


As I mentioned in my original response, an object orientated approach is valid, but in a micro controller you are much closer to the hardware and sometimes it good to acknowledge this and enjoy the differences.

If you want to continue with the OO approach, I would suggest that you revisit your objects so that they are less tightly coupled - i.e. should the alarms be inside the heat tape object - could you achieve what you want more easily if they were outside ?

Duane B.



Thanks for the responses. I was hoping for a "just put a -> after the variable and it'll work" type of answer. DuaneB: Your comments are interesting because I'm basically rewriting my original working sketch (which also includes buttons, LED displays, a web server and thermostat control) to make it object oriented. One of the first things that occurred to me is that, although the OO code is more understandable, extensible and compact from a coding perspective, I'm using more RAM. I'm not sure about more Flash but it wouldn't surprise me. pYro_65: the paradshift link greatly increased my understanding of this subject - Thanks!


Go Up