Hi i am trying to toggle the inbuilt RGB LED of the ESP32-C6 (with as goal for it to be the status of the device: connecting, connected, error...). I did this with a timer with a callback but this does not work. My LED is continiously red, but should be toggling green/red. When i use this code in the loop function it works without any problems.
What makes it that rgbLedWrite cannot be used in a interupt?
hw_timer_t *timer = NULL;
volatile bool ledState = false;
void IRAM_ATTR onTimer() {
ledState = !ledState;
if(ledState) {
Serial.println("Green");
rgbLedWrite(RGB_BUILTIN, 0, RGB_BRIGHTNESS, 0);
} else{
Serial.println("Red");
rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
//Initialise blink timer(1 per second)
timer = timerBegin(1000000); // 1Mhz
timerAttachInterrupt(timer, &onTimer);
timerAlarm(timer, 2000000, true, 0);
timerStart(timer);
}
void loop() {
// ledState = !ledState;
// if(ledState) {
// Serial.println("Green");
// rgbLedWrite(RGB_BUILTIN, 0, RGB_BRIGHTNESS, 0);
// } else{
// Serial.println("Red");
// rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);
// }
delay(1000);
}
Have you tried without Serial.print in your interrupt?
On UNO that is a no go as the serial uses interrupts...
Do you know which of the following is the reason for it not working when the code is in onTimer()?
a) onTimer() is not being called
b) onTimer() is being called, but rgbLedWrite() doesn't work
c) onTimer() is being called, but Serial.println() stops it from working
d) something else I haven't thought of
If you don't know, you could find out by moving parts of the code from onTimer() into loop(). E.g. first move everything except ledState = !ledState; into loop().
I don't think it's being used in an interrupt based on this information.
I do think that the problem lies wiht the rgbLedWrite() function. When removing the serial.println(which i added to see if the boolean was being updated) and only keeping the state change in the onTimer function the led blinks Red/Green as expected.
Like so
hw_timer_t *timer = NULL;
volatile bool ledState = false;
void IRAM_ATTR onTimer() {
ledState = !ledState;
}
void setup() {
Serial.begin(115200);
// Initialise pins
pinMode(LED_BUILTIN, OUTPUT);
//Initialise blink timer(1 per second)
timer = timerBegin(1000000); // 1Mhz
timerAttachInterrupt(timer, &onTimer);
timerAlarm(timer, 1000000, true, 0);
timerStart(timer);
}
void loop() {
if(ledState) {
rgbLedWrite(RGB_BUILTIN, 0, RGB_BRIGHTNESS, 0);
} else{
rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);
}
delay(500);
}
When i move the if block with the rgbLedWrite function calls into the onTimer the LED stays green.
Is that a solution for you?
I don't know why rgbLedWrite() wouldn't work from onTimer().
Perhaps you could find out by looking at the code for rgbLedWrite. I'm not familiar with that function, because all my ESP32 boards don't have a built in RGB LED.
The build in lED is a WS2812 type. might it need interrupts to control it?
I can't but you could try
void loop() {
noInterrupts();
if (ledState) {
rgbLedWrite(RGB_BUILTIN, 0, RGB_BRIGHTNESS, 0);
}
else {
rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);
}
interrupts();
delay(500);
}
to see if t works with interrupts off.
a7
I have have acepted that it doesnt work, will just use a non blinking led to show the state
You do you but that attitude will not be a good one in this hobby.
What you want to do is possible, trust me. Why it isn't working is a mystery. Problems like this are an opportunity to learn through experiments and research.
I wanted you to take less than seven minutes on an experiment that might have advanced our collective knowledge around your issue.
What will you do with real problems that you can't just decide to take an easy way out by changing your mind about what you want to accomplish?
Every flaw is a challenge. I see ppl entirely satisfied with dodgy projects. I think things like this should be run to ground. There is an objective reality here, things can be traced to reasons.
a7