This is the user manual for the patched semichcsc-byte/Open-Chess firmware running on a Concept-Bytes PCB + Arduino Nano RP2040 Connect.
If you're reading this with the original Concept-Bytes firmware, several features described here won't work. Flash the patched firmware first.
- First boot
- Mode selection
- Game mode 1 — Human vs Human
- Game mode 2 — Human vs AI (Stockfish)
- Game mode 3 — Coming Soon
- Game mode 4 — Sensor Test
- WiFi & AI mode setup
- Self-tests
- Saving & resuming games
- Troubleshooting
- Resetting the board
- Coordinate system
When you power on the board (USB-C to the Arduino, or external 5 V to J1 if you've populated it):
- LEDs all off for a moment while the firmware boots.
- Self-tests run (see Self-tests) — pure software, no LED activity unless something fails.
- WiFi AP
OpenChessBoardstarts (passwordchess123). You can ignore this; the AP is only useful for a future web UI. - The board asks you to set up the pieces — your side glows white, the far side red, and each square goes dark as you place its piece. Once all 32 are down, a rainbow burst plays and the mode selection menu appears.
If the board flashes red 5 times immediately after boot, the self-tests failed — your firmware is broken. Re-flash the latest release.
Once the board is fully set up (all 32 pieces placed), a rainbow burst plays and two menu LEDs light up in the centre of the board. Each is a button: place any chess piece on top of one to select that mode.
a b c d e f g h
8 . . . . . . . . 8
7 . . . . . . . . 7
6 . . . . . . . . 6
5 . . . ⚪ . . . . 5 ⚪ = white (Human vs Human)
4 . . . . 🔵 . . . 4 🔵 = blue (Human vs AI)
3 . . . . . . . . 3
2 . . . . . . . . 2
1 . . . . . . . . 1
| LED | Colour | Mode |
|---|---|---|
| D5 (left) | ⚪ white | Human vs Human |
| E4 (right) | 🔵 blue | Human vs AI (Stockfish) |
The two colours let you tell the options apart at a glance: white = local 2-player, blue = play the Stockfish bot.
After selection:
- The menu LEDs go off and a green flash confirms the choice.
- AI mode then asks for difficulty (see Difficulty) on 4 lit centre squares.
- The board waits for the 32 pieces to be in the starting position, then play begins.
- During play, the side-to-move's back rank gently breathes so you always know whose turn it is (white for you, red for the opponent / bot's blue "thinking" pulse).
Sensor Test / other modes: the on-board menu now offers just the two main modes. Sensor Test still exists in the firmware for hardware bring-up.
- Select Human vs Human (place a piece on D5).
- The 32 starting squares slowly light up in dim white as you place each piece. You must place all 32 pieces before the game starts.
- When the board is fully set up, a fireworks animation plays. Game on.
- Lift a piece of the colour whose turn it is (white starts).
- The square you lifted from glows dim white.
- Every legal destination glows soft white (quiet move) or red (capture).
- For en-passant captures, the destination glows pink.
- If you lift a piece that has no legal moves (e.g. a pinned piece), the square blinks twice and you must replace it.
- Place the piece on a legal destination, OR return it to its original square to cancel.
- The destination flashes green twice to confirm.
- Turn switches to the other colour.
The firmware enforces all chess rules. You cannot make an illegal move because illegal squares simply aren't lit. This includes:
- Pieces pinned against your own king
- Moves that leave your king in check
- Castling through attacked squares
- Castling while in check
- Castling after the king or rook has moved (rights tracked in
GameState)
Both kingside (O-O) and queenside (O-O-O) castling work:
- Lift your king. If castling is legal, you'll see white LEDs two squares away on the king's flank (g1/g8 for kingside, c1/c8 for queenside) in addition to the normal one-square king moves.
- Place the king on the castling target square.
- The board lights up the rook's source and destination — move the rook to complete the castle (h1→f1 or a1→d1, mirror for black).
- Done.
The board prevents any of the FIDE-illegal castles automatically:
- King has moved
- Rook on that side has moved (or has been captured on its starting square)
- King is in check
- King's path is attacked
- Squares between king and rook are not empty
If your opponent just made a 2-square pawn advance and your pawn is adjacent:
- Lift your pawn.
- The diagonal destination behind their pawn glows pink (instead of white) — this is the en-passant target.
- Place your pawn there.
- The captured pawn's square is shown briefly in red. Remove the captured pawn from the board to complete the move.
The window is exactly one move — if you don't take the en-passant immediately, the right is lost.
When your pawn reaches the back rank:
-
The destination square lights up gold.
-
Four selector LEDs light up on your own back rank (rank 1 for white, rank 8 for black) on files a, b, c, d:
File Colour Promotes to a Gold Queen b Red Rook c Blue Bishop d White Knight -
Place any chess piece on one of the four selector squares.
-
Lift the selector piece off when prompted. The pawn is now treated as the chosen piece for the rest of the game (you can swap the physical pawn for a queen, but the firmware doesn't require it — it tracks the promoted type internally).
- Check: the king square blinks red 3 times. The next move must remove the check (block, capture, or move king).
- Checkmate: the board plays a continuous fireworks celebration until you lift a piece, and prints
CHECKMATE - WHITE/BLACK WINSon the serial monitor. - Stalemate / 50-move rule / insufficient material: fireworks animation. The board prints
DRAW - <reason>on the serial monitor.
Both game modes detect checkmate and draws — including Human-vs-AI (earlier firmware only ended Human-vs-Human games; against the bot it would keep asking for moves forever).
To start a new game after game over: lift a piece (the fireworks stop), then re-place all 32 pieces in the starting position to reset.
Not yet implemented: 3-fold repetition (would require position hashing + history; possible but uses more RAM).
- WiFi credentials configured in
arduino_secrets.hand the firmware re-flashed (see WiFi & AI mode setup). - Internet access to
stockfish.online(HTTPS).
- Place a piece on the Human vs AI selector square.
- Pick the difficulty on the 4 lit centre squares (see Difficulty).
- The board prints the chosen difficulty, tears down its own AP, then connects to your home WiFi.
- On success: 3 brief green flashes across the entire board.
- On failure: 5 red flashes, AI mode is unavailable until next reboot. See Troubleshooting.
- Set up the 32 pieces in starting position. Fireworks play. White (you) starts.
- You play white. The bot plays black.
- Make your move exactly as in Human vs Human.
- The board sends the position (FEN) to the Stockfish API and waits for the bot's response (typically <2 s for Medium, longer for Hard/Expert).
- The bot's intended move is shown on the board:
- Source square blinks white.
- Destination square glows white.
- You make the move physically: lift the bot's piece from the source, place it on the destination.
- The board confirms with green flashes. Your turn again.
The patched firmware validates every API response locally with the chess engine. If Stockfish ever returns a move that isn't legal in the current position (corrupt response, partial JSON, side-of-turn confusion), the board:
- Prints
Bot move <xxxx> rejected by local engineto serial - Returns the turn to you (you don't lose your move)
- Stays in the current position
This protects against silent state corruption.
After you select AI mode, the board lights 4 squares on rank 4 (the empty centre row) as difficulty buttons. Lift any piece and place it on one to choose:
| Square | Colour | Difficulty | Stockfish depth | Timeout |
|---|---|---|---|---|
| c4 | Green | Easy | 6 | 15 s |
| d4 | Blue | Medium | 10 | 25 s |
| e4 | Amber | Hard | 14 | 45 s |
| f4 | Red | Expert | 16 | 60 s |
The chosen square blinks 3× to confirm; then lift the piece off and the board
connects to WiFi and waits for you to set up the starting position. No
recompile needed — the difficulty is picked fresh at the start of every AI
game. (The presets themselves still live in stockfish_settings.h.)
- Promotion choice for the player. When your pawn reaches the back rank in AI mode, it auto-promotes to Queen. (The Stockfish API string includes a 5th promotion char like
e7e8qbut the parser only takes the first 4 chars; bolting on the 5th is a small follow-up.) - Showing the bot's promotion choice on the LED. Same reason.
This is a placeholder for a future game mode (likely a chess puzzle / tactics trainer). Selecting it just prints a message and returns to the menu when you lift the piece.
Note: in the original Concept-Bytes firmware, this mode caused an infinite loop spamming serial and freezing the menu while the piece was on the square. The patched firmware fixes that — it waits for you to lift the piece before re-arming the menu.
Place a piece on E4. The board enters a continuous loop where every square that has a magnet on it lights up blue.
Use this to:
- Test that all 64 hall sensors detect their magnet
- Diagnose dead zones (squares that don't light up even with a magnet)
- Verify magnet polarity (A3144 sensors are unipolar — only the south pole triggers them; if a piece doesn't register, flip it over)
To exit: power-cycle the board (no menu return from this mode).
The pre-built .uf2 does not include WiFi credentials — we can't ship binaries with someone else's password baked in.
-
Clone the firmware fork:
git clone https://github.com/semichcsc-byte/Open-Chess.git cd Open-Chess git checkout v1.0.0-rp2040 -
Copy the secrets template:
cp arduino_secrets_template.h arduino_secrets.h
-
Edit
arduino_secrets.h:#define SECRET_SSID "YourWiFiName" #define SECRET_PASS "YourWiFiPassword" // Stockfish API — these defaults work, no change needed #define STOCKFISH_API_URL "stockfish.online" #define STOCKFISH_API_PATH "/api/s/v2.php" #define STOCKFISH_API_PORT 443 // HTTPS
-
Install dependencies (one-time):
arduino-cli core install arduino:mbed_nano arduino-cli lib install "Adafruit NeoPixel"@1.14.0 arduino-cli lib install WiFiNINA -
Compile and upload:
# Find the port: arduino-cli board list # Then (replace usbmodemXXX with yours): arduino-cli compile --fqbn arduino:mbed_nano:nanorp2040connect . arduino-cli upload --fqbn arduino:mbed_nano:nanorp2040connect -p /dev/cu.usbmodemXXX .
The firmware now has your WiFi baked in and AI mode will work.
arduino_secrets.his.gitignored in this repo — you can safely commit other firmware changes without leaking your WiFi password.
Board (Nano RP2040, station mode)
│
│ HTTPS GET /api/s/v2.php?fen=…&depth=10
▼
Your home router
│
▼
stockfish.online (Cloudflare-fronted)
│ Returns JSON: {"success":true, "bestmove":"bestmove e2e4 ponder d7d5", …}
▼
Board parses, validates, applies move
There's no server you need to host — stockfish.online is a free public API. Latency is typically < 2 s for depth 10.
Every boot, before WiFi setup, the firmware runs 10 deterministic chess engine tests and prints results to serial at 9600 baud:
=== ChessEngine self-tests ===
PASS T1: e2 pawn has 2 legal moves
PASS T2: b1 knight has 2 legal moves
PASS T3: no check at start
PASS T4: Fool's Mate detected
PASS T5: pinned rook stayed on file
PASS T6: both castlings legal
PASS T7: no castling in check (or fail above)
PASS T8: en-passant offered
PASS T9: K vs K is draw
PASS T10: kingside castle layout correct
=== Self-tests complete: 10/10 passed ===
If any test fails:
- The board flashes red 5 times across all 64 LEDs (impossible to miss)
- A
WARNING: N engine self-tests FAILEDline is printed - The board still continues to boot, but you should re-flash a clean release because the engine is broken
The tests cover: pseudo-legal move generation, legal-move filtering (own-check), Fool's Mate detection, pinned-piece handling, castling rights, castling-in-check forbidden, en-passant, insufficient material, and applyMove correctness for castling.
These caught a real bug during development (a wrong test fixture) and would catch any regression in the engine before it reaches a game.
During normal play the serial monitor (9600 baud) stays quiet by design: you get the boot banner, the self-test summary, a short "How to play" legend, and then one line per game event (moves, check, castling hints, game result).
The old firmware printed a DEBUG: Loop running, uptime: N seconds line every
10 seconds and a wall of boot internals — that noise is now gated behind a
single switch. To bring the verbose diagnostics back (board-type detection,
uptime heartbeat, WiFi internals), set #define DEBUG_VERBOSE 1 near the top
of OpenChess.ino and re-flash.
(v1.4.0+) The board automatically saves your game to internal flash after every move — the full position, whose turn it is, castling rights, en-passant state, and the mode/difficulty. This means:
- Power off mid-game and come back later (hours or days). On the next boot the board silently resumes exactly where you left off — no resume menu, no "set up the pieces" prompt. In AI mode it reconnects to WiFi automatically.
- The saved game stays active until you reset by placing all 32 pieces back on their starting squares for ~1.5 s (the reset gesture). That clears the save and returns to the menu for a new game.
- Works in both Human-vs-Human and Human-vs-AI.
Notes:
- The save lives in a reserved region of flash, so it survives a power cycle.
Re-flashing the firmware (a new
.uf2) may erase it — that only happens when you update, not during normal play. - Leave the physical pieces where they are when you power off; on resume the board expects the board to match the saved position.
Check the serial monitor (9600 baud).
| Symptom in serial | Cause | Fix |
|---|---|---|
No === Starting Chess Bot Mode === line |
You placed the piece on the wrong selector. | E5 = AI (not D5/D4/E4). |
Stops at Connecting to WiFi... |
You're running the unpatched Concept-Bytes firmware (AP+STA conflict). | Flash v1.0.0-rp2040. |
Connection attempt 10/10 - Status: ... then red flash |
Wrong WiFi credentials, or 5 GHz network. WiFiNINA only supports 2.4 GHz. | Edit arduino_secrets.h, switch to a 2.4 GHz SSID. |
Failed to connect to Stockfish API |
Internet blocked, DNS issue, or stockfish.online is down (rare). |
Try curl https://stockfish.online/api/s/v2.php?fen=…&depth=6 from your laptop. |
Bot move XXXX rejected by local engine |
Stockfish returned an illegal move (rare; Cloudflare hiccup). | Just play your turn again — the board returned the turn to you. |
- The patched firmware adds debounce (3 consecutive scans). If you still see flicker:
- Slow down piece movement
- Verify the piece's magnet hasn't fallen off
- Try the Sensor Test mode to find the bad squares
- If the same square consistently fails to detect:
- Magnet polarity wrong on that piece (flip it)
- Hall sensor (A3144) damaged on that square — visible as no detection in Sensor Test
- PCB trace or solder joint issue
- The Arduino Nano RP2040 powers the LEDs from its own 3.3 V supply via a level shifter. If you see no LEDs at all:
- Check the LED data line on D17 (NeoPixel
DIN) - Re-seat the Arduino in its socket
- Try the Sensor Test mode to force LEDs on
- Check the LED data line on D17 (NeoPixel
If the firmware freezes (no serial output for 30+ seconds):
- Power-cycle (unplug USB, plug back in)
- Re-flash the latest release in case of corruption
- Open an issue with the serial output in the firmware repo
Some modes (Sensor Test, AI mode after WiFi connect) don't have a back-to-menu option. Power-cycle the board to return to mode selection.
For mode 3 (Coming Soon), just lift the piece — the patched firmware returns to the menu automatically.
| What you want | How |
|---|---|
| End the game / back to menu | Place all 32 pieces on their starting squares and hold ~1.5 s (the reset gesture). This also clears the saved game. |
| Restart current game | After game over, set up the starting position again. |
| Resume after power-off | Just power back on — the board resumes automatically (see Saving & resuming games). A power-cycle no longer returns to the menu. |
| Clear all state and re-flash firmware | Double-tap reset button → drag fresh .uf2 to RPI-RP2 drive. |
| Reset to factory firmware | Flash the original Concept-Bytes binary (not recommended — known bugs). |
The firmware uses an internal (row, col) coordinate system that maps to standard chess notation as follows:
| Internal | Chess notation |
|---|---|
row 0 |
rank 1 (white back rank: RNBQKBNR) |
row 1 |
rank 2 (white pawns) |
row 2-5 |
empty middle ranks |
row 6 |
rank 7 (black pawns) |
row 7 |
rank 8 (black back rank) |
col 0 |
file a |
col 7 |
file h |
So the white king's home square e1 is internally (0, 4), and the black queen d8 is (7, 3).
The serial output uses standard algebraic notation (e2, d4, Qh4#, …) so you don't usually need to think in (row, col).
- 🐛 Bug reports / feature requests: open an issue on the firmware repo
- 💡 Build questions: see BUILD_LOG.md and BOM.md, or open an issue here in
semichcsc-byte/openchess - 🌐 Wiring & schematics: the
joojoooobuild guide is the best public reference (covers both RP2040 and ESP32 layouts) - � Hardware & STLs: PCB from concept-bytes.com (originally a Kickstarter campaign); 3D files at MakerWorld (Concept_Bytes, CC BY 4.0)
- �📺 Original videos: Concept Bytes on YouTube