Timer
About
The ESP32 SoCs contains from 2 to 4 hardware timers.They are all 64-bit (54-bit for ESP32-C3) generic timers based on 16-bit pre-scalers and 64-bit (54-bit for ESP32-C3)up / down counters which are capable of being auto-reloaded.
ESP32 SoC | Number of timers |
|---|---|
ESP32 | 4 |
ESP32-S2 | 4 |
ESP32-S3 | 4 |
ESP32-C3 | 2 |
ESP32-C6 | 2 |
ESP32-H2 | 2 |
Arduino-ESP32 Timer API
timerBegin
This function is used to configure the timer. After successful setup the timer will automatically start.
hw_timer_t*timerBegin(uint32_tfrequency);
frequencyselect timer frequency in Hz. Sets how quickly the timer counter is “ticking”.
This function will returntimer structure if configuration is successful.IfNULL is returned, error occurs and the timer was not configured.
timerEnd
This function is used to end timer.
voidtimerEnd(hw_timer_t*timer);
timertimer struct.
timerStart
This function is used to start counter of the timer.
voidtimerStart(hw_timer_t*timer);
timertimer struct.
timerStop
This function is used to stop counter of the timer.
voidtimerStop(hw_timer_t*timer);
timertimer struct.
timerRestart
This function is used to restart counter of the timer.
voidtimerRestart(hw_timer_t*timer);
timertimer struct.
timerWrite
This function is used to set counter value of the timer.
voidtimerWrite(hw_timer_t*timer,uint64_tval);
timertimer struct.valcounter value to be set.
timerRead
This function is used to read counter value of the timer.
uint64_ttimerRead(hw_timer_t*timer);
timertimer struct.
This function will returncountervalue of the timer.
timerReadMicros
This function is used to read counter value in microseconds of the timer.
uint64_ttimerReadMicros(hw_timer_t*timer);
timertimer struct.
This function will returncountervalue of the timer in microseconds.
timerReadMillis
This function is used to read counter value in milliseconds of the timer.
uint64_ttimerReadMillis(hw_timer_t*timer);
timertimer struct.
This function will returncountervalue of the timer in milliseconds.
timerReadSeconds
This function is used to read counter value in seconds of the timer.
doubletimerReadSeconds(hw_timer_t*timer);
timertimer struct.
This function will returncountervalue of the timer in seconds.
timerGetFrequency
This function is used to get resolution in Hz of the timer.
uint16_ttimerGetFrequency(hw_timer_t*timer);
timertimer struct.
This function will returnfrequency in Hz of the timer.
timerAttachInterrupt
This function is used to attach interrupt to timer.
voidtimerAttachInterrupt(hw_timer_t*timer,void(*userFunc)(void));
timertimer struct.userFuncfunction to be called when interrupt is triggered.
timerAttachInterruptArg
This function is used to attach interrupt to timer using arguments.
voidtimerAttachInterruptArg(hw_timer_t*timer,void(*userFunc)(void*),void*arg);
timertimer struct.userFuncfunction to be called when interrupt is triggered.argpointer to the interrupt arguments.
timerDetachInterrupt
This function is used to detach interrupt from timer.
voidtimerDetachInterrupt(hw_timer_t*timer);
timertimer struct.
timerAlarm
This function is used to configure alarm value and autoreload of the timer. Alarm is automatically enabled.
voidtimerAlarm(hw_timer_t*timer,uint64_talarm_value,boolautoreload,uint64_treload_count);
timertimer struct.alarm_valuealarm value to generate event.autoreloadenabled/disabled autorealod.reload_countnumber of autoreloads (0 = unlimited). Has no effect if autorealod is disabled.
Example Applications
There are 2 examples uses of Timer:
Repeat timer example:
/* Repeat timer example This example shows how to use hardware timer in ESP32. The timer calls onTimer function every second. The timer can be stopped with button attached to PIN 0 (IO0). This example code is in the public domain. */// Stop button is attached to PIN 0 (IO0)#define BTN_STOP_ALARM 0hw_timer_t*timer=NULL;volatileSemaphoreHandle_ttimerSemaphore;portMUX_TYPEtimerMux=portMUX_INITIALIZER_UNLOCKED;volatileuint32_tisrCounter=0;volatileuint32_tlastIsrAt=0;voidARDUINO_ISR_ATTRonTimer(){// Increment the counter and set the time of ISRportENTER_CRITICAL_ISR(&timerMux);isrCounter=isrCounter+1;lastIsrAt=millis();portEXIT_CRITICAL_ISR(&timerMux);// Give a semaphore that we can check in the loopxSemaphoreGiveFromISR(timerSemaphore,NULL);// It is safe to use digitalRead/Write here if you want to toggle an output}voidsetup(){Serial.begin(115200);// Set BTN_STOP_ALARM to input modepinMode(BTN_STOP_ALARM,INPUT_PULLUP);// Create semaphore to inform us when the timer has firedtimerSemaphore=xSemaphoreCreateBinary();// Set timer frequency to 1Mhztimer=timerBegin(1000000);// Attach onTimer function to our timer.timerAttachInterrupt(timer,&onTimer);// 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);}voidloop(){// If Timer has firedif(xSemaphoreTake(timerSemaphore,0)==pdTRUE){uint32_tisrCount=0,isrTime=0;// Read the interrupt count and timeportENTER_CRITICAL(&timerMux);isrCount=isrCounter;isrTime=lastIsrAt;portEXIT_CRITICAL(&timerMux);// Print itSerial.print("onTimer no. ");Serial.print(isrCount);Serial.print(" at ");Serial.print(isrTime);Serial.println(" ms");}// If button is pressedif(digitalRead(BTN_STOP_ALARM)==LOW){// If timer is still runningif(timer){// Stop and free timertimerEnd(timer);timer=NULL;}}}
Watchdog timer example:
#include"esp_system.h"#include"rom/ets_sys.h"constintbutton=0;//gpio to use to trigger delayconstintwdtTimeout=3000;//time in ms to trigger the watchdoghw_timer_t*timer=NULL;voidARDUINO_ISR_ATTRresetModule(){ets_printf("reboot\n");esp_restart();}voidsetup(){Serial.begin(115200);Serial.println();Serial.println("running setup");pinMode(button,INPUT_PULLUP);//init control pintimer=timerBegin(1000000);//timer 1Mhz resolutiontimerAttachInterrupt(timer,&resetModule);//attach callbacktimerAlarm(timer,wdtTimeout*1000,false,0);//set time in us}voidloop(){Serial.println("running main loop");timerWrite(timer,0);//reset timer (feed watchdog)longloopTime=millis();//while button is pressed, delay up to 3 seconds to trigger the timerwhile(!digitalRead(button)){Serial.println("button pressed");delay(500);}delay(1000);//simulate workloopTime=millis()-loopTime;Serial.print("loop time is = ");Serial.println(loopTime);//should be under 3000}