# Arduino Nano: flipdot driver PlatformIO environment: `nano` The Nano is connected directly to the Brose panel electronics. It keeps an 84 × 19 frame buffer and takes drawing commands over serial (115200 baud). It has no clock or network logic. ## Files | File | Contents | |------|----------| | `main.cpp` | `setup()` / `loop()`, feeds serial bytes to the parser, periodic full redraw | | `config.h` | All settings: debug options, display size, flip time limits, timings | | `command_parser.h/.cpp` | `CommandParser`: the serial protocol, one method per command | | `settings.h/.cpp` | Flip time stored in EEPROM | The display driver itself is in [lib/BROSE9323](../../lib/BROSE9323/README.md). ## Tests `pio test -e test_nano` runs the unit tests in [test/test_nano](../../test/test_nano/test_main.cpp) on the PC. They feed serial data to the firmware and check what it asks the display to do: every command, bitmaps, bad input, flip time storage and the full-redraw timing. The Arduino core, EEPROM and the display driver are replaced by fakes in [test/mocks](../../test/mocks). ## Behaviour - **Boot:** the Nano loads the flip time from EEPROM, sets up the pins and sends `READY`. It doesn't flip any dots at boot. The relay powers the Nano, so it boots every time the display is switched on. - **First `display()` after boot** redraws every dot, because the Nano doesn't know which state the dots were left in. - **`display()`:** compares the new buffer with the last one that was shown and strobes only the dots that changed. - **Every 2 minutes** (`REFRESH_TIME`) it does a full redraw to fix dots that got stuck. A full redraw blocks for about half a second, which is long enough to overflow the 64-byte serial buffer. So it only runs right after a `D` (the end of a frame, when the ESP is quiet) or when no serial data has arrived for 2 seconds. - **Flip pulse length** (µs, 50–2000) is set with the `T` command and stored in EEPROM, so it is kept after a reboot. The default is 200 µs. ### Debug options Uncomment these in `config.h`: | Define | Effect | |--------|--------| | `DEBUG` | Print unknown command bytes on the serial port | | `MEASURE_REFRESH` | At boot, time a full redraw and print the duration in ms | ## Serial protocol Each command is one ASCII line that **ends with `\n`** (`\r` is ignored). The Nano collects a whole line before it runs the command. If a line is broken or unknown, it is skipped and the next line starts clean. Coordinates are 2-digit **hex**. Color is `0` (black) or `1` (yellow). The ESP32 driver (`ESPSERIAL`) only uses `s`, `S`, `F`, `D` and `T`. | Cmd | Format | Meaning | |-----|--------|---------| | `s` | `sXXYYc` | Set pixel in the buffer | | `S` | `SXXYYc` | Set pixel and flip it right away (direct mode) | | `F` | `Fc` | Fill the whole buffer | | `D` | `D` | Push the buffer to the display (changed dots only) | | `P` | `PXXYYcsTEXT` | Print text at (XX,YY), color `c`, size `s`. A literal `\n` (backslash, n) in TEXT starts a new line. The whole line can be at most 64 characters. | | `B` | `BXXYYWWHHcHEX...` | Draw a bitmap. WW must be a multiple of 4. Pixel data is one hex digit per 4 pixels, row by row. The data is drawn while it arrives, so it is not limited to 64 characters. | | `R` | `R` | Print the buffer as ASCII art on the serial port | | `T` | `Tnnn` | Set the flip pulse length in µs (decimal, 50–2000), stored in EEPROM | Replies on the Nano's TX pin: - `READY` after booting. The ESP waits for it before sending the first frame. - `ERR: ...` for invalid commands. Example (what the ESP32 sends for one pixel and a refresh): ``` s0a051 D ``` ## Wiring (default pinout) The pins are defined in [lib/BROSE9323/BROSE9323.h](../../lib/BROSE9323/BROSE9323.h). If you use the PLCC adapter board, build with `-D FLIPDOT_PLCC_ADAPTER` to switch to its pinout. | Signal | Nano pin | |--------|----------| | ENABLE | D7 | | ADDR_0 / 1 / 2 (panel select) | D3 / D5 / D6 | | COL_DATA | D4 | | COL_0 … COL_4 | D8, D10, D9, D11, D12 | | ROW_0 … ROW_4 | A3, A4, A2, A0, A1 | | ROW_RESET | D13 | | ROW_SET | A5 | | Serial RX | D0 (from ESP32 GPIO 17, TX2) | | Serial TX | D1 (to ESP32 GPIO 16, RX2, through a 5 V → 3.3 V voltage divider). Optional: needed for `READY`. Without it, the ESP waits the full 3 s timeout. |