Arduino (esp8266 / esp32) функция-член обратного вызова тикера - PullRequest
0 голосов
/ 02 апреля 2020

Может кто-нибудь помочь мне со следующим кодом?
У меня есть собственный класс, и я хочу определить обратный вызов для ticker функции onTickerCallback().
. Она компилируется и запускается на ESP8266, но не на ESP32.
Я вижу, что ESP32 Ticker::once имеет другое объявление, но мои знания c ++ не помогают мне найти решение.

Test.h

class Test {
  public:
    void start();
    void doSomething();
  private:
    void onTickerCallback();
};

Test. cpp

#include <Arduino.h>
#include <Test.h>
#include <functional>

// for ESP8266: https://github.com/esp8266/Arduino/blob/master/libraries/Ticker/src/Ticker.h
// for ESP32:   https://github.com/espressif/arduino-esp32/blob/master/libraries/Ticker/src/Ticker.h
#include <Ticker.h>

Ticker ticker;

void Test::start(){
  ticker.once(5, std::bind(&Test::onTickerCallback, this) );
}

void Test::onTickerCallback() {
  doSomething();
}

void Test::doSomething() {
  Serial.println("Hello");
}

main. cpp

#include <Arduino.h>
#include <Test.h>

Test t;

void setup() {
  Serial.begin(115200);
  t.start();
}

void loop() {
}

На ESP32 я получаю следующую ошибку:

error: no matching function for call to 'Ticker::once(int, std::_Bind_helper<false, void (Test::*)(), Test*>::type)'  
note: candidate: void Ticker::once(float, Ticker::callback_t)
   void once(float seconds, callback_t callback)  
note:   no known conversion for argument 2 from 'std::_Bind_helper<false, void (Test::*)(), Test*>::type {aka std::_Bind<std::_Mem_fn<void (Test::*)()>(Test*)>}' to 'Ticker::callback_t {aka 
void (*)()}'  
note: candidate: template<class TArg> void Ticker::once(float, void (*)(TArg), TArg)
   void once(float seconds, void (*callback)(TArg), TArg arg)  
note:   mismatched types 'void (*)(TArg)' and 'std::_Bind<std::_Mem_fn<void (Test::*)()>(Test*)>'  

1 Ответ

0 голосов
/ 02 апреля 2020

Реализация двух файлов Ticker.h немного отличается. В ESP8266 метод Once ожидает тип «callback_function_t», где callback_function_t определен как:

typedef std::function<void(void)> callback_function_t;

В ESP32 он ожидает тип «callback_t», который определен как:

typedef void (*callback_t)(void);

In В вашем примере кода std :: bind предоставляет ожидаемый тип std :: function. Это не относится к ESP32 Ticker.h, он ожидает указатель на функцию. У вас есть два варианта:

  1. Вместо использования функции onTickerCallback класса Test, просто создайте бесплатную функцию для обратного вызова. (Обратите внимание, что это допустимо, только если обратный вызов не должен быть частью класса Test).
#include <Arduino.h>
#include <Test.h>
#include <functional>

// for ESP8266: https://github.com/esp8266/Arduino/blob/master/libraries/Ticker/src/Ticker.h
// for ESP32:   https://github.com/espressif/arduino-esp32/blob/master/libraries/Ticker/src/Ticker.h
#include <Ticker.h>

Ticker ticker;

void callbackFunction() {
  Serial.println("Hello");
}

void Test::start(){
  ticker.once(5, callbackFunction);
}
Создайте бесплатную функцию, которая принимает экземпляр теста, и используйте ее для вызова вашей функции. (Обратите внимание, что для этого также потребуется, чтобы onTickerCallback был опубликован c, я не могу придумать никакого реального решения).
#include <Arduino.h>
#include <Test.h>
#include <functional>

// for ESP8266: https://github.com/esp8266/Arduino/blob/master/libraries/Ticker/src/Ticker.h
// for ESP32:   https://github.com/espressif/arduino-esp32/blob/master/libraries/Ticker/src/Ticker.h
#include <Ticker.h>

Ticker ticker;

void callbackFunc(Test* testInstance) {
  testInstance->onTickerCallback();
}

void Test::start(){
  ticker.once(5, callbackFunc, this);
}

void Test::onTickerCallback() {
  doSomething();
}

void Test::doSomething() {
  Serial.println("Hello");
}

Бонус: Подумав об этом на секунду, вы могли бы используйте лямбду вместо создания функции (обратите внимание, что вам нужно иметь знак + перед лямбда, чтобы он работал как указатель на функцию). Это будет выглядеть так:

#include <Arduino.h>
#include <Test.h>
#include <functional>

// for ESP8266: https://github.com/esp8266/Arduino/blob/master/libraries/Ticker/src/Ticker.h
// for ESP32:   https://github.com/espressif/arduino-esp32/blob/master/libraries/Ticker/src/Ticker.h
#include <Ticker.h>

Ticker ticker;

void Test::start(){
  ticker.once(5, +[](Test* testInstance) { testInstance->onTickerCallback(); }, this);
}

void Test::onTickerCallback() {
  doSomething();
}

void Test::doSomething() {
  Serial.println("Hello");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...