A 3-ring NeoPixel wall clock on the Seeed XIAO ESP32-C3. Seconds sweep the outer 60-LED ring, minutes on the 24, hours on the 12. Web UI, NTP sync, OTA updates, ambient-light auto dimming, and Focus Reminder nudges for ADHD hyperfocus. The diffused rings bloom like a flower, hence the name.
- Time from NTP over WiFi, with timezone and DST rules. No RTC chip.
- Web UI on your LAN for colors, brightness, animations, and per-ring settings
- 8 color palettes, per-ring color and intensity controls
- Quarter-hour, half-hour, and top-of-hour chime animations (3/3/5 styles)
- VEML7700 lux sensor drives auto-brightness. Pitch black room, LEDs sleep. Light returns, clock wakes.
- Focus Reminders: visual nudge animations at intervals you pick, built for interrupting hyperfocus
- WiFi setup via captive portal on first boot. No hardcoding credentials.
- OTA firmware updates from a browser after the first USB flash
- Settings persist in EEPROM, with a user-saved defaults slot
Prices swing. Shop around.
| Part | Qty | Notes | Where |
|---|---|---|---|
| Seeed XIAO ESP32-C3 | 1 | The brain. USB-C, WiFi, tiny. | Amazon / eBay |
| WS2812B 241-LED ring set | 1 | Sold as a 9-ring kit. You use the 60, 24, and 12 rings plus 1 loose pixel for the center. Rest goes in the parts bin. | Amazon / eBay |
| VEML7700 lux sensor module | 1 | Optional but worth it. Auto-brightness and dark-room sleep. | Amazon / eBay |
| Momentary push buttons | 2 | Time up/down, factory reset combo | Amazon / eBay |
| 5V power supply, 3A | 1 | 2A works, 3A gives headroom for bright animations | Amazon / eBay |
| 300Ω resistor | 1 | Inline on the LED data line | Amazon / eBay |
Plus a 3D printer for the frame, parchment paper for the diffuser, wire, and hot glue or cable ties.
The recommended path. 85% scale, fits a 256mm print bed (Bambu P1S class). Single NeoPixel chain of 97 LEDs: the three rings, then the center pixel. Parchment paper diffuser. Desktop kickstand or wall hang. Weighs about 500g.
Build environment: esp32c3_v3_8inch
Historical footnote: the firmware supports an optional "sacrificial" extra first pixel that stays dark and re-drives the data line at 5V logic. The original prototype has one spliced in, left over from troubleshooting. It turned out to be unnecessary and ships disabled. You will almost certainly never need it. See the [led_chain] note in platformio.ini if you are curious.
200% scale. Frame prints in thirds with alignment pins. The face diffuser needs one of:
- Laser-cut acrylic (600mm x 410mm bed) with parchment paper behind it
- 0.5mm white PLA face printed on an XXL-bed printer
Separate center pixel strip on GPIO20. This is the wall piece. Build the 8" first, then decide if you want to go big.
Build environment: esp32c3_v3_15inch
STL/3MF files for both builds: docs/publish/ChronoBloom_3D_Files/. CC BY 4.0, credit Steve Manley (see NOTICE).
XIAO Pin GPIO Function Notes
─────────────────────────────────────────────────────────────
D10 GPIO10 NeoPixel data (rings) Through 300Ω resistor
D7 GPIO20 NeoPixel data (center) 15" build only
D3 GPIO5 Button UP INPUT_PULLUP, polled
D9 GPIO9 Button DOWN INPUT_PULLUP, polled
D4 GPIO6 I2C SDA VEML7700
D5 GPIO7 I2C SCL VEML7700
5V/VIN - LED power rail External 5V supply
GND - Common ground ESP32 + LED supply
3V3 - VEML7700 power only Do NOT power LEDs
─────────────────────────────────────────────────────────────
AVOID: GPIO2, GPIO8 (boot strapping); GPIO3/GPIO4 (JTAG)
Do not hold the DOWN button (GPIO9) at power-on. It is the ESP32-C3 boot pin.
Full pin maps, LED indexing, power math, and assembly notes: docs/HARDWARE.md
Needs PlatformIO (VS Code extension or CLI).
First flash over USB:
pio run -e esp32c3_v3_8inch -t upload --upload-protocol esptool --upload-port COMx
Swap COMx for your port (/dev/ttyACM0 on Linux). Serial monitor runs at 115200.
Every flash after that is OTA from a browser:
- Build:
pio run -e esp32c3_v3_8inch - Open
http://esp32c3-v3-8inch.local/update - Upload
.pio/build/esp32c3_v3_8inch/firmware.bin
Inner ring shows blue during update, green on success, red on failure. Device reboots itself.
No credentials in code. On first boot the clock opens a captive portal:
- Join the WiFi network
esp32c3-clock-setupfrom your phone (no password) - A setup page opens (or go to
http://192.168.4.1) - Pick your network, enter the password
- Clock saves it to EEPROM and connects
After that it auto-connects on boot. If the password changes or the network disappears, the portal comes back.
Then open the web UI: http://esp32c3-v3-8inch.local/ (or the IP from your router's device list).
- docs/HARDWARE.md: pins, LED mapping, power, construction
- docs/FEATURES.md: every feature, current and planned
- docs/ANIMATIONS.md: animation catalog and triggers
- docs/API.md: web endpoints, settings JSON, client examples
- docs/TROUBLESHOOTING.md: when it does not work
- docs/ARCHITECTURE.md: codebase structure, for contributors
- docs/FOCUS_REMINDERS.md: the ADHD-nudge feature in depth
- docs/HISTORY.md: the full decade-long design story
- docs/CHANGELOG.md: version history
One person built and maintains this as a hobby project. Support is best effort. Open an issue with the bug report or build help template and I will get to it when I can. No SLA, no promises, but I do read everything.
This design has history. Three builders across a decade:
- Steve Manley (2015): the original NeoPixel Ring Clock. Arduino Nano, DS3234 RTC, 3D printed frame, UV glow-in-dark PLA. The whole concept starts here.
- Mike van der Sluis (2020): cost-optimized remix for inexpensive NeoPixel ring clones, simplified firmware
- Maestro8484 (2022-2026): ESP32-C3 port. WiFi, NTP, OTA, web UI, per-ring controls, auto-brightness, Focus Reminders, multi-scale parametric frame (85% and 200%).
Thanks to Steve and Mike for the foundation. See NOTICE for the attribution chain, or docs/HISTORY.md for the full decade-long story.
Firmware: Apache 2.0. Hardware/STL files: CC BY 4.0.