Home > Software engineering >  How to pass a class member function that modifies class members to a function that takes a function
How to pass a class member function that modifies class members to a function that takes a function

Time:05-31

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?

CodePudding user response:

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() {

}
  • Related