🌐
DeepBlue
deepbluembedded.com › home › blog › esp32 timers & timer interrupt tutorial (arduino ide)
ESP32 Timers & Timer Interrupt Tutorial (Arduino IDE) – DeepBlueMbedded
February 17, 2025 - /* * LAB: 25 * Name: ESP32 Timer Interrupt Example * Author: Khaled Magdy * For More Info Visit: www.DeepBlueMbedded.com */ #define LED 21 hw_timer_t *Timer0_Cfg = NULL; void IRAM_ATTR Timer0_ISR() { digitalWrite(LED, !digitalRead(LED)); } void setup() { pinMode(LED, OUTPUT); Timer0_Cfg = timerBegin(0, 80, true); timerAttachInterrupt(Timer0_Cfg, &Timer0_ISR, true); timerAlarmWrite(Timer0_Cfg, 50000, true); timerAlarmEnable(Timer0_Cfg); } void loop() { // Do Nothing!
🌐
CircuitDigest
circuitdigest.com › microcontroller-projects › esp32-timers-and-timer-interrupts
ESP32 Timers & Timer Interrupt Tutorial
August 5, 2025 - #define LED 21 hw_timer_t *My_timer = NULL; void IRAM_ATTR onTimer(){ digitalWrite(LED, !digitalRead(LED)); } void setup() { pinMode(LED, OUTPUT); My_timer = timerBegin(0, 80, true); timerAttachInterrupt(My_timer, &onTimer, true); timerAlarmWrite(My_timer, 1000000, true); timerAlarmEnable(My_timer); //Just Enable } void loop() { }
Discussions

Timer error building infinity cube. New syntax?
That library hasn't been updated for Arduino 3.0. This is the old way to make timers: prescaler=80000000/frequency; timer = timerBegin(0, prescaler , true); timerAttachInterrupt(timer, &onTick, true); timerAlarmWrite(timer, 1, true); timerAlarmEnable(timer); and this is the new way, where 'frequency' is in Hz. timer = timerBegin(frequency); timerAttachInterrupt(timer, &onTick); timerAlarm(timer, 1, true, 0); More on reddit.com
🌐 r/esp32
11
0
June 8, 2025
How to delete and restart hw timer (for interrupts) on demand for esp32 arduino (stepper motor controller application) - Stack Overflow
I am having trouble figuring out how to disable then re-enable (upon a triggering event) the hw (esp32-hal-timer) timer from the esp-arduino library, here for a stepper motor controller application... More on stackoverflow.com
🌐 stackoverflow.com
Hardware timer, how to run once and restart again?
I had some trouble with timers and alarms on my esp32 doit devboard. Spent many hours trying to debug, end of the days its a silicon issue with the REV0 chips. Not sure if this applies to you but more information can be found here: https://github.com/espressif/arduino-esp32/issues/1313 More on reddit.com
🌐 r/esp32
8
5
April 12, 2021
timerBegin () / timerAlarmWrite () do not work with frequencies higher than 500 khz. (IDFGH-812)
Hi. I need to generate pulses of 75 nanoseconds and a function that, depending on the number of pulses counted, does certain operations. I am using the functions timerBegin, timerAlarmWrite and tim... More on github.com
🌐 github.com
3
March 20, 2019
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Hardware Timer ESP32 Dev Module - Programming - Arduino Forum
July 19, 2024 - #include #include hw_timer_t *timer = NULL; const int ledPin = 2; void IRAM_ATTR onTimer() { // Toggle LED state digitalWrite(ledPin, !digitalRead(ledPin)); } void setup() { pinMo…
🌐
GitHub
gist.github.com › futureshocked › 5327bec254a9d5afcc91fa0b673442b6
ESP32 timer interrupts, how to change duration in the loop. · GitHub
void setup() { Serial.begin(115200); timer1 = timerBegin(0, 80, true); timerAttachInterrupt(timer1, &onTimer1, true); // Configura o Timer 1 para o primeiro disparo timerAlarmWrite(timer1, 5000000, false); timerAlarmEnable(timer1); // setupTimer1(); }
🌐
Luis Llamas
luisllamas.es › inicio › tutoriales arduino › curso esp8266 / esp32
How to use ESP32 timers
November 25, 2024 - hw_timer_t *timer = NULL; volatile void has_expired = false; void IRAM_ATTR timerInterrupt() { has_expired = true; } void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); timer = timerBegin(0, 80, true); // Timer 0, clock divisor 80 timerAttachInterrupt(timer, &timerInterrupt, true); // Attach the interrupt handling function timerAlarmWrite(timer, 1000000, true); // Interrupt every 1 second timerAlarmEnable(timer); // Enable the alarm } void loop() { if(has_expired) { // Tasks to perform when the Timer interrupt is activated digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Toggle the state of the LED has_expired = false; } }
🌐
ElectronicWings
electronicwings.com › esp32 › esp32-timer-interrupts
ESP32 Timer Interrupts | ESP32
“timerAlarmWrite” function is used for defining the value for which the timer will generate the interrupt.
🌐
Upsy
upesy.com › tutorials › esp32 › esp32 programming › arduino code › basics › timers
Timer ESP32 with Arduino Code: Master the time - uPesy
February 2, 2023 - #define PIN_LED 2 hw_timer_t * timer = NULL; volatile uint8_t led_state = 0; void IRAM_ATTR timer_isr(){ led_state = ! led_state; digitalWrite(PIN_LED, led_state); } void setup() { Serial.begin(115200); pinMode(PIN_LED, OUTPUT); uint8_t timer_id = 0; uint16_t prescaler = 80; int threashold = 1000000; timer = timerBegin(timer_id, prescaler, true); timerAttachInterrupt(timer, &timer_isr, true); timerAlarmWrite(timer, threashold, true); timerAlarmEnable(timer); } void loop() { // put your main code here to run repeatedly }
🌐
Phatiphat Thounthong
phatiphatt.wordpress.com › esp32-sampling_mode
ESP32 Timer Interrupt (Sampling Mode) – Phatiphat Thounthong
October 21, 2020 - //Step #3 timerAlarmWrite(My_timer, 2000000, true); //timerAlarmWrite(timer?, Sampling Time, bool autoreload); //Sampling Time=> 2 s = 2000000/(80,000,000 MHz/prescale 80) //autoreload: if it is true, timer will repeat.
🌐
QuadMeUp
blog.quadmeup.com › home › programming › esp32, arduino and timer/alerts
ESP32, Arduino and Timer/Alerts » QuadMeUp
May 20, 2025 - timerAlarmWrite(timer, 1000, true); the last true sets alarm to autorepeat.
Find elsewhere
🌐
ESP32 Forum
esp32.com › viewtopic.php
ESP32 Timer changes - ESP32 Forum
November 26, 2024 - timerAlarmWrite(hw_timer[timer_no], alarm_value, timer_reload); replaced with new API: Code: Select all · timerAlarm(hw_timer[timer_no], alarm_value, timer_reload, 0); 2. the removed API: Code: Select all · hw_timer[timer_no] = timerBegin(timer_no, (uint16_t)(getApbFrequency() / TIME_BASE), cnt_up); replaces with new API : Code: Select all ·
🌐
Phatiphat Thounthong
phatiphatt.wordpress.com › watchdog-timer-esp32
Watchdog Timer (ESP32) – Phatiphat Thounthong
October 2, 2019 - //setup Watchdog Timer watchdogTimer = timerBegin(myTimerWDT, 80, true); timerAlarmWrite(watchdogTimer, 2000000, false); timerAttachInterrupt(watchdogTimer, &interruptReboot, true); timerAlarmEnable(watchdogTimer); //End setup WDT
🌐
Espressif
docs.espressif.com › projects › arduino-esp32 › en › latest › migration_guides › 2.x_to_3.0.html
Migration from 2.x to 3.0 - - — Arduino ESP32 latest documentation
timerAlarm used to set up Alarm for the timer and enable it automatically (merged timerAlarmWrite and timerAlarmEnable functions).
🌐
Reddit
reddit.com › r/esp32 › timer error building infinity cube. new syntax?
r/esp32 on Reddit: Timer error building infinity cube. New syntax?
June 8, 2025 -

Building, https://github.com/mecharms/Infinity-LED-CUBE/tree/main

I believe the problem is the timer is written under old format so does not work with new version in IDE.

Does anyone know if this is just a syntax fix?

 //--------------------------------
  // Configure Prescaler to 80, as our timer runs @ 80Mhz
  // Giving an output of 80,000,000 / 80 = 1,000,000 ticks / second
  timer = timerBegin(0, 80, true);                
  timerAttachInterrupt(timer, &onTime, true);    
  // Fire Interrupt every 1m ticks, so 1s
  timerAlarmWrite(timer, 5000000, true);      
  timerAlarmEnable(timer);
  //--------------------------------

C:\Users\Jason\Downloads\Infinity-LED-CUBE-main\Infinity-LED-CUBE-main\code\cube_led\cube_led.ino: In function 'void setup()':

C:\Users\Jason\Downloads\Infinity-LED-CUBE-main\Infinity-LED-CUBE-main\code\cube_led\cube_led.ino:3829:21: error: too many arguments to function 'hw_timer_t* timerBegin(uint32_t)'

3829 | timer = timerBegin(0, 80, true);

| ~~~~~~~~~~^~~~~~~~~~~~~

In file included from C:\Users\Jason\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.2.0\cores\esp32/esp32-hal.h:98,

from C:\Users\Jason\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.2.0\libraries\Wire\src/Wire.h:33,

from C:\Users\Jason\Downloads\Infinity-LED-CUBE-main\Infinity-LED-CUBE-main\code\cube_led\cube_led.ino:2:

C:\Users\Jason\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.2.0\cores\esp32/esp32-hal-timer.h:35:13: note: declared here

35 | hw_timer_t *timerBegin(uint32_t frequency);

| ^~~~~~~~~~

C:\Users\Jason\Downloads\Infinity-LED-CUBE-main\Infinity-LED-CUBE-main\code\cube_led\cube_led.ino:3830:23: error: too many arguments to function 'void timerAttachInterrupt(hw_timer_t*, void (*)())'

3830 | timerAttachInterrupt(timer, &onTime, true);

| ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~

C:\Users\Jason\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.2.0\cores\esp32/esp32-hal-timer.h:50:6: note: declared here

50 | void timerAttachInterrupt(hw_timer_t *timer, void (*userFunc)(void));

| ^~~~~~~~~~~~~~~~~~~~

C:\Users\Jason\Downloads\Infinity-LED-CUBE-main\Infinity-LED-CUBE-main\code\cube_led\cube_led.ino:3832:3: error: 'timerAlarmWrite' was not declared in this scope; did you mean 'timerWrite'?

3832 | timerAlarmWrite(timer, 5000000, true);

| ^~~~~~~~~~~~~~~

| timerWrite

C:\Users\Jason\Downloads\Infinity-LED-CUBE-main\Infinity-LED-CUBE-main\code\cube_led\cube_led.ino:3833:3: error: 'timerAlarmEnable' was not declared in this scope; did you mean 'timerAlarm'?

3833 | timerAlarmEnable(timer);

| ^~~~~~~~~~~~~~~~

| timerAlarm

exit status 1

Compilation error: too many arguments to function 'hw_timer_t* timerBegin(uint32_t)'

Thank you!

🌐
ESP32 Forum
esp32.com › viewtopic.php
Timers and interrupts not working as expected - ESP32 Forum
January 12, 2024 - hw_timer_t * timer = NULL; void IRAM_ATTR onTimer() { bool state = digitalRead(5); digitalWrite(5, !state); } void setup() { pinMode(5, OUTPUT); Serial.begin(115200); timer = timerBegin(0, 80, true); // Timer 0, prescaler 80, count up timerAttachInterrupt(timer, &onTimer, true); timerAlarmWrite(timer, 100, true); timerAlarmEnable(timer); timerWrite(timer, 50); } void loop() { }
Top answer
1 of 2
1

The word 'restart' had me thinking that it would just immediately start the timer again, but it turns out that is not the case. If the reload was set false previously, the timer has to be set again before it will actually execute - which works perfectly for my use case. Below is my new code (figured I would include the wifi and mqtt stuff to help anyone else as well):

#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include "VCDevices.h"

hw_timer_t * motorTimer = NULL;
Motor linMotor2 = Motor(pulsePin, directionPin);
int d = 0;
bool nextRun = false;

const char* ssid = "SSID";
const char* password = "PASSWORD_HERE";
const char* mqtt_server = "MQTT_SERVER_HERE";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char topArr[50];
char msgArr[100];

portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

//Timer ISR
void IRAM_ATTR motorInterrupt(void) 
{
  portENTER_CRITICAL(&timerMux);
  noInterrupts();
  //check if the motor is in motion still
  if (!linMotor2.getMotorStatus())
  {
    d = linMotor2.Update();
    //give timer different delay, dependent on its current speed
    timerAlarmWrite(motorTimer, d, true);
    timerAlarmEnable(motorTimer);
  }
  //kill the timer and interrupt if not
  else
  {
    nextRun = true;
    //set the 'reload' boolean to false, to get it to only trigger one more time
    timerAlarmWrite(motorTimer, 10, false);
    // Serial.println("POSITION REACHED!");
  }

  interrupts();
  portEXIT_CRITICAL(&timerMux); 
}

void reconnect() 
{
  // Loop until we're reconnected
  while (!client.connected()) 
  {
    Serial.print("Attempting MQTT connection...");
    Serial.println(mqtt_server);
    // Attempt to connect
    if (client.connect("ESP8266Client"))
    {
      client.subscribe(motorControlTopic);
      Serial.println("connected");
    } 
    else 
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void setup_wifi() 
{
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* message, unsigned int length)
{
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  String response;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }

  Serial.println();
  if (String(topic) == String(motorControlTopic))
  {
    if (messageTemp.toInt() > 0)
    {
      //check if motor is available to run
      if (linMotor2.getMotorStatus())
      {
        
        linMotor2.MoveTo(messageTemp.toInt());

        //set the motor timer and enable it
        timerAlarmWrite(motorTimer, 1, true);
        timerAlarmEnable(motorTimer);
        
        response = "moving to " + String(messageTemp.toInt()) + " mm position";
      }
      else
      {
        response = "motor is busy - wait for movement to end!";
      }
      Serial.println(response);
    }
  } 
}

void setup()
{ 
  //Start serial connection
  Serial.begin(115200);

  //Setup wifi and mqtt stuff
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  //Fix up motor settings
  pinMode(pulsePin, OUTPUT);
  linMotor2.SetSpeed(200);
  linMotor2.SetAcceleration(10);

  //Initialize timer here for later use!
  motorTimer = timerBegin(1, 80, true);
  timerAttachInterrupt(motorTimer, &motorInterrupt, true);
  Serial.println("TIMER SET!!");
  digitalWrite(pulsePin, LOW);

}

void loop()
{
  if (!client.connected()) reconnect();
  client.loop();  
  portENTER_CRITICAL(&timerMux);
  vTaskDelay(500);
  count = linMotor2.GetPosition();
  Serial.println("POSITION: " + String(count));
  if (nextRun)
  {
    noInterrupts();
    timerRestart(motorTimer);
    Serial.println("*********TIMER RESTARTED!******");
    nextRun = false;
    interrupts();
  }
  portEXIT_CRITICAL(&timerMux);
}
2 of 2
1

I found this question to be very similar to an issue I am experiencing, also in a stepper application I need to set a pin HIGH fo the stepper to run and then, after 2ms, need to set the pin back to LOW. To do that I am firing a second timer form inside the ISR of the first timer, but no matter what I try/set, the second timer always fires 23us later. To illustrate that I made the below barebone example so one can see that the interval between to two ISR is always 22/23us no matter what. This routine/strategy is part of the very popular TeensyStep library (ESP32 Fork) and the very short pulse length is not really appreciated by the large DRIVERS. What am I doing wrong?

hw_timer_t *timerA = NULL;
hw_timer_t *timerB = NULL;

void IRAM_ATTR onTimerA()
{
  digitalWrite(13, 1);  
  Serial.print("HI ");
  Serial.println(micros());
  timerAlarmEnable(timerB);
}

void IRAM_ATTR onTimerB()
{
  digitalWrite(13, 0);  
  Serial.print("LO ");
  Serial.println(micros());    
}

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  timerA = timerBegin(0, 80, true);
  timerAttachInterrupt(timerA, &onTimerA, true);
  timerAlarmWrite(timerA, 1000000, true);  
  
  timerB = timerBegin(1, 80, true);
  timerAttachInterrupt(timerB, &onTimerB, true);
  timerAlarmWrite(timerB, 200000, false);

  timerAlarmEnable(timerA);
}

void loop(){}
🌐
Reddit
reddit.com › r/esp32 › hardware timer, how to run once and restart again?
r/esp32 on Reddit: Hardware timer, how to run once and restart again?
April 12, 2021 -

Guys

I have a DevKitC dev board, and I'm trying to set up a HW timer that I want to re-use under certain conditions. In other words, I don't want it to reload automatically, it should run once and then remain dormant until I enable it again. It seems to work the first time, but when I enable the timer a second time it fires immediately, without any delay. It seems I'm not resetting it properly, so that the counter starts from 0 again (?).

What I've tried is this:

initialize timer 0 in setup(), with a prescaler for 80MHz.

myTimer = timerBegin (0, 80, true);
timerAttachInterrupt (myTimer, &isrMyTimer, true);

then when I want to use the timer I enable it as follows (for a duration of 3 seconds):

timerAlarmWrite(myTimer, 3000000), false);
timerAlarmEnable(myTimer);

I am also trying to confirm the frequency to use for the timer, whether it is indeed 80MHz. I get the values as shown below for the different functions. Any thoughts on what they mean?

getCpuFrequencyMhz()		240	
getXtalFrequencyMhz()		40
getApbFrequency()		80000000
Top answer
1 of 4
2
I had some trouble with timers and alarms on my esp32 doit devboard. Spent many hours trying to debug, end of the days its a silicon issue with the REV0 chips. Not sure if this applies to you but more information can be found here: https://github.com/espressif/arduino-esp32/issues/1313
2 of 4
2
I managed to get it working. The trick that worked for me was to reset the timer (counter) before each use, with the following statement: timerRestart() Below is a little pseudo sketch, only showing the relevant statements, to give you or anyone finding this post later, an idea of what worked for me. #include // only needed to get ESP32 frequency detail hw_timer_t * tmrTEST = NULL; // timer used for TESTING unsigned long lngTimerStart = 0; // system micro-seconds at timer start int tmrDuration = 5; // run timer for 5 seconds // Interrupt Service Routine called when TEST timer fires. void IRAM_ATTR isrTimerTEST() { Serial.print(" >>>>> TEST TIMER ISR: "); Serial.print( micros() ); Serial.print(" diff="); Serial.println((micros()-lngTimerStart)/1000/1000); } void setup() { Serial.begin(115200); ... // Set up TEST timer.. tmrTEST = timerBegin (1, 80, true); // use ESP32 Timer 1, pre-scale 80 (for 80MHz freq), count up. timerAttachInterrupt (tmrTEST, &isrTimerTEST, true); // attach the function to call when timer interrupt fires. Edge. Serial.print(" >> CPU Freq: "); Serial.println(getCpuFrequencyMhz()); Serial.print(" >> XTL Freq: "); Serial.println(getXtalFrequencyMhz()); Serial.print(" >> APB Freq: "); Serial.println(getApbFrequency()); ... } void loop() { ... if (tmrDuration > 0) { // initiate TEST timer. duration in micro-seconds. False to run once. timerAlarmWrite(tmrTEST, (tmrDuration * 1000000), false); timerRestart(tmrTEST); // reset timer counter timerAlarmEnable(tmrTEST); // start the timer lngTimerStart = micros(); Serial.print(" >>>>> TimerTEST dur="); Serial.print(tmrDuration); Serial.print(" start: "); Serial.println( lngTimerStart ); } ... } Thanks for your replies and time !
🌐
GitHub
github.com › espressif › arduino-esp32 › issues › 2603
timerBegin () / timerAlarmWrite () do not work with frequencies higher than 500 khz. (IDFGH-812) · Issue #2603 · espressif/arduino-esp32
March 20, 2019 - Hi. I need to generate pulses of 75 nanoseconds and a function that, depending on the number of pulses counted, does certain operations. I am using the functions timerBegin, timerAlarmWrite and timerAttachInterrupt, which work perfectly ...
Author   espressif
🌐
Arduino Forum
forum.arduino.cc › projects › programming
ESP32 hardware timer. Can anyone explain why one code works and the other don't? - Programming - Arduino Forum
August 26, 2023 - This code works: #define LED 2 hw_timer_t *blinkTimer = NULL; volatile bool toggle=0; volatile bool flip=0; void IRAM_ATTR blink(){ toggle=!toggle; if (toggle){ // controversial if statement timerAlarmWrite(blinkTimer, 500000, true); } else if (!toggle){ timerAlarmWrite(blinkTimer, 1500000, true); } } void setup() { Serial.begin(57600); pinMode(LED, OUTPUT); blinkTimer = timerBegin(0, 80, true); timerAttachInterrupt(blinkTimer, &blink, true); timerAlarmWrite(blink...
🌐
Arduino Forum
forum.arduino.cc › projects › programming
ESP32 Timer Interrupt - Programming - Arduino Forum
June 10, 2024 - Hi Folks, I am using Esp32 Dev Module to develop the timer interrupt code .but when I am using timerBegin() function I am getting errors like that: timerBegin() function can accept only one argument.Please help me out t…