The clock answers like a WLED device (mDNS _wled._tcp, /json/info, /json/state, realtime UDP on 21324 and DDP on 4048), so SignalRGB can drive the 4 backlight LEDs, one per tube, LED 0 = left tube. Frames are shown at most 30 times a second (WLED_MAX_FPS); the normal effect returns 2.5 s after they stop, and the alarm flash still wins. Three new settings on the RGB page: enable (also a Home Assistant switch), stay dark while the tubes are off, and scale by the RGB brightness. They are stored in EEPROM after prm with their own magic value, so the update does not factory-reset the clock. page.js and site.css are now sent with no-cache: browsers kept them for a year and ran the old script after a web UI update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.6 KiB
IN-12 nixie clock: open firmware
Replacement firmware for a RetroModding NixieIN12v2 WiFi nixie clock (the 5 V, USB-C version sold on AliExpress): 4x IN-12 tubes, 2x IN-3 neon dots, 4 WS2812 LEDs, an ESP8266 (ESP-12) and a light sensor. The closed stock firmware (SV1.3) is replaced by ESP_UniClock with a new display driver for this board, WiFi updates and Home Assistant control.
Features
- Time from NTP with time zone and EU summer time, 12/24 h, day/night brightness, auto dimming from the light sensor, digit animations, cathode-poisoning protection, blinking colon
- WS2812 backlight: fixed colour or one of nine animated effects
- UniClock's web page for all settings
- Firmware updates over WiFi (ArduinoOTA)
- Home Assistant over MQTT discovery: tubes on/off, day/night brightness, auto dim, backlight (on/off, brightness, colour), LED effect, cathode protect, SignalRGB on/off, light and WiFi-signal sensors
- SignalRGB: the backlight can show up in SignalRGB as a WLED device (see below)
The hardware
The pinout was taken from the stock firmware by disassembly and checked on the clock; details and evidence are in docs/stock-firmware-pins.md.
| Function | GPIO |
|---|---|
| 2x 74HC595 (cathodes, anodes, dots) DATA / CLOCK | 13 / 14 (hardware SPI) |
| 74HC595 latch | 15 |
| WS2812 data | 12 |
| Light sensor (LDR) | A0 |
The two shift registers hold one 16-bit word: bits 0-9 are the cathodes for digits 0-9, bits 11-14 the tube anodes (bit 11 = left tube), bit 10 the neon dots and bit 15 the decimal points. The tubes are multiplexed, one at a time. This board has no RTC chip and no buttons.
Warning: the board makes about 170 V for the tubes whenever USB-C is connected.
Repository layout
| Path | Contents |
|---|---|
| firmware/uniclock/ | ESP_UniClock with the board support (PlatformIO project, see its README) |
firmware/uniclock/ESP32_UniClock2/nixie595.ino |
Display driver for this board |
firmware/uniclock/ESP32_UniClock2/clocks.h |
Board configuration, CLOCK_90 |
| docs/ | Pinout analysis of the stock firmware, schematic of the related 12 V board |
| tools/ | Python helpers used to disassemble the stock firmware |
The stock firmware dump is not included: it contains the WiFi password.
Building and flashing
Install PlatformIO, then in firmware/uniclock/:
pio run # build
pio run -t upload # first flash, over serial
pio run -t uploadfs # web page files, over serial
pio run -e nixie_in12_ota -t upload # later updates, over WiFi
The first flash needs a USB-serial adapter (3.3 V logic) on the programming header (GND, GPIO0,
RST, RXD, TXD, 3.3V). The clock stays powered from its own USB-C, so leave the adapter's 3.3V
unconnected. There is no auto-reset: before each serial upload, hold GPIO0 to GND, tap RST to
GND and release GPIO0. Set the serial port and the clock's IP address in platformio.ini. Back up the stock
firmware first (esptool read-flash 0 0x400000 stock.bin); it is the only way back.
On first boot the clock opens a WiFi access point called UNICLOCK. Connect to it and set your WiFi on http://192.168.4.1. For Home Assistant, enter the MQTT broker on the clock's web page and restart the clock; it then shows up under Settings > Devices > MQTT.
Optional passwords for the web page and OTA updates go in
firmware/uniclock/ESP32_UniClock2/secrets.h (see secrets.h.example; the file is gitignored).
SignalRGB
Turn on SignalRGB (WLED) on the RGB page of the web UI (or the SignalRGB switch in Home
Assistant). The clock then answers like a WLED device with one LED per tube, LED 0 = left tube:
mDNS _wled._tcp, /json/info and /json/state without a password, and colour frames over UDP
(WLED realtime on port 21324, DDP on 4048). SignalRGB should find it by itself; if not, add it by
IP address. SignalRGB only drives as many LEDs as the component on the device's channel has, so
give the channel a component with 4 LEDs. While SignalRGB sends colours it controls the LEDs (at most 30 frames per second,
WLED_MAX_FPS in clocks.h); 2.5 s after it stops, the normal effect comes back. The alarm
flash always wins. Two more switches on the same page:
- SignalRGB off with tubes: the LEDs stay dark at night and while the tubes are off.
- SignalRGB uses RGB Brightness: colours are scaled by the RGB brightness and auto dim; off = colours as SignalRGB sends them.
Changes to ESP_UniClock
Besides the new driver and configuration:
- NeoPixels on any ESP8266 pin, sent only when they change and between tube slots (the bit-banged update blocks interrupts and made the tubes flicker)
- ArduinoOTA; Home Assistant integration rewritten for ArduinoHA 2.1
- WLED emulation for SignalRGB (
wled.ino); its settings are stored after the UniClock settings in EEPROM, so the update keeps all existing settings - EU summer-time rules (upstream ended summer time on the US date); switching DST on no longer shifts the clock by an hour in winter
- Saving the firmware URL no longer starts an HTTP update; optional web password
- Small fixes: PlatformIO build, MQTT message buffer overflow, cathode-protect random start, LED gamma
Credits and license
ESP_UniClock is © Peter Gautier and licensed GPL-3.0-or-later; the modified firmware in
firmware/uniclock/ is under the same license. The libraries in firmware/uniclock/lib/ keep
their own licenses. The board support, analysis and changes were made with
Claude Code.