Methods to Make ESP32 Blinks

Methods to Make ESP32 Blinks

Here’s a comprehensive breakdown of all practical methods to blink an LED on an ESP32, categorized by execution model, with framework context, key APIs, and use-case guidance.

Blocking Methods #

Method Framework Key API Notes
Simple Delay Arduino / ESP-IDF delay(500) or vTaskDelay(pdMS_TO_TICKS(500)) Blocks the CPU. Fine for single-task sketches.
Deep Sleep Wake ESP-IDF / Arduino esp_sleep_enable_timer_wakeup(), esp_deep_sleep_start() Not for continuous blinking. Used for ultra-low-power periodic tasks (e.g., sensor + LED indicator).

Non-Blocking / Polling Methods #

Method Framework Key API Notes
millis() State Machine Arduino if (millis() - lastToggle >= 500) { toggle(); } Standard non-blocking pattern. Allows concurrent loops (WiFi, sensors, etc.).
esp_timer_get_time() ESP-IDF uint64_t now = esp_timer_get_time(); Microsecond-precision version of millis(). Used in same state-machine pattern.

Hardware Timer & Interrupt Methods #

Method Framework Key API Notes
Hardware Timer + ISR ESP-IDF / Arduino timer_create(), timer_arm(), attachInterrupt() Uses ESP32’s 4 hardware timers. ISR toggles GPIO. Must be short & marked IRAM_ATTR.
LEDC Peripheral (Hardware PWM) ESP-IDF / Arduino ledcSetup(), ledcAttachPin(), ledcWriteTone() Built-in PWM controller. Can generate exact square waves without CPU. Best for precise 1 Hz.
RMT Peripheral ESP-IDF rmt_init(), rmt_write_sample() Remote control peripheral. Overkill for blinking but can output arbitrary pulse trains via DMA.

FreeRTOS Task & Synchronization Methods #

(ESP32 runs FreeRTOS natively in both Arduino & ESP-IDF)

Method Framework Key API Notes
Dedicated RTOS Task ESP-IDF / Arduino xTaskCreate(), vTaskDelay() Runs in its own thread. Clean separation for complex systems.
FreeRTOS Software Timer ESP-IDF xTimerCreate(), xTimerStart() Callback-based periodic execution. Lightweight, runs in timer daemon task.
Event Group / Queue Trigger ESP-IDF xEventGroupWaitBits(), xQueueSend() Task waits for event/message, then toggles LED. Useful for state-driven blinking (e.g., blink on WiFi connect).
Semaphore/Binary Mutex ESP-IDF xSemaphoreGive(), xSemaphoreTake() One task signals, another blinks. Rarely needed for single LED but valid in multi-threaded designs.

Framework/Environment Alternatives #

Environment Method Example
MicroPython utime.sleep(), machine.Timer, asyncio timer = machine.Timer(); timer.init(period=500, mode=machine.Timer.PERIODIC, callback=lambda t: led.toggle())
Zephyr RTOS k_sleep(), k_timer_start(), workqueues k_timer_init(&blink_timer, blink_handler, NULL); k_timer_start(&blink_timer, K_MSEC(500), K_NO_WAIT);
Bare-Metal / Direct Registers GPIO + Timer registers Write to GPIO_OUT_W1TS/W1TC & configure TIMGn timers manually. No RTOS overhead.

Quick Comparison #

Method CPU Load Precision Complexity Best For
delay() / vTaskDelay() High (blocks) ±1 ms Simple sketches, prototyping
millis() state machine Low ±1 ms ⭐⭐ Multi-task Arduino apps
Hardware Timer + ISR Very Low ±1 μs ⭐⭐⭐ Real-time requirements
LEDC (Hardware PWM) Zero (after setup) Exact Hz ⭐⭐ Precise 1 Hz, power efficiency
FreeRTOS Task Low-Medium OS-dependent ⭐⭐⭐ Modular firmware
Software Timer (xTimer) Low ±1 tick ⭐⭐ Lightweight periodic callbacks
MicroPython machine.Timer Low ±1 ms Rapid prototyping, IoT scripts
comments powered by Disqus