Search code examples
c++arduinocallback

How to pass a class member function that modifies class members to a function that takes a function pointer


I am writing software for an Arduino-powered weather station.

I have a class for each of the sensor systems (some simple, some complex) and the rain gauge one needs to use the Arduino attachInterrupt function.
Signature:

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(), int mode)

This is used to execute a callback when a pin changes state, which increment a counter (which is a member variable of the class).

I currently have the following:

// `pulses` and `pin` are member variables.
void RainGauge::begin()
{
  pulses = 0;
  attachInterrupt(digitalPinToInterrupt(pin), callback, FALLING);
}

I need to somehow define that callback.

I have tried this, without success, due to the capturing aspect:

void RainGauge::begin()
{
  pulses = 0;
  auto callback = [this](void) {
    pulses++;
  };
  attachInterrupt(digitalPinToInterrupt(pin), callback, FALLING);
}

This gives the error no suitable conversion function from "lambda []()->void" to "void (*)()" existsC/C++(413).

Is there any way to do this?


Solution

  • The problem is, on what object should the function be invoked when the interrupt occurs?

    You could do it this way for example:

    class RainGauge {
      int pulses;
    public:
      void begin(int pin, void (*callback)());
      void increment();
    };
    
    void RainGauge::begin(int pin, void (*callback)())
    {
      pulses = 0;
      attachInterrupt(digitalPinToInterrupt(pin), callback, FALLING);
    }
    
    void RainGauge::increment()
    {
      pulses++;
    }
    
    RainGauge RainGauge1;
    RainGauge RainGauge2;
    
    void setup() {
      RainGauge1.begin(2, []() {RainGauge1.increment();});
      RainGauge2.begin(3, []() {RainGauge2.increment();});
    }
    
    void loop() {
    
    }