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_t frequency);
frequency
select timer frequency in Hz. Sets how quickly the timer counter is “ticking”.
This function will return timer
structure if configuration is successful.
If NULL
is returned, error occurs and the timer was not configured.
timerEnd
This function is used to end timer.
void timerEnd(hw_timer_t * timer);
timer
timer struct.
timerStart
This function is used to start counter of the timer.
void timerStart(hw_timer_t * timer);
timer
timer struct.
timerStop
This function is used to stop counter of the timer.
void timerStop(hw_timer_t * timer);
timer
timer struct.
timerRestart
This function is used to restart counter of the timer.
void timerRestart(hw_timer_t * timer);
timer
timer struct.
timerWrite
This function is used to set counter value of the timer.
void timerWrite(hw_timer_t * timer, uint64_t val);
timer
timer struct.val
counter value to be set.
timerRead
This function is used to read counter value of the timer.
uint64_t timerRead(hw_timer_t * timer);
timer
timer struct.
This function will return counter value
of the timer.
timerReadMicros
This function is used to read counter value in microseconds of the timer.
uint64_t timerReadMicros(hw_timer_t * timer);
timer
timer struct.
This function will return counter value
of the timer in microseconds.
timerReadMilis
This function is used to read counter value in miliseconds of the timer.
uint64_t timerReadMilis(hw_timer_t * timer);
timer
timer struct.
This function will return counter value
of the timer in miliseconds.
timerReadSeconds
This function is used to read counter value in seconds of the timer.
double timerReadSeconds(hw_timer_t * timer);
timer
timer struct.
This function will return counter value
of the timer in seconds.
timerGetFrequency
This function is used to get resolution in Hz of the timer.
uint16_t timerGetFrequency(hw_timer_t * timer);
timer
timer struct.
This function will return frequency
in Hz of the timer.
timerAttachInterrupt
This function is used to attach interrupt to timer.
void timerAttachInterrupt(hw_timer_t * timer, void (*userFunc)(void));
timer
timer struct.userFunc
funtion to be called when interrupt is triggered.
timerAttachInterruptArg
This function is used to attach interrupt to timer using arguments.
void timerAttachInterruptArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg);
timer
timer struct.userFunc
funtion to be called when interrupt is triggered.arg
pointer to the interrupt arguments.
timerDetachInterrupt
This function is used to detach interrupt from timer.
void timerDetachInterrupt(hw_timer_t * timer);
timer
timer struct.
timerAlarm
This function is used to configure alarm value and autoreload of the timer. Alarm is automaticaly enabled.
void timerAlarm(hw_timer_t * timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count);
timer
timer struct.alarm_value
alarm value to generate event.autoreload
enabled/disabled autorealod.reload_count
number 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 0
hw_timer_t * timer = NULL;
volatile SemaphoreHandle_t timerSemaphore;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t isrCounter = 0;
volatile uint32_t lastIsrAt = 0;
void ARDUINO_ISR_ATTR onTimer(){
// Increment the counter and set the time of ISR
portENTER_CRITICAL_ISR(&timerMux);
isrCounter = isrCounter + 1;
lastIsrAt = millis();
portEXIT_CRITICAL_ISR(&timerMux);
// Give a semaphore that we can check in the loop
xSemaphoreGiveFromISR(timerSemaphore, NULL);
// It is safe to use digitalRead/Write here if you want to toggle an output
}
void setup() {
Serial.begin(115200);
// Set BTN_STOP_ALARM to input mode
pinMode(BTN_STOP_ALARM, INPUT);
// Create semaphore to inform us when the timer has fired
timerSemaphore = xSemaphoreCreateBinary();
// Set timer frequency to 1Mhz
timer = 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);
}
void loop() {
// If Timer has fired
if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){
uint32_t isrCount = 0, isrTime = 0;
// Read the interrupt count and time
portENTER_CRITICAL(&timerMux);
isrCount = isrCounter;
isrTime = lastIsrAt;
portEXIT_CRITICAL(&timerMux);
// Print it
Serial.print("onTimer no. ");
Serial.print(isrCount);
Serial.print(" at ");
Serial.print(isrTime);
Serial.println(" ms");
}
// If button is pressed
if (digitalRead(BTN_STOP_ALARM) == LOW) {
// If timer is still running
if (timer) {
// Stop and free timer
timerEnd(timer);
timer = NULL;
}
}
}
Watchdog timer example:
#include "esp_system.h"
#include "rom/ets_sys.h"
const int button = 0; //gpio to use to trigger delay
const int wdtTimeout = 3000; //time in ms to trigger the watchdog
hw_timer_t * timer = NULL;
void ARDUINO_ISR_ATTR resetModule() {
ets_printf("reboot\n");
esp_restart();
}
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("running setup");
pinMode(button, INPUT_PULLUP); //init control pin
timer = timerBegin(1000000); //timer 1Mhz resolution
timerAttachInterrupt(timer, &resetModule); //attach callback
timerAlarm(timer, wdtTimeout * 1000, false, 0); //set time in us
}
void loop() {
Serial.println("running main loop");
timerWrite(timer, 0); //reset timer (feed watchdog)
long loopTime = millis();
//while button is pressed, delay up to 3 seconds to trigger the timer
while (!digitalRead(button)) {
Serial.println("button pressed");
delay(500);
}
delay(1000); //simulate work
loopTime = millis() - loopTime;
Serial.print("loop time is = ");
Serial.println(loopTime); //should be under 3000
}