Skip to the content
PCBKitNew board
2 layers197.5 × 33 mmCharge Case, the printed circuit board in 3D

Super cheap super tiny bots for....playing chess...

Size
197.5 × 33 mm
Copper layers
2
Thickness
1.6 mm
Parts
42
Nets
62
Pads
196
Tracks, vias
202, 53
Pours
2
Routed
Yes
KiCad
KiCad 7 (file 20221018)
Created
14 Jan 2025
Updated
11 Sep 2026

Overview

Charge Case is an open-source printed circuit board by DDeGonge, from the DDeGonge/MiniBot repository on GitHub, published under the MIT licence. It is a 2-layer board of 197.5 × 33 mm with 42 parts on 62 nets, routed with 202 tracks and 53 vias.

It is built around the USB4180-03-0120-C and GSB1C41110SSHR.

Main components

2

README

README.md

MiniBot

A swarm robotics platform built around autonomous chess. The system runs 34 small differential-drive robots across an 8x8 board, each independently localized and coordinated by a central Python application running on a Raspberry Pi.

The design is general-purpose — chess is the primary use case, but the platform works for any scenario requiring coordinated movement of many small autonomous robots in a bounded space.

Per-bot hardware cost is approximately $4 excluding PCB.


Table of Contents

  1. System Architecture
  2. Hardware
  3. Communication Pathways
  4. Server-Bot Sync
  5. Localization
  6. PCB and CAD
  7. Firmware

System Architecture

The system has three layers:

Coordinator is a Python/PyQt6 application running on a Raspberry Pi. It holds board state, runs path planning, drives the GUI, and sends motion commands to the Server over USB serial.

Server is an ESP32 on the motherboard. It acts as a wireless gateway: it receives CSV commands from the Coordinator over USB serial, translates them to binary ESP-NOW messages, and broadcasts them to the bots. It also drives the electromagnets used for localization and collects ACK/NACK responses back up to the Coordinator.

MiniBots are the robots themselves. Each runs an ESP32-C3 with five concurrent FreeRTOS tasks handling motion control, wireless communication, position estimation, and battery management entirely onboard.


Hardware

MiniBot

ComponentDetails
MCUESP32-C3 (RISC-V, 2.4 GHz WiFi)
Motors2x PMO8-2 miniature stepper motors
Motor driversSTSPIN220
MagnetometerMMC5633NJL (I2C)
Power~170 mAh LiPo
ChassisFully 3D printed; 2x M2x5mm bolts, 2x 7mm ID o-rings for tires
PCBCustom 4-layer; fits in the base of the chassis

Server / Motherboard

ComponentDetails
MCUESP32-C3 (RISC-V, 2.4 GHz WiFi)
ElectromagnetsMultiple, positioned at fixed known coordinates on the board
InterfaceUSB serial to Raspberry Pi
WiFiSoft AP; bots connect on a dedicated channel

The electromagnets fire in a timed sequence that the MiniBots detect with their onboard magnetometers. This is the primary localization mechanism.


Communication Pathways

mermaid
flowchart TD
    subgraph Coordinator["Coordinator (Raspberry Pi)"]
        GUI["GUI / Path Planner"]
        SH["SerialHandler\n(QThread)"]
        GUI -->|MoveCommand list| SH
    end

    subgraph Server["Server (Motherboard ESP32)"]
        ST["SerialTask"]
        CT["CommunicatorTask"]
        ET["ElectromagnetTask"]
        ST -->|CommandMessage| CT
        CT -->|GUIStatus| ST
    end

    subgraph Bots["MiniBot #1 ... #34 (ESP32-C3)"]
        COMM["EspNowCommunicator"]
        KIN["KinematicsController"]
        PE["PositionEstimator"]
        COMM -->|MotionCommand| KIN
        COMM -->|sync time| PE
    end

    SH -->|"Serial CSV Commands"| ST

CSV Protocol (Host to Server)

All messages are prefixed with >. The Server parses these and forwards the appropriate ESP-NOW message to the targeted bot(s).

TypeDirectionFormat
0Host to ESP32>0,{id},{mode},{duty1},{duty2} -- motor test
1Host to ESP32>1,{id},{x},{y},{theta_rad},{duration_ms} -- position command
2Host to ESP32>2,{id} -- position request
3ESP32 to Host>3,{id},{x},{y},{theta_rad},{timestamp_ms},{battery_v} -- ACK
4ESP32 to Host>4,{id},{err_type},{timestamp_ms} -- NACK
5Host to ESP32>5,{id} -- mag field request
6ESP32 to Host>6,{id},{bx},{by},{bz},{timestamp_ms} -- mag field response
7Host to ESP32>7 -- sync broadcast
254Host to ESP32>254,{0 or 1} -- electromagnet enable/disable
255Both>255 -- ping/pong

Theta is transmitted in radians on the wire. The Coordinator converts internally; all application-level code uses degrees.

ESP-NOW Protocol (Server to MiniBots)

Binary packed structs defined in ESPNowMessages.h (Server) and messages_espnow.h (MiniBot). Key message types: PositionCommand, MotTestCommand, PositionRequest, PosSync, AckMessage, NackMessage, MagneticFieldRequest, MagneticFieldResponse.


Server-Bot Sync

Before a localization measurement can be taken, every MiniBot needs to know precisely when the electromagnet frame will begin so it can timestamp its magnetometer samples against a common reference.

Initiating a sync is triggered by the Coordinator sending a >7 sync command. The Server's CommunicatorTask handles it as follows:

  1. A PosSyncCommand is broadcast to all bots. The message includes a timeout indicating how long the bots should stay awake listening for the frame.
  2. After a short delay, the Server sends a rapid burst of PosSync pulses. Each carries a next_frame_us field indicating how many microseconds until the electromagnet frame starts.
  3. The ElectromagnetTask fires the frame immediately after the burst completes.

On each MiniBot, when PosSyncCommand is received, EspNowCommunicator sets a deadline and raises waiting_for_pos_sync. The ESP-NOW receive callback captures a high-resolution timestamp the instant each PosSync pulse arrives, before any further processing. The task keeps only the earliest-arriving pulse from the burst — minimum latency gives the best timing accuracy. The estimated frame start is receive_time + next_frame_us from that best pulse.

Once the deadline passes, the bot calls PositionEstimator_SetSyncTime() with the estimated frame-start, then sends an ACK with a small random delay to spread simultaneous responses from many bots. If no pulse arrived in time, it sends ERR_SYNC_TIMEOUT.

Radio duty cycling is tied to sync health. After a successful sync, each bot enables duty cycling to save power. If sync becomes stale, the radio reverts to always-on so the Server can reach the bot to re-establish sync.


Localization

The Server fires each electromagnet in sequence as part of a repeating frame. Each slot has a brief forward and reverse pulse to produce a detectable field, with a known timing offset between slots.

On each MiniBot, PositionEstimator_SensorTask reads the magnetometer continuously. Once a valid sync time is set, it timestamps each sample relative to the frame start and assigns samples to their electromagnet slot by timing alone.

Once a complete frame is collected, PositionEstimator_CalcTask performs trilateration using the field strength readings from the closest electromagnets and their known board positions. This yields an (x, y, orientation) estimate with a confidence score, which is used to weight a low-pass filter before the result is committed to the robot's true pose via robot.setTruePose().


PCB and CAD

Current board designs are in pcbs/:

  • pcbs/MiniBot_MainBoard/ -- MiniBot PCB (ESP32-C3, stepper drivers, magnetometer, LiPo charger)
  • pcbs/Server_Motherboard/ -- Motherboard (ESP32-C3, electromagnet drivers, connectors)

Gerber files are in the GERBERS/ subdirectory of each board folder.

CAD (OnShape): https://cad.onshape.com/documents/4f8eaef75458146767928ab5/w/f159d6d65b9091531e1ead34/e/13b51722310f27710438c727


Firmware

Each firmware project has its own README with task breakdowns, key objects, and build instructions.

  • firmware/MiniBot_Coordinator/ -- Python/PyQt6 host application
  • firmware/MiniBot_Server/ -- ESP32 motherboard firmware (PlatformIO)
  • firmware/MiniBot_StepperClient/ -- ESP32-C3 per-bot firmware (PlatformIO)

Parts

42
QtyValueFootprintReferences
24Conn_01x01TestPoint:TestPoint_THTPad_1.0x1.0mm_Drill0.5mmJ3, J10, J12, J13, J15, J16, J18, J19, J21, J22, J24, J25, J27, J28, J30, J31 +8
12USB4180-03-0120-Cminibot:USB4180030120CJ2, J5, J8, J11, J14, J17, J20, J23, J26, J29, J32, J35
3MountingHole_PadMountingHole:MountingHole_2.7mm_M2.5_DIN965_Pad_TopOnlyH1, H2, H3
2Jumper_2_BridgedJumper:SolderJumper-2_P1.3mm_Bridged_RoundedPad1.0x1.5mmJP1, JP2
1GSB1C41110SSHRminibot:GSB1C41110SSHRJ1

Questions

How big is the Charge Case PCB?

It measures 197.5 × 33 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Charge Case use?

42 parts, built around the USB4180-03-0120-C and GSB1C41110SSHR. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Charge Case KiCad files?

From the DDeGonge/MiniBot repository on GitHub, at the commit this page was made from: the board is pcbs/Charge_Case/Charge_Case.kicad_pcb and its schematic pcbs/Charge_Case/ChargePort.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Charge Case design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

More from DDeGonge/MiniBot

2
  • 2 layers48.8 × 50.4 mmServer Motherboard, the printed circuit board in 3D

    Server Motherboard

    DDeGonge/MiniBot

    Super cheap super tiny bots for....playing chess...

    110 parts47MIT
  • 4 layers21 × 27.9 mmMiniBot, the printed circuit board in 3D

    MiniBot

    DDeGonge/MiniBot

    Super cheap super tiny bots for....playing chess...

    60 parts47MIT

Similar boards

  • 2 layers73 × 20.8 mmLED driver Rev 1.1, the printed circuit board in 3D

    LED driver Rev 1.1

    marksdude/Pikne

    A modular and repairable power bank

    67 parts1
  • 6 layers150 × 87 mmPOWERCORE V2.0 MOTHERBOARD, the printed circuit board in 3D

    POWERCORE V2.0 MOTHERBOARD

    Rack-Robotics/Powercore-V2.0

    Open-Source wire EDM power supply by Rack Robotics, Inc.

    254 parts258
  • 2 layers79.5 × 79.5 mmEsp32-energymeter V2, the printed circuit board in 3D

    Esp32-energymeter V2

    ElektorLabs/esp32-energymeter

    The Elektor ESP32 Energy Meter project, featuring schematics, PCB designs, and ESPHome integration for advanced energy monitoring

    116 parts48MIT
  • 4 layers71.7 × 62.4 mmProject Aether, the printed circuit board in 3D

    Project Aether

    shiva233/Aether

    Project Aether - A2DP Bluetooth Bridge to PC

    91 parts3
  • 2 layers50 × 60 mmGO, the printed circuit board in 3D

    GO

    Ainacteru/GO

    The source code for the GO PCB

    72 parts1
  • 4 layers33 × 34.7 mmEIS PCB, the printed circuit board in 3D

    EIS PCB

    akshayshivkumar/EIS-PCB

    PCB for Electrochemical Impedance Spectroscopy with the AD5941

    54 parts1
  • 4 layers85.9 × 82 mmBalloonMotherboardV4, the printed circuit board in 3D

    BalloonMotherboardV4

    EggiEl/SpiCy-BEXUS

    Cyanobacteria are among the oldest and most efficient photosynthetic organisms on planet Earth. They contribute 25% of the oxygen on Earth today and were crucial in forming our atmosphere in the early stages of Earth's…

    283 parts1
  • 2 layers345 × 121.5 mmDeskFighter, the printed circuit board in 3D

    DeskFighter

    Swonkie/DeskFighter

    Design and production files for DeskFighter keyboard

    213 parts1CERN-OHL-S-2.0