Failed to pass a member method reference to a Ticker method
Posted: Fri Aug 17, 2018 12:00 pm
I'm working on a project using the Ticker library to perform periodic callbacks. I got it working using C but now I'm trying to get a C++ implementation working. I gave up C++ for Python 8 or 9 years ago and am just now re-learning C++. The concepts are still fresh but the syntax is slow to return.
I have an implementation similar to this example from Arduino/libraries/Ticker/examples/TickerFunctional/TickerFunctional.ino:
In this example std::Bind is used to pass a this pointer along with the function reference.
My class looks like this:
My constructor looks like this in UTimer.cpp:
That attach_ms call fails to compile with the following message:
I've scoured the forums for help on passing member function references to other classes and most seem to suggest std::bind. Can anyone see what I'm doing wrong?
I have an implementation similar to this example from Arduino/libraries/Ticker/examples/TickerFunctional/TickerFunctional.ino:
Code: Select all
class ExampleClass {
public:
ExampleClass(int pin, int duration) : _pin(pin), _duration(duration) {
pinMode(_pin, OUTPUT);
_myTicker.attach_ms(_duration, std::bind(&ExampleClass::classBlink, this));
}
~ExampleClass() {};
int _pin, _duration;
Ticker _myTicker;
void classBlink() {
digitalWrite(_pin, !digitalRead(_pin));
}
};
In this example std::Bind is used to pass a this pointer along with the function reference.
My class looks like this:
Code: Select all
typedef void (*CallbackFn)();
typedef struct
{
bool active; // Is this timeout active?
bool repeat; // Restart this timeout when it expires?
unsigned int duration; // The duration (seconds) for the timeout
unsigned int timeoutTime; // The future time when the timeout occurs
CallbackFn callbackFn; // The function to call if/when the timeout expires
} TimeoutInstance;
class UTimer
{
public:
UTimer(Log &info, Log &error);
~UTimer() {};
int setTimeout(unsigned int duration, CallbackFn callbackFn, bool repeat);
void cancelTimeout(int index);
private:
Ticker timeoutTimer;
unsigned int elapsedTime = 0;
TimeoutInstance timeouts[NUM_TIMEOUTS];
Log &info;
Log &error;
void timeoutMonitor();
};
My constructor looks like this in UTimer.cpp:
Code: Select all
#include <UTimer.h>
UTimer::UTimer(Log &info, Log &error) : info(info), error(error)
{
timeoutTimer.attach_ms(TIMER_TICK_100MS, std::bind(&UTimer::timeoutMonitor, this));
for (int i = 0; i < NUM_TIMEOUTS; i++) this->timeouts[i].active = false;
}
That attach_ms call fails to compile with the following message:
Code: Select all
C:\Users\marc\Documents\PlatformIO\lib\utimer\src\UTimer.cpp: In constructor 'UTimer::UTimer(Log&, Log&)':
C:\Users\marc\Documents\PlatformIO\lib\utimer\src\UTimer.cpp:6:73: error: no matching function for call to 'Ticker::attach_ms(int, void (UTimer::*)(), UTimer* const)'
timeoutTimer.attach_ms(TIMER_TICK_100MS, &UTimer::timeoutMonitor, this);
^
C:\Users\marc\Documents\PlatformIO\lib\utimer\src\UTimer.cpp:6:73: note: candidates are:
In file included from C:\Users\marc\Documents\PlatformIO\lib\utimer\src/UTimer.h:4:0,
from C:\Users\marc\Documents\PlatformIO\lib\utimer\src\UTimer.cpp:1:
C:\Users\marc\.platformio\packages\framework-arduinoespressif8266\libraries\Ticker/Ticker.h:46:7: note: void Ticker::attach_ms(uint32_t, Ticker::callback_t)
void attach_ms(uint32_t milliseconds, callback_t callback)
^
C:\Users\marc\.platformio\packages\framework-arduinoespressif8266\libraries\Ticker/Ticker.h:46:7: note: candidate expects 2 arguments, 3 provided
C:\Users\marc\.platformio\packages\framework-arduinoespressif8266\libraries\Ticker/Ticker.h:63:7: note: template<class TArg> void Ticker::attach_ms(uint32_t, void (*)(TArg), TArg)
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
^
C:\Users\marc\.platformio\packages\framework-arduinoespressif8266\libraries\Ticker/Ticker.h:63:7: note: template argument deduction/substitution failed:
C:\Users\marc\Documents\PlatformIO\lib\utimer\src\UTimer.cpp:6:73: note: mismatched types 'void (*)(TArg)' and 'void (UTimer::*)()'
timeoutTimer.attach_ms(TIMER_TICK_100MS, &UTimer::timeoutMonitor, this);
^
I've scoured the forums for help on passing member function references to other classes and most seem to suggest std::bind. Can anyone see what I'm doing wrong?