Can't use attachInterrupt in a library

北城余情 提交于 2019-12-01 05:36:21

So the compiler (not the IDE) tells you exactly what's wrong:

argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()

So, while attachInterrupt() takes a function pointer of type void (*)(), you're trying to pass it a non-static member function, which you can't. You can try making the member function static and casting:

static void echoHigh();

// ...

attachInterrupt(_echo_pin - 2, reinterpret_cast<void (*)()>(&echoHigh), RISING);

Arduino interrupt handlers can only be functions. You are trying make method of an object an interrupt handler. Hence the compiler complains.

To be more precise about it, object methods are like functions, but it is as if they take a "hidden" parameter, which specifies the object instance. Therefore, they actually have different type signatures from plain functions. This disallows one to pass a method pointer when what a function is looking for is a plain function pointer.

The solution is to move your echoHigh() and echoLow() out of the HCSR04Interrupt class, and make them plain functions.

As I stumbled upon this question and it hasn't had an accepted answer, I write what I found, which worked for me:

The interrupt has to be called by a global wrapper. This wrapper needs to call a handleInterupt function of the class. Therefore it has to know the class. This can be done by storing it in a global variable. If multiple instances of the class should be used, multiple such global variables have to be used. But as the interrupt pins are just a few you can write a global variable and function for every pin:

MyClass theInstance_pin3 = NULL;
MyClass theInstance_pin7 = NULL;

// Somewhere, fill in an initialized copy of MyClass,
// and set theInstance_pin3 or theInstance_pin7 to it

void ISR_3()
{
   if (theInstance_pin3)
       theInstance_pin3->handleInterrupt();
}
void ISR_7()
{
   if (theInstance_pin7)
       theInstance_pin7->handleInterrupt();
}

as a reference see: http://forum.arduino.cc/index.php?topic=41713.0 or http://forum.arduino.cc/index.php?topic=160101.0

I got around this by making a singleton base class which represents the hardware as a whole (which kinda makes sense in this situation anyway).

Any function pointers can then be passed to the sub-component class, and handled by the singleton, whose member variables and methods are all static.

Example headers (untested):

// Sub-component
class LampButton {
public:
    LampButton(int pin, void(*pushHandler)());
}

// Sub-component
class LampLed {
public:
    LampLed(int pin);
    void toggle();
}

// Singleton represents the hardware in it's entirety
class Lamp {
public:
    // Call this instead of a constructor
    static void initialize(int buttonPin, int ledPin);

    // Function implemented inline for clarity - don't do this
    static void handleButtonPush() {
        led.toggle();
    }

private:
    static LampButton button;
    static LampLed led;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!