| **Arduino Nano** | [src/nano](src/nano/README.md) | Drives the panel's row and column electronics directly. Keeps a frame buffer and flips only the dots that changed. Takes simple text commands over serial. |
| **ESP32** | [src/esp32](src/esp32/README.md) | Connects to WiFi, gets the time over NTP, shows a clock with Pikachu bitmaps, exposes switches to Home Assistant over MQTT, switches display power with a relay and supports OTA updates. |
| **BROSE9323 driver** | [lib/BROSE9323](lib/BROSE9323/README.md) | Shared `Adafruit_GFX` display driver. On the Nano it toggles GPIO pins. On the ESP32 (`-D ESPSERIAL`) it turns every drawing call into a serial command for the Nano. |
Because the driver is an `Adafruit_GFX` subclass on both boards, the ESP32 can use the
normal GFX API (`print`, `drawBitmap`, `fillScreen`, ...). Each call is sent to the
Nano and drawn there.
## Repository layout
```
platformio.ini one PlatformIO project, multiple environments
lib/BROSE9323/ shared flipdot driver (used by both targets)
src/nano/ Arduino Nano firmware
src/esp32/ ESP32 firmware
secrets.example.h template for WiFi / MQTT credentials
archive/ old, unused sketches kept for reference
CLAUDE.md project notes for Claude Code
```
## Building and flashing
Install [PlatformIO](https://platformio.org/) (the VS Code extension is easiest) and open
this folder.
1. Copy `src/esp32/secrets.example.h` to `src/esp32/secrets.h` and fill in your WiFi and
MQTT details. `secrets.h` is gitignored.
2. Check the COM ports and the OTA IP in `platformio.ini`.
3. Build or upload:
| Environment | Board | Upload method |
|-------------|-------|---------------|
| `nano` | Arduino Nano (ATmega328P) | USB (`COM10`) |
| `esp32` | ESP32 DevKit v1 | OTA over WiFi (`10.1.1.198`) |
| `esp32_usb` | ESP32 DevKit v1 | USB (`COM11`). Use it for the first flash or for recovery. |
```sh
pio run # build nano + esp32
pio run -e nano -t upload # flash the Nano
pio run -e esp32 -t upload # flash the ESP32 over the air
pio run -e esp32_usb -t upload # flash the ESP32 over USB
pio device monitor -e nano # serial monitor
```
In VS Code you can also pick the environment in the PlatformIO status bar.
> **Tip:** The ESP32 → Nano wire goes to the Nano's RX pin, which the Nano's USB chip
> also uses. Disconnect that wire before you flash the Nano over USB, or the upload may
> fail.
## Wiring between ESP32 and Nano
The ESP32 talks to the Nano on **UART2** (`Serial2`, 115200 baud). The ESP32's own
`Serial` (UART0, USB) is free for debug output.
| ESP32 | Nano | Notes |
|-------|------|-------|
| GPIO 17 (TX2) | D0 (RX) | Display commands |
| GPIO 16 (RX2) | D1 (TX) | `READY` and `ERR` replies. Use a 5 V → 3.3 V voltage divider (e.g. 1 kΩ / 2 kΩ), because the ESP32 is not 5 V tolerant. Optional: without it, the ESP waits a fixed 3 s after power-on. |
| GND | GND | Common ground |
| GPIO 13 | Relay input | Relay powers the panels and the Nano (`LOW` = on) |