I'm posting here a simple project to create an interrupt timer on an ESP32 board for version 3.1.1 by Esspressif Systems. I had difficulties to find updated information to make this code, I hope it can be useful to someone !
This code creates an interrupt every 100ms and counts the number of interrupts.
There is the code :
#include "esp32-hal-timer.h"
const int ledPin = 2; // pin of the LED
volatile bool flag = false; // State of the LED
hw_timer_t *timer = NULL; // declaration of timer
int c=0;
// function call by the timer interruption
void IRAM_ATTR onTimer() {
flag = true; // Inverser l'état de la LED
}
void setup() {
Serial.begin(115200);
Serial.println("Start...");
// Timer initialisation at a frequency of 1 MHz (1 µs per tick)
timer = timerBegin(1000000);
if (timer == NULL) {
Serial.println("Error with the start of the timer");
while (1);
}
// Attaches the interrupt function to the timer
timerAttachInterrupt(timer, &onTimer);
// Configure an alarm to trigger the interrupt every 100 ms (100000 µs) timerAlarm(timer, 100000, true, 0); // 1000000 µs = 100ms = 0.1s
// Start of the timer
timerStart(timer);
}
void loop() {
if (flag){
c+=1;
Serial.println(c);
flag=false;
}
if (timer == NULL) {
Serial.println("Erreur : timerBegin() a échoué !");
while (1){
Serial.println("Erreur !!");
}
}
// Nothing in the loop because everything is managed by the interruption
}
Thank you, the comment was not on the right line.
And thank you for the documentation, I couldn't find the documentation about the new version of eps32 by expressif
An infinite loop() without an explicit yield(), delay() etc. may cause a watch dog timer reset which could make troubleshooting more complex.
This comment is a bit misleading because the parameter 2 is not primarily a time period, it is a number of ticks of the timer. :
If you are using the timer for only one purpose, as in your example, then you could instead have set the frequency of timer to 10Hz and set the alarm to trigger on every tick.
I am using ESP32 core 3.1.1
think the problem is timerbegin() initializes the timer and starts it
the following timerstart() attempts to start the timer again and throws the exception
E (20) gptimer: gptimer_start(396): timer is not ready for a new start
the ESP32 documentation timer example uses
// Set alarm to call onTimer function every second (value in microseconds).
// Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
timerAlarm(timer, 1000000, true, 0);
Ah yes. On looking more closely at the quoted official example, the statement timerStart(timer); does not appear. Actually, the error message you got is quite explicit and the behaviour of timerBegin() is also clear and documented to read "This function is used to configure the timer. After successful setup the timer will automatically start."
Back to the OP to tidy up their code. The timerAlarm() function is also erroneously in a comment.
FWIW, this code (originally written for Core 3.0.7) compiles and works in Core 3.1.1. So, any differences are not due to changes in the IDF APIs, but the Arduino APIs that wrap them.
the ESP32 timer is very useful
by calling timerAlarm() in the timer ISR one can have a sequence of events of different periods, e.g. events at 100Usec 350uSec 750uSec
// ESP32 timer interrupts - three pulses 100Usec 350uSec 750uSec
#define pin 19
hw_timer_t *timer = NULL;
// timer ISR invert pin level
volatile int counter = 0;
void ARDUINO_ISR_ATTR onTimer() {
static int timer1 = 350;
counter++;
// digitalWrite(pin, !digitalRead(pin));
gpio_set_level((gpio_num_t)pin, HIGH); // HIGH pulse
// set next interrupt time
timerAlarm(timer, timer1, true, 0);
if (timer1 == 100) timer1 = 350;
else if (timer1 == 350) timer1 = 750;
else timer1 = 100;
gpio_set_level((gpio_num_t)pin, LOW); // LOW
}
void setup() {
Serial.begin(115200);
pinMode(pin, OUTPUT);
timer = timerBegin(1000000); // Set timer frequency Mhz
timerAttachInterrupt(timer, &onTimer); // Attach onTimer function to our timer.
// Set alarm to call onTimer function(value in microseconds).
// Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
timerAlarm(timer, 150, true, 0); // start with 150uSec pulse
}
void loop() {
// display counter every second
static long timer1 = millis();
if (millis() - timer1 > 1000) {
timer1 = millis();
Serial.println(counter);
counter = 0;
}
}
I don't understand why you have this error, my code works perfectly on my esp32 and I'm also using version 3.1.1...
However, I tried commenting out the timerStart(timer); and that works too...