Public Access
- config.h: all constants and debug defines - command_parser.h/.cpp: CommandParser class, one method per command - settings.h/.cpp: EEPROM flip time storage - main.cpp: setup/loop and the periodic full redraw only - Full redraw now checks frameEnded() after the serial buffer is drained - Drop the SPI/Adafruit_I2CDevice include workaround (not needed) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3.7 KiB
3.7 KiB
Flipdot display: notes for Claude
A PlatformIO project with two firmware targets for an 84×19 Brose flipdot clock. See README.md for the overview.
Layout and build
platformio.inihas the environmentsnano,esp32(OTA to 10.1.1.198) andesp32_usb(COM11). The sources are split withbuild_src_filter(src/nano/,src/esp32/).lib/BROSE9323/is the shared driver. Its behaviour depends on build flags set inplatformio.ini, not in the header:ESPSERIAL(ESP32): draw calls become serial commands.FLIPDOT_PLCC_ADAPTER(Nano, optional): alternative pinout.
- PlatformIO CLI is not on PATH. Run
~/.platformio/penv/Scripts/pio.exe run(Git Bash) or$env:USERPROFILE\.platformio\penv\Scripts\pio.exe run(PowerShell). - If an ESP32 build fails with
No module named 'intelhex', run~/.platformio/penv/Scripts/python.exe -m pip install intelhex. - After any change, build both targets:
pio run -e nano -e esp32.
Constraints
- Nano RAM is tight (ATmega328P, 2 KB). The frame buffers are allocated with
calloc. AvoidString, large stack buffers and new globals in Nano code. Put constant data inPROGMEM. - The ESP32 talks to the Nano on
Serial2(nanoSerialinlibs.h, GPIO 17 TX / GPIO 16 RX).Serial(UART0/USB) is free for debug output. Never write debug text tonanoSerial: the Nano runs lines that start with s/S/F/D/P/B/R/T as commands. - Open hardware TODOs are listed in the README
TODOsection. Update it when one is done. src/esp32/secrets.hholds the real credentials and is gitignored. Never commit it. Add new secrets tosecrets.example.has placeholders.- The relay (ESP32 GPIO 13,
LOW= on) powers both the panels and the Nano. Each time it switches on, the Nano cold-boots and then sendsREADY. The ESP'srelayOn()waits for that message, at mostNANO_BOOT_TIMEOUT. The timeout also covers the case where the Nano's TX isn't wired to the ESP's RX. relayOff()endsnanoSerialand sets its TX pin to input. Otherwise the idle-high TX line powers the Nano through its RX pin. Never send display commands whilerelay_onis false.- The Nano keeps no state over a power cycle except the flip time in EEPROM. The driver
forces a full redraw on the first
display()after boot (_force_next). - Hardware is not available here. Builds can be checked, but runtime behaviour can't.
Nano serial parser (src/nano/main.cpp)
- Files:
main.cpp(setup/loop, refresh),config.h(all constants and debug defines),command_parser.*(protocol, one method per command),settings.*(EEPROM). - Line based and non-blocking: bytes are collected into a 64-character buffer and a
command runs when
\narrives. Bitmap (B) pixel data is the exception. It is drawn while it arrives, so it can be longer than the buffer. Keeploop()free of busy-waits. - A full redraw (
display(true)) blocks for about 0.5 s, which overflows the 64-byte serial receive buffer. Only run it when no data is expected: right after aD, or after 2 s with no serial data. The ESP sends one frame per second, ending withD. - Flip time is stored in EEPROM as a magic word at address 0 and a
uint16_tat address 2. Values outside 50–2000 µs are rejected. - The Nano only replies
READY(at boot) andERR: .... There is no per-frame acknowledgement. Whether the Nano's TX is wired to the ESP's RX is unconfirmed, so every wait for a reply needs a timeout. - To test the parser without hardware, compile all
src/nano/*.cppfiles with g++ (Strawberry Perl provides it atC:\Strawberry\c\bin) and mock headers forArduino.h,EEPROM.handBROSE9323.h.
Git
- Remote: https://mangavalk.com/mangavalk/Flipdot-display.git, branch
main.