Skip to main content

Firmware Overview

The alarm clock firmware runs on ESP-IDF v5 with FreeRTOS. Each hardware subsystem runs in its own FreeRTOS task; a central event loop coordinates them via a state machine.


Why ESP-IDF (Not Arduino)

The Arduino framework is simpler to start with, but ESP-IDF is the better choice here because:

  • Real RTOS tasks — audio streaming needs its own task pinned to core 1; Arduino's loop() runs everything on one core with no preemption
  • Proper I2S DMA — the i2s_std.h API in IDF v5 is stable and supports correct stereo/mono configuration
  • NVS (Non-Volatile Storage) — ESP-IDF's built-in NVS flash storage is the easiest way to persist alarm settings across power cycles
  • Production-quality drivers — SPI, I2C, FATFS, WiFi, SNTP are all well-tested IDF components

The Dev Environment doc covers ESP-IDF v5 installation.


Task Architecture

Each task communicates through FreeRTOS queues:

QueueDirectionContents
button_event_queuebutton_task → mainbutton_event_t (which button, press/long-press)
display_cmd_queuemain → display_taskdisplay_cmd_t (which screen to render)
audio_cmd_queuemain → audio_taskaudio_cmd_t (play file, stop, set volume)
ntp_sync_eventntp_task → mainEventBits_t (NTP synced flag)
main_event_queuepower_monitor → mainEVT_POWER_LOSS / EVT_POWER_RESTORED

State Machine

The main task runs a finite state machine that determines what is shown on the display and what audio (if any) is playing:

The full state machine implementation is in the main loop doc.


Firmware Sections in This Guide

  1. Dev Environment — install ESP-IDF, create project
  2. Project Structure — CMake component layout
  3. Drivers — one driver per hardware component
  4. Features — higher-level behaviour built on top of the drivers
  5. Main Loop — the state machine and event loop

Follow this order. Each driver is a self-contained component you can test independently before wiring into the main loop.