0

I'm using the exact piece of code in my ESP8266 library (which works OK ), but when used in a ESP32 library- I got an error:

This is the relevant code snip:

void myIOT32::_feedTheDog()
{
  _wdtResetCounter++;
  if (_wdtResetCounter >= _wdtMaxRetries)
  {
    sendReset("Dog goes woof");
  }
}
void myIOT32::_startWDT()
{
  wdt.attach(1, std::bind(&myIOT32::_feedTheDog, this)); // Start WatchDog
}

void myIOT32::sendReset(char *header)
{
  char temp[150];

  sprintf(temp, "[%s] - Reset sent", header);

  if (useSerial)
  {
    Serial.println(temp);
  }
  if (strcmp(header, "null") != 0)
  {
    pub_msg(temp);
  }
  delay(1000);
  ESP.restart();
}

and this is the error:

/home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp: In member function 'void myIOT32::_startWDT()':
/home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:333:55: error: no matching function for call to 'Ticker::attach(int, std::_Bind_helper<false, void (myIOT32::*)(), myIOT32*>::type)'
   wdt.attach(1, std::bind(&myIOT32::_feedTheDog, this)); // Start WatchDog
                                                       ^
1

ESP32 ticker attach functions take pure function pointers with at max one argument type -- not a std::function/ std::_Bind_helper that std::bind produces.

See code and types at https://github.com/espressif/arduino-esp32/blob/master/libraries/Ticker/src/Ticker.h#L38.

For the ESP8266 however, they do use a std::function:

https://github.com/esp8266/Arduino/blob/master/libraries/Ticker/src/Ticker.h#L36

And that's why it works on ESP8266 and not on ESP32 -- either adapt the Ticker library or rework your own code to not use member functions of classes.

Edit: You can easily rewrite your code to use a static helper function with one argument (the watchdog object itself) which then just calls the member function of that object. For this to work, the called function must be public. So a rewrite like

static void watchdog_timer_triggered_helper(myIOT32* watchdog) {
   //needs to be public!
   watchdog->_feedTheDog();
}

void myIOT32::_feedTheDog()
{
  _wdtResetCounter++;
  if (_wdtResetCounter >= _wdtMaxRetries)
  {
    sendReset("Dog goes woof");
  }
}
void myIOT32::_startWDT()
{
  wdt.attach(1, &watchdog_timer_triggered_helper, this); // Start WatchDog
}

void myIOT32::sendReset(char *header)
{
  char temp[150];

  sprintf(temp, "[%s] - Reset sent", header);

  if (useSerial)
  {
    Serial.println(temp);
  }
  if (strcmp(header, "null") != 0)
  {
    pub_msg(temp);
  }
  delay(1000);
  ESP.restart();
}

Since both the ESP32 and ESP8266 versions implement the

    template<typename TArg>
    void attach(float seconds, void (*callback)(TArg), TArg arg)

templated function this should work on both platforms now.

| improve this answer | |
  • Thank you for explaining. Can you share an example how to rework ? – Guy . D Jun 6 at 19:43
  • @Guy.D see update. – Maximilian Gerhardt Jun 6 at 20:12
  • @Maximillian - thank you for you answer. I'm afraid your it a bit more than I understand :( , and I do not like to copy an answer without fully understand. Can you please explain more, or perhaps a more simple answer ( sorry... ) – Guy . D Jun 7 at 5:17
  • @Guy.D didn't you write the initial code with std::bind, which is more complex than the function pointer used in the answer? Anyways I suggest reading up on C++ templates (attach() is a templated function), pure function pointers and std::function in C++. I'd take some quiet lengthy text to explain that fully in my answer o_o. – Maximilian Gerhardt Jun 7 at 13:51
  • to be honest, when I found that answer for 8266, I just took it as a given solution without knowing how bind work for every detail.... ( shame me :) ).... – Guy . D Jun 7 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.