Description
Board
ESP32-D0WD-V3
Device Description
Just a plain module on a breadboard
Hardware Configuration
Nothing is connected.
Version
latest master (checkout manually)
IDE Name
Arduino IDE
Operating System
Windows 10
Flash frequency
Presumably 80MHz; not relevant to issue
PSRAM enabled
yes
Upload speed
921600
Description
I'm trying to use timer interrupts and alarms within a class to contain its update needs. The function to call is a method in the class. But when passing that into timerAttachInterrupt()
I'm getting this error: Invalid use of non-static member function 'void Test::testFn()'
.
However, I cannot simply make the method static because I need to modify other members specific to my object instance.
To get around this issue in the past, I've passed a lambda function as a callback with this
specified, and then used that to call the class method ([&]() {update();}
). However, when I try that with timerAttachInterrupt()
, I get the error: Cannot convert 'Test::Test()::<lambda()>' to 'void (*)()'
.
I found a similar issue from a few years ago (#3465), and tried using <FunctionalInterrupt.h> and the example in the Ticker library as suggested. (I also tried commenting on that issue, but it's marked as closed, so I'm creating a new issue.) However, their suggested code produces the error Invalid use of member function 'void Test::testFn()' (did you forget the '()' ?)
, and I'm not sure how to remedy that. Nothing I've found searching online forums has provided any explanation of what's failing in this case either.
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.
P.S.
Interestingly, attachInterrupt()
(located in FunctionalInterrupt.h) does at least allow the use of lambda function callbacks, which timerAttachInterrupt()
does not. I assume this is because that function uses the type std::function<void(void)>
for its callback, while timerAttachInterrupt()
uses void (*fn)(void)
, though I don't know why this difference exists. Would it be possible to change timerAttachInterrupt()
to use the same callback type?
Sketch
#include "esp_timer.h"
class Test {
public:
Test(void) {
esp_timer_handle_t testTimer;
esp_timer_create_args_t timerConfig;
timerConfig.arg = 0;
timerConfig.callback = reinterpret_cast<esp_timer_cb_t>(testFn);
timerConfig.dispatch_method = ESP_TIMER_TASK;
timerConfig.name = "Test_Timer";
esp_timer_create(&timerConfig, &testTimer);
esp_timer_start_periodic(testTimer, 1000000);
}
void testFn(void) {
Serial.print("Test succeeded! Time elapsed: ");
Serial.printf("%lu.%03lu sec\n", millis() / 1000, millis() % 1000);
}
};
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while(!Serial);
Test justATestObject;
}
void loop() {
// put your main code here, to run repeatedly:
}
Debug Message
Invalid use of member function 'void Test::testFn()' (did you forget the '()' ?)
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.