# How it works [← Back to the README](../README.md) 1. **ESP32 boot.** The ESP32 connects to WiFi and starts ArduinoOTA. After a crash it runs only OTA for 15 seconds, and after repeated crashes it goes to safe mode. Bad OTA firmware is rolled back automatically, see [Keeping OTA alive](../src/esp32/README.md#keeping-ota-alive). It then switches the display relay on, waits for the Nano's `READY` message (at most 3 s), shows "Connecting...", starts NTP and connects to MQTT. 2. **Clock.** Once the time is synced, the ESP32 sends a new frame whenever the screen changes, mostly once a minute: - **08:00–22:00:** the page: the chosen page (by default the built-in Clock page, Pikachu with a thought bubble showing `HH:MM`, yawning from 17:00), or what the [schedule and rules](web-ui.md#schedule) pick. - **22:00–23:30:** the clock is only shown during the minutes :00, :15, :30 and :45. 30 seconds after each of those minutes, the relay turns the display off. - **23:31–08:00:** the screen is cleared (or shows the off image chosen in the web UI) and power is cut after 30 seconds. 3. **Home Assistant**: switches, dropdowns and sensors over MQTT, see [Home Assistant](home-assistant.md). 4. **Nano.** The Nano reads commands from the serial line and updates its frame buffer. On `D` it flips only the dots that changed, in small steps so it never stops reading the serial port. Every 2 minutes (Settings, "Dot refresh") it flips every dot once more to fix dots that did not flip. 5. **Frame check.** After a frame the ESP asks the Nano for a checksum of its image and compares it with what it sent. When they differ (lost bytes can shift the picture), the Nano doesn't answer, or it restarted, the ESP sends the whole image again. It also does that every 10 minutes (Settings, "Image resync"); only dots that differ flip, so normally nothing changes. The counts are on the System tab. The serial protocol is described in [src/nano/README.md](../src/nano/README.md).