What you need

Install the Arduino IDE and the ESP32 board package

Download the Arduino IDE from arduino.cc/en/software and install it. Then add Espressif's ESP32 board package:

  1. Open File → Preferences (Windows/Linux) or Arduino IDE → Settings (macOS).
  2. In "Additional boards manager URLs", add:
    https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  3. Open Tools → Board → Boards Manager, search for esp32 (by Espressif Systems), and install it.

Install the required libraries

Open Tools → Manage Libraries... and install each of these (search by name, exact match on the first result). This is the full list — the v2.0 board's physical button and speaker don't add anything here, both run on APIs already built into the core ESP32 toolchain.

LibraryAuthorUsed for
GxEPD2ZinggJMDriving the Waveshare e-paper panel
Adafruit GFX LibraryAdafruitFonts and drawing primitives
Adafruit BusIOAdafruitDependency of the GFX library
Adafruit NeoPixelAdafruitDriving the WS2812 LED strip
ArduinoJsonBenoit BlanchonParsing chess.com and Lichess API responses
WebSocketsMarkus Sattler (Links2004)The live RSocket-over-WebSocket connection to chess.com (Lichess needs no extra library — it's plain HTTPS)
Install "WebSockets" by Markus Sattler (Links2004) — not the similarly-named "ArduinoWebsockets" library. The wrong one doesn't enable TLS correctly on ESP32 and the connection to chess.com will simply fail to open.

Patch the WebSockets library (one line, required)

The WebSockets library always appends its own default User-Agent header when building the handshake — even when the caller (this firmware) already supplied one. That duplicate header corrupts the handshake chess.com expects, and the connection drops right after the first frame with no useful error.

Find WebSocketsClient.cpp inside your Arduino libraries folder (typically Documents/Arduino/libraries/WebSockets/src/) and locate the sendHeader() function. Skip appending the default User-Agent line when the caller already provided extra headers containing one. The exact patch and a full explanation of the bug are documented at the top of LiveGameClient.cpp in the firmware source — open that file for the precise before/after code.

This patch lives outside this repo, in your local Arduino libraries folder — it does not survive a library reinstall or update. If you ever update the WebSockets library, redo this patch before flashing again, or the live connection will silently stop working.

Select the board and the partition scheme

With the clock connected over USB-C:

  1. Tools → Board → esp32 → XIAO_ESP32C6
  2. Tools → Partition Scheme → Huge APP (3MB No OTA/1MB SPIFFS)
  3. Tools → Port → select the port the clock enumerated as.
The partition scheme matters. The default scheme only gives the app 1.2MB of flash, and this firmware (e-paper driver, fonts, WebSockets, ArduinoJson) sits right at that ceiling — it won't compile on the default scheme. Nothing here uses OTA updates, so the OTA partition isn't needed anyway.

Get the code

Clone or download the firmware from GitHub:

git clone https://github.com/ivolanski/IvoChess-Clock.git

Open IvoChess_Clock.ino in the Arduino IDE — it'll load the whole sketch (all the .h/.cpp files sit alongside it and load together).

Compile and upload

Click Upload (or Ctrl/Cmd+U). First compile takes a few minutes; the ESP32 core and libraries above need to build. Once it's done, the board resets and starts running automatically.

To confirm it's alive, open Tools → Serial Monitor at 115200 baud — you should see startup logs, including whether it found a saved Wi-Fi network or started its own setup hotspot.

What's next

The firmware is running — now it needs a Wi-Fi network and a chess.com, Lichess, or ChessConnect connection to actually show anything.