| Document | Description |
|---|---|
| codingRules.md | Coding conventions and rules for this project |
| menuStructure.md | Menu layout, navigation, and event handling specification |
| colorSettings.md | Display color theme and UI color rules |
| DisplayDriverClass.md | Technical and API documentation for the reusable display driver class |
| InputClass.md | Technical and API documentation for the reusable encoder + auxiliary button input class |
| WifiSettings.md | Technical and API documentation for the reusable WiFi settings struct |
| WiFiManagerExt.md | Technical and API documentation for the reusable WiFi manager class |
| webUI.md | Web UI architecture, behavior, menus, and API endpoints |
| 24hTimer.md | 24 hour timer, behavior, menus, and API endpoints |
This software and/or hardware is developed incrementally. That means I have no clear idea how it works (though it mostly does).
If you have questions about this software, it will probably take you just as long to figure things out as it would take me. So I’d prefer that you investigate it yourself.
Having said that Don’t Even Think About Using It.
Seriously. Don’t.
Building this design may injure or kill you during construction, burn your house down while in use, and then—just to be thorough—explode afterward.
This is not a joke. This project involves lethal voltages and temperatures. If you are not a qualified electronics engineer, close this repository, step away from the soldering iron, and make yourself a cup of tea.
If you decide to ignore all of the above and build it anyway, you do so entirely at your own risk. You are fully responsible for taking proper safety precautions. I take zero responsibility for anything that happens—electrically, mechanically, chemically, spiritually, or otherwise.
Also, full disclosure: I am not a qualified electrical engineer. I provide no guarantees, no warranties, and absolutely no assurance that this design is correct, safe, or suitable for any purpose whatsoever.
ESP32 cyclic and 24h timer for a 2.4 inch SPI TFT + EC11 rotary encoder module with the Piggy Back Board attached.
Read codingRules.md
read menuStructure.md
read colorSettings.md
- Local TFT menu
- Main menu splits timer editing into
Cyclic Timer Settingsand24h Timer Settings - Rotary encoder editing
- Save Profile confirmation via [No] [Yes] buttons for the active profile
- New Profile name entry with character-by-character editing
- JSON profiles in LittleFS
- JSON cyclic profiles in LittleFS (stored as
<name>.json) - JSON 24h profiles in LittleFS (stored as
<name>24h.json) - Trigger and reset inputs
- Output control with selectable polarity
- Web UI Timer Settings split into two submenu items:
Cyclic Timer Settingsfor cyclic timer editing24h Timer Settingsfor full 24h timer configuration (including quarter-hour editing)
- Web UI action buttons (Start/Stop/Reset) hidden for 24h timer profiles
- Web UI automatically stops timer when a menu tile opens and automatically starts it again when all menu tiles are closed
- Web UI shows a save warning when
Auto Save ProfileisNoand settings are saved - Output control with selectable polarity
- Web UI with matching timer settings
- Web UI live-apply only for Timer Settings (apply immediately, save only on explicit save)
- Web UI System settings are changed only via explicit Save (no live-apply)
- Web UI Cancel buttons always close the current sub-screen without saving
- Web UI Save Profile uses the active profile (no editable profile-name field in Save Profile tile)
- Web UI Save Profile button remains enabled while timer is running
- Web UI System tile has a Theme selector only (no extra read-only Theme display field)
- Web UI status refresh always updates Timer Screen, but does not overwrite fields in an open edit tile
- Web UI header shows
(not saved)after active profile name when Timer Settings are changed but not saved to profile - System settings stored separately from profile timer fields
- Profile dropdown refresh keeps current selection
repeatCount = 0support for infinite cycles- TFT status updates while running with partial line redraw (no full-screen flicker)
- Build-time configuration through
build_flagsinplatformio.ini - Optional color test mode through
TEST_COLOR_PATERN - Reusable
InputClassfor EC11 encoder + auxiliary button (PIN_KEY0) with configurable pins, press thresholds, and full in-class event/state logic - Reusable
DisplayDriverclass for the current ST7789 hardware, with generic init, theme, tile, header, button, and screen helpers; legacy free-function wrappers remain for existing firmware call sites
- Timer screen shows:
- cyclic timer:
State,On time,Off time,Output, andCycles - 24h timer:
State,Next Change Between,Last State Change (ON/OFF),Next State Change (OFF/ON),Output(noCyclestile)
- cyclic timer:
Outputline includes a live countdown timer (MMM:SS) to the next ON/OFF switch while running/paused.- For cyclic timers, when
Warp Speedis enabled, elapsed runtime advances at 60x speed (1 real second = 60 countdown seconds) for phases usingsorMin, while the countdown format remainsMMM:SS. - If either cyclic phase unit is
Min, warp acceleration remains active across both phases. - For cyclic timers, the
Cyclestile always keeps the cycle counter visible; whenWarp Speedis enabled it also showsWarp modenear the right side of the same tile. - For 24h timers, the
Next Change Betweentile showshh:mm - hh:mmfor the next possible switch span. - When
Warp Speedis enabled, the TFT header keeps showing the warped clock (HH:MM) even if WiFi is disconnected. - Open the local menu with a long press on the rotary encoder.
- Select menu options with a short press on the rotary encoder.
- Menu navigation is clamped (no wrap-around).
- In
Manualtrigger mode, timer action row includesStart,Stop,Reset. - In
Externaltrigger mode, the action row is replaced byExternal Triggertext (no local start/stop/reset actions). - For 24h timer profiles, local
Start,Stop, andResetactions are hidden. - Menu list items are rendered left-aligned with a two-character prefix area: selected item is shown as
> Item <, unselected items use leading spaces so text starts at the same position.
Cyclic Timer Settings24h Timer SettingsSave ProfileLoad ProfileNew ProfileDelete ProfileSystem SettingsExit(return to status screen)
The press durations are configurable in platformio.ini via build_flags:
ENCODER_SHORT_PRESS_MSENCODER_MEDIUM_PRESS_MSENCODER_LONG_PRESS_MSBUTTON_SHORT_PRESS_MSBUTTON_MEDIUM_PRESS_MSBUTTON_LONG_PRESS_MS
Current configured values in this repository:
ENCODER_SHORT_PRESS_MS=50ENCODER_MEDIUM_PRESS_MS=1000ENCODER_LONG_PRESS_MS=2000BUTTON_SHORT_PRESS_MS=50BUTTON_MEDIUM_PRESS_MS=1000BUTTON_LONG_PRESS_MS=2000
- Cyclic profile files are stored as `/<profileName>.json` (no suffix)
- 24h profile files are stored as `/<profileName>-24h.json` (automatic "-24h" suffix)
- Profile files store:
timerType,onTimeValue,offTimeValue,onTimeUnit,offTimeUnit,repeatCount,triggerMode,triggerEdge, and the 24h quarter-hour states - System-level settings such as output polarity, lock input during run, auto-save profile, theme color, and encoder direction are stored separately in Preferences/NVS
- Display rotation is a system setting in
System Settingsand is persisted in Preferences/NVS (values:1or3) - Built-in profiles
default(cyclic) anddefault-24h(24h) are always available in the Load Profile list - Built-in profiles
defaultanddefault-24hcannot be deleted and are hidden from the Delete Profile list - If the active profile is deleted, firmware automatically loads the corresponding default profile based on timer type
- Display rotation is a system setting in
- The fallback access point is open (no password)
- If no WiFi credentials are found (or STA connection fails), use the local
WiFi Setupmenu: scan nearby APs, select SSID with the rotary encoder, then enter the WiFi password via rotary text input and save/apply. - At startup, Serial Monitor prints
WiFi connected. IP address: <ip>once when STA connects, orNo WiFi Connectionif no STA link is established within the startup connection window. - The local UI currently includes timer and profile management
- Local TFT WiFi credential editing is available through the rotary menu
- If LittleFS marker file
/firstBootexists at startup, firmware skips WiFi startup for that boot, erases stored STA credentials, showsfirstBoot / WiFi init skipped, and removes the marker file
- All TFT text is rendered with the built-in monospaced font.
- Header uses the same calibrated blue background as selected action buttons.
- Header right side shows
No WiFiwhen disconnected, orHH:MMwhen WiFi and NTP time are available. - Header time is refreshed across all screens with a lightweight header-only redraw (at least once per 10 seconds while NTP time is valid).
- Selected action button is blue; not-selected action buttons are light gray.
- Button text is rendered in the calibrated high-contrast mapping used by this panel.
- Status screen redraws only changed lines for smooth runtime updates.
- In button-mode field input, buttons are centered and drawn directly on the black background near the bottom (no tile behind the button group).
- Add
-D TEST_COLOR_PATERNtobuild_flagsinplatformio.inito enable test mode. - In this mode, firmware only initializes the display and shows a color palette test screen.
- Timer/menu/WiFi runtime logic is skipped in this mode.
- This project currently targets an ST7789-based 2.4 inch SPI display module.
- Required signals include power,
CS,DC,RST,BL, plus SPISCKandMOSI. - Rotation is configurable in local
System SettingsviaDisplay Rotation(1or3).
