Description
Hardware:
Board: DOIT ESP32 DEVKIT V1
Core Installation version: Arduino-ESP32 v1.04 / Espressif 32 v1.11.1 in Platform.io
IDE name: Arduino IDE / Platform.io
Flash Frequency: 80Mhz
PSRAM enabled: ?no? ?yes?
Upload Speed: 921600
Computer OS: Windows 10
Description:
I'm trying to use timer interrupts and alarms inside a class (in the class definition). The function to call is a method in the class. But when passing that into timerAttachInterrupt()
I'm getting this error: argument of type "void (Motor::*)()" is incompatible with parameter of type "void (*)()"
.
I've tried using <FunctionalInterrupt.h> by passing the method with std::bind(), like it's done in the functional interrupts example but that doesn't work either, giving the error: no suitable conversion function from "std::_Bind<std::_Mem_fn<void (Motor::*)()> (Motor *)>" to "void (*)()" exists
.
How can timer interrupts be done within classes? I can't make the timer ISR method static as I want it to be object dependant to process the attribute values for the particular object.
Sketch: (leave the backquotes for code formatting)
//Change the code below by your sketch
#include <Arduino.h>
#include <FunctionalInterrupt.h>
class Motor {
private:
int pwm_ch, IN1, IN2;
float _PPR, reduction_ratio;
volatile unsigned long enc_pulse;
hw_timer_t * RPM_timer = NULL;
void IRAM_ATTR encoder_ISR() {
enc_pulse++;
}
void IRAM_ATTR calc_RPM() {
// RPM calculation code
}
public:
Motor(int pwm_channel, int pwm_pin, int IN1_pin, int IN2_pin, int enc_pin, float PPR, float ratio) {
pwm_ch = pwm_channel;
IN1 = IN1_pin;
IN2 = IN2_pin;
_PPR = PPR;
reduction_ratio = ratio;
enc_pulse = 0;
ledcSetup(pwm_ch, 5000, 8);
ledcAttachPin(pwm_pin, pwm_ch);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
coast();
pinMode(enc_pin, INPUT);
attachInterrupt(digitalPinToInterrupt(enc_pin), std::bind(&Motor::encoder_ISR, this), FALLING);
RPM_timer = timerBegin(0, 80, true);
timerAttachInterrupt(RPM_timer, std::bind(&Motor::calc_RPM, this), true); // THIS DOESN'T WORK
timerAlarmWrite(RPM_timer, 1000000, true);
timerAlarmEnable(RPM_timer);
}
void forward(int pwm_speed) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
ledcWrite(pwm_ch, pwm_speed);
}
void reverse(int pwm_speed) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
ledcWrite(pwm_ch, pwm_speed);
}
void coast() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
ledcWrite(pwm_ch, 0);
}
};
Motor drive_R = Motor(0, 23, 18, 19, 35, 11, 34.02);
Motor drive_L = Motor(1, 5, 16, 17, 34, 11, 34.02);
void setup() {
Serial.begin(115200);
}
void loop() {
// Some project specific code
}
Debug Messages:
src\RC-CONTROL-WORKING.cpp: In constructor 'Motor::Motor(int, int, int, int, int, float, float)':
src\RC-CONTROL-WORKING.cpp:88:78: error: cannot convert 'std::_Bind_helper<false, void (Motor::*)(), Motor*>::type {aka std::_Bind<std::_Mem_fn<void (Motor::*)()>(Motor*)>}' to 'void (*)()' for argument '2' to 'void timerAttachInterrupt(hw_timer_t*, void (*)(), bool)'
timerAttachInterrupt(RPM_timer, std::bind(&Motor::calc_RPM, this), true);
^