A competition-grade, custom-PCB mini sumo robot running deterministic embedded C++ firmware.
This repository contains the firmware, hardware design files, and documentation for JAGA, a fully autonomous Mini Sumo combat robot. It currently spans two generations:
- Current build (competing): an Arduino-based kit running
mini_sumo.cpp— edge-reactive control with DIP-selectable opening tactics. - Next generation (in development): a custom ATmega32U4-AU PCB (Arduino Leonardo-class) that integrates power regulation, motor driving, and the sensor front-end on a single board — schematic, layout, and manufacturing files in
docs/Mini_Sumo_Pcb/.
The design philosophy is simple: deterministic behavior beats clever behavior. The target firmware architecture is a fixed-rate, non-blocking control loop with layered design, hardware failsafes, and a strategy layer tunable from a single configuration header — no recompiling of core logic between matches.
| Goal | Rationale |
|---|---|
| Deterministic control loop | Fixed-rate sensing → decision → actuation cycle, no blocking calls |
| Layered firmware | HAL → drivers → detection → strategy; portable across MCU targets |
| Failsafe-first | Ring-edge protection has priority over attack behavior, always |
| Single-point tuning | All match-tunable parameters live in one configuration header |
| Observable | Serial telemetry for calibration, tuning, and post-match debugging |
JAGA is designed for the Mini Sumo class (a.k.a. Mini class sumo):
| Parameter | Specification |
|---|---|
| Class | Mini Sumo |
| Max footprint | 100 mm × 100 mm (height unrestricted in most rulebooks) |
| Max mass | 500 g |
| Ring (dohyō) | ~77 cm diameter circular surface, typically black with a white boundary line |
| Match format | Best of 3 rounds, each up to ~3 minutes |
| Autonomy | Fully autonomous after a short start delay (~5 s) — no remote control |
Important
Rulebooks vary between organizers (round length, start delay, edge-marker geometry, forbidden devices). Always validate this checklist against your event's official regulations. See Rules Compliance.
Current build — mini_sumo.cpp (Arduino):
- Fully autonomous after start — waits for the IR start module, deploys the blade servo, then fights with no operator input.
- 8 DIP-selectable opening tactics — forward charges, arc entries, zigzag sweep, and back-and-wait, latched at power-up.
- Edge-priority reactive control — center → right → left arbitration with last-bearing memory, so the ring boundary always wins attention first.
- Bit-banged servo control — precise 500–2500 µs pulse generation for the blade actuator.
- Serial debug output — live sensor and DIP reporting at 9600 baud behind a commented debug block.
Target architecture — custom ATmega32U4 board (in development):
- Fixed-rate, non-blocking control loop — zero
delay()calls in the hot path. - Filtered edge detection — threshold + hysteresis + debouncing to survive specular reflections and dohyō seams.
- Single-header tuning — speeds, thresholds, timeouts, and strategy weights centralized in
config.h. - Hardware failsafes — watchdog timer, brown-out detection, and a physical start/kill switch.
- 4-way strategy DIP + I²C expansion — TCA6408 GPIO expander and castellated pads (
B0–B7,D2–D6) with per-pin 5 V/GND.
flowchart LR
subgraph Sensing["Sensing"]
EDGE["Edge sensors<br/>(reflectance)"]
OPP["Opponent sensors<br/>(IR ranging)"]
BAT["Battery monitor"]
DIP["Strategy DIP switch<br/>(F0 / F1 / F4 / F5)"]
end
subgraph MCU["MCU — Firmware (C++)"]
HAL["HAL / Drivers"]
DET["Detection & Filtering<br/>(hysteresis, debounce)"]
FSM["Strategy / State Machine<br/>(priority arbitration)"]
MIX["Motor Mixer"]
end
subgraph Actuation["Actuation"]
DRV["H-Bridge Motor Driver"]
ML["Left Motor"]
MR["Right Motor"]
end
PWR["DC/Battery input +<br/>Regulation"] --> MCU
PWR --> DRV
EDGE & OPP & BAT --> DET
DIP --> FSM
DET --> FSM
FSM --> MIX
MIX --> DRV
DRV --> ML & MR
Control flow per cycle: sample → filter → arbitrate → actuate. The strategy layer never touches hardware directly; it emits throttle/steer set-points that a single motor mixer translates into PWM output.
JAGA runs on a custom single-board design — designed in Altium Designer, fabricated and assembled by JLCPCB:
| Subsystem | Implementation |
|---|---|
| MCU | ATmega32U4-AU (8-bit AVR, TQFP-44) — crystal (Y1), BOOT (HWB) & RST buttons |
| Motor drive | Two H-bridge drivers (U4, U5) → four motor outputs M1–M4 |
| Power | DC/battery input, power slide switch, fuses & TVS protection, switching + LDO rails |
| USB | USB-C for programming and telemetry |
| Strategy input | 4-way DIP switch (F0 / F1 / F4 / F5) — behavior profile without reflashing |
| I/O expansion | I²C GPIO expander (TCA6408) for additional sensor inputs |
| Expansion headers | Castellated pads along both edges (B0–B7, D2–D6), each with per-pin 5 V and GND |
Note
The complete Altium Designer project — schematic, PCB layout, libraries, and manufacturing outputs (Gerbers, NC drill, pick-and-place, BOM export) — is included under docs/Mini_Sumo_Pcb/.
First revision of the board, fabricated and populated:
Rev A — assembled board (real photos)
Confirm against the exported BOM in
docs/Mini_Sumo_Pcb/4 Motor Driver/Manufacturing Files/before ordering. Onboard electronics reflect the current rev A design; off-board components are representative of the final build.
| Component | Part | Qty | Role |
|---|---|---|---|
| MCU | ATmega32U4-AU (8-bit AVR, TQFP-44) — U1 | 1 | Control |
| Motor driver | Dual H-bridge drivers — U4, U5 | 2 | Four motor channels (M1–M4) |
| Motors | JSumo Core DC Motor — 6 V nominal (up to 15 V), 750 RPM, Ø15 mm, 3 mm × 12 mm shaft, 0.95 kg·cm working / 2.8 kg·cm stall (3.5 A stall), 21 g | 2 | Drive |
| Edge sensors | IR reflectance pair (e.g., TCRT5000-class) angled at front | 2–4 | Ring boundary detection |
| Opponent sensors | Sharp IR ranging (e.g., GP2Y0A21) or ultrasonic | 1–4 | Opponent acquisition |
| Battery / DC input | Gaoneng GNB 380 mAh 3S 11.4 V HV 60C LiPo, XT30 plug — 2-pack (AliExpress) | 1 | Power (spare hot-swap) |
| Flag spinner motors | Hollow-cup (coreless) micro gear motors — 47 / 120 / 720 RPM geared variants (small plastic output shaft) or direct-drive with brass hex hub (AliExpress) | 1–2 | Decoy flags |
| Regulator | Onboard switching regulator + LDO rails | — | Logic & motor supply |
| Wheels | Silicon Wheels — self-cast PL30 (~30 Shore A) 2-part platinum-cure silicone tires on JSumo JS2622 machined aluminum rims, Ø26.5 × 22 mm, 3 mm bore, M4 setscrew (cast in the repo's two-piece FDM mold) | 2 | Traction (24 g/pair) |
| Chassis blade | Front scoop / wedge, ground-hugging | 1 | Opponent lift |
Signals as printed on the board silkscreen (ATmega32U4 port/pin naming — e.g. PB0 → B0):
| Group | Signals | Function |
|---|---|---|
| Motor outputs | M1 M2 M3 M4 |
Four H-bridge channels to the drive motors |
| Expansion pads — edge A | B0 B2 B7 D3 D4 |
GPIO, each with adjacent 5 V and GND |
| Expansion pads — edge B | D6 D5 D2 B3 B1 |
GPIO, each with adjacent 5 V and GND |
| Strategy select | F0 F1 F4 F5 |
4-way DIP switch (S4) |
| Sensor connector | E6 (+5 V, G) |
3-pin sensor header |
| USB | USB-C (J2) | Programming & telemetry |
| Control | BOOT, RST |
Bootloader & reset buttons |
Tip
Firmware pin assignments live in firmware/include/config.h and must mirror this netlist.
- Separate logic and motor rails; motor noise must never reset the MCU.
- Star-ground or solid ground plane on the custom PCB; bulk capacitance (≥ 470 µF) across the motor supply.
- Fuse or PTC on the battery input; verify brown-out detector is enabled on the MCU.
The sheet is organized into seven labeled functional blocks:
| Block | Contents | Purpose |
|---|---|---|
| DC INPUT | DC jack, fuse & reverse-polarity protection, input filtering, logic regulator | Accepts the battery (2S–3S LiPo class) and steps it down to stable, protected logic rails |
| MOTORS +5 V | Dedicated 5 V switching regulator (L1), bulk & output capacitors |
Motor-only supply — startup surges and noise never reach the microcontroller |
| MCU | ATmega32U4-AU (TQFP-44): power/reset, crystal, ISP header, decoupling caps | Reads sensors, executes the control loop, commands the drivers |
| USB | Connector with D+/D− data lines, ESD protection |
Firmware upload, debugging & PC telemetry (native USB on the 32U4) |
| DIP SWITCH | 4-pole switch with pull-ups (F0/F1/F4/F5) |
Hardware behavior selection — up to 16 profiles without reflashing |
| I/O EXPANDER | TCA6408 I²C GPIO expander with port pull-ups | Extra digital I/O for sensors and indicators when MCU pins run out |
| MOTOR DRIVERS | Two dual H-bridge ICs on the 5 V motor rail, protection capacitors | Forward/reverse motor control with sufficient current for the drive motors |
Modular by design: protected power → isolated motor supply → MCU brain → expandable I/O → robust drive stage.
The robot's mechanical platform is designed in Shapr3D — a wedge-form chassis with a ground-hugging front blade, a rear drive hump, and a recessed bay for the custom control board:
Shapr3D renders — wedge & blade assembly (left) and underside / PCB bay (right)
| Feature | Design intent |
|---|---|
| Wedge & blade | Angled front face ending in a thin, ground-hugging blade edge (modeled as a separate insert) to get under the opponent and steal traction |
| Rear drive hump | Curved rear housing with axle bores carrying the drive wheels — sized for the Silicon Wheels drive pair (cast PL30 silicone on JSumo JS2622 rims; Ø26.5 × 22 mm, 3 mm hub bore, M4 setscrew retention) |
| PCB bay | Recessed interior cavity with a flat deck and corner posts for mounting the custom ATmega32U4 board |
| Side cutouts | Trapezoidal lightening openings to hold mass inside the 500 g budget and route wiring |
| Deck bosses | Screw posts on the top deck for a lid / component mounting |
Tip
Keep blade-to-ring clearance minimal (~0.5–1 mm) — every millimetre of daylight under the blade is a millimetre the opponent can dig into.
Next-generation sensing uses a custom sensor module designed in EasyEDA Pro — a complete IR reflectance sensor on a 8.984 × 5.047 mm board, the smallest dedicated mini-sumo sensor module on the market (a fraction of the footprint of off-the-shelf TCRT5000-class breakouts):
Sensor module — top (left): castellated S / V / G pads · bottom (right): ICSP DIO / CLK / VPP pads
| Subsystem | Implementation |
|---|---|
| MCU | PIC12F1572 (8-bit PIC, DFN-8) — on-board signal conditioning, single digital S output |
| Emitter | IR LED (PT19-21B/L41/TR8) + auxiliary 0603 IR LED (ZIR-1608C-06A-Z4, 59 Ω limit), MOSFET low-side drive (2N7002-class) |
| Detector | Reflective IR photodetector (U4) |
| Power | Reverse-protection dual Schottky (SDM02U30LP3-7B), 10 µF bulk + 100 nF decoupling |
| Interface | Castellated edge pads S / V / G on the top face — drop-in 3-pin module |
| Programming | ICSP pads (DIO / CLK / VPP) on the bottom face — flash in-system without desoldering |
Note
EasyEDA Pro manufacturing outputs — all Gerber layers, NC-drill files, and flying-probe test data — are included under docs/Mini_Sumo_Sensor_Pcb/.
Written for the Arduino platform using the IronBrick kit library (ironbrick.h). Execution flow:
- Wait for the IR start module (
D10) — blade servo held deployed. - On start: retract the blade servo, latch the DIP tactic (runs once).
- Reactive loop — edge sensors steer: center → forward charge, right → right pivot, left → left pivot. When no edge is seen, hold the last bearing at reduced speed.
Pin map (as coded):
| Signal | Pin | Mode | Function |
|---|---|---|---|
LSens |
A0 |
Input, pull-up | Left edge sensor (active LOW) |
RSens |
A1 |
Input, pull-up | Right edge sensor (active LOW) |
MSens |
A2 |
Input, pull-up | Center edge sensor (active LOW) |
DS1–DS3 |
A3–A5 |
Input, pull-up | Tactic DIP switch |
| Servo | D8 |
Output | Blade actuator — bit-banged 500–2500 µs pulses |
| Start | D10 |
Input | IR start module |
DIP tactic selection:
| DS1 | DS2 | DS3 | Opening tactic |
|---|---|---|---|
| 0 | 1 | 1 | Forward → 2 s wait → left-arc charge |
| 1 | 0 | 1 | Forward charge (long) |
| 1 | 1 | 0 | Forward charge (short) |
| 0 | 0 | 1 | 1/8 right arc → charge |
| 0 | 1 | 0 | Back off and wait |
| 1 | 0 | 0 | Right zigzag sweep |
| 0 | 0 | 0 | Right arc turn → charge |
| 1 | 1 | 1 | Left arc turn → charge |
DS lines are read with internal pull-ups (
0= switch closed / LOW). Tactics run once after start; edge reactions take over for the rest of the match.
The subsections below describe the firmware architecture designed for the custom ATmega32U4 board.
- Layered: HAL → peripheral drivers → detection services → strategy. Each layer only calls the layer beneath it.
- Non-blocking: the main loop is a fixed-rate scheduler; long operations are state machines, not loops.
- Single source of truth: all tunable constants in one
config.hwith comments documenting ranges and units.
stateDiagram-v2
[*] --> Idle
Idle --> StartDelay : kill switch released
StartDelay --> Search : start delay elapsed (~5 s)
Search --> Charge : opponent acquired
Search --> EdgeRecover : edge detected
Charge --> EdgeRecover : edge detected
Charge --> Search : contact lost / timeout
EdgeRecover --> Search : recovery maneuver complete
Search --> Idle : kill switch engaged
| State | Behavior |
|---|---|
Idle |
Motors disabled, status LED slow blink, waiting for handler |
StartDelay |
Mandatory stationary period after switch release (rule compliance) |
Search |
Patterned scan (sweep/spin) to acquire the opponent |
Charge |
Full-speed pursuit and push along the acquired bearing |
EdgeRecover |
Highest priority — stop, reverse, rotate toward ring center |
void loop() {
scheduler.tick(); // fixed-rate task scheduling, no blocking
sensors.read(); // 1. sample edge + opponent sensors
edge.update(); // 2. filter: threshold + hysteresis + debounce
opponent.update();
strategy.run(edge, opponent); // 3. arbitrate: edge > charge > search
strategy.output(throttle, turn);
motors.drive(throttle, turn); // 4. slew-limited differential output
telemetry.tick(); // 5. non-intrusive serial logging
}.
├── mini_sumo.cpp # Competition firmware — Arduino (IronBrick platform)
├── hardware/ # Reserved: bring-up notes & future board revisions
├── docs/
│ ├── images/ # PCB renders, schematic, real build photos
│ └── Mini_Sumo_Pcb/ # Altium Designer project & manufacturing files
│ └── 4 Motor Driver/
│ ├── 4_Motor_Driver/ # .SchDoc, .PcbDoc, libraries, .OutJob
│ └── Manufacturing Files/ # Gerbers, NC drill, pick & place, BOM
├── tests/ # Host-side unit tests for logic modules
└── README.md
| Tool | Purpose |
|---|---|
| Arduino IDE 2.x (or Arduino CLI) | Current build — compile & upload mini_sumo.cpp |
IronBrick kit library (ironbrick.h) |
Motor/servo abstraction for the current build |
Serial terminal (Serial Monitor, PuTTY, minicom) |
Telemetry & debug (9600 baud current build) |
| PlatformIO + AVR-GCC (or the Arduino IDE) | Custom ATmega32U4 board — when its firmware lands |
| USB-C cable and/or ISP programmer (e.g., USBasp) | Flashing the custom board / burning the bootloader |
- Install the Arduino IDE and the IronBrick library that ships with the kit.
- Open
mini_sumo.cpp. - Select the board and port, then Upload.
- For live sensor/DIP reporting, uncomment the debug block in
loop()and open Serial Monitor @ 9600 baud.
The custom board is Arduino Leonardo-compatible (ATmega32U4-AU with the Caterina USB bootloader):
pip install platformio
pio run # compile
pio run --target upload # flash over USB-C via the Caterina bootloader
pio device monitor --baud 115200Tip
In the Arduino IDE, select the Arduino Leonardo board and upload directly over USB-C. An external ISP programmer (e.g., USBasp) is only required to (re)burn the bootloader.
- ✅ Verify battery polarity and rail voltages with a multimeter before connecting the MCU.
- ✅ Flash firmware with motors mechanically lifted (wheels off the ground).
- ✅ Confirm the kill switch immediately disables motors at any time.
- ✅ Run calibration before the first test on a ring.
Today the tunables (speeds, tactic timings, sensor pins) sit at the top of mini_sumo.cpp; the custom-board firmware will centralize them in config.h. Calibrate in this order:
| # | Parameter | Procedure |
|---|---|---|
| 1 | Edge sensor thresholds | Place robot on the black ring surface → record readings; place on the white boundary → record; set threshold between them with hysteresis margin |
| 2 | Opponent sensor range | Verify detection at your intended engagement distance; adjust threshold to reject ring boundary/audience noise |
| 3 | Motor ramping | Increase slew limit until wheels never slip on hard acceleration from standstill |
| 4 | Search pattern | Tune sweep speed so the opponent sensor dwell time covers the full forward arc |
| 5 | Charge speed | Maximum speed that retains traction and controllability on ring contact |
| 6 | Edge recovery | Tune reverse duration + turn angle to reliably re-center from any edge position |
| 7 | Start delay | Set to match your event's rulebook (commonly ~5 s) |
Tip
Re-verify edge thresholds on the actual competition surface — lighting and surface finish shift readings more than any other factor.
The firmware prints a single line per cycle (rate configurable):
[edge:FL=812 FR=790] [opp:L=42cm R=38cm] [state=CHARGE] [pwm:L=+230 R=+218]
- LiPo batteries: charge only in a LiPo-safe bag/charger; never leave charging unattended; store at ~3.8 V/cell.
- Kill switch discipline: never work on the drivetrain with the battery connected.
- Bench testing: always test with wheels off the ground before floor runs.
- Sharp edges: the front blade can pinch — keep fingers clear during powered tests.
- Competition: the robot must be de-energizable in one action by the handler at any time.
Use as a pre-registration checklist (adapt to your event's rulebook):
- Mass ≤ 500 g (weigh final assembly, with battery)
- Footprint ≤ 100 mm × 100 mm
- No liquids, projectiles, fire, entanglement, or jamming devices
- No devices intended to damage the ring or opponent's electronics
- Fully autonomous after start; no remote control or signals
- Starts/stops by handler action only; cannot move before start delay elapses
- Does not damage or mark the dohyō surface
- Battery secured against impact; no exposed conductors
- Custom PCB rev A — designed in Altium Designer, fabricated & assembled via JLCPCB
- Competition firmware v1 (Arduino/IronBrick): drive, edge protection, 8 DIP tactics
- Migrate firmware to the custom ATmega32U4 board (layered, non-blocking architecture)
- PCB CAD sources, Gerbers & BOM published in
docs/Mini_Sumo_Pcb/ - Chassis — wedge body & blade designed in Shapr3D (renders in
docs/images/) - Custom mini-sumo sensor module — designed in EasyEDA Pro, 8.984 × 5.047 mm (Gerbers in
docs/Mini_Sumo_Sensor_Pcb/) - Gyro-assisted heading hold (IMU)
- Bluetooth telemetry app for tuning between matches
- Host-side unit test suite for detection & strategy modules
- Photographic assembly guide
Contributions are welcome!
- Fork / branch from
main. - Follow the existing code style (layered architecture, no blocking calls in the control path).
- Keep behavioral changes testable on the bench — document tuning impacts in
docs/. - Commit with clear, conventional messages (
feat:,fix:,docs:,hw:). - Open a Pull Request describing hardware impact (if any) and test evidence.
All rights reserved. © 2026 AnastKara.
The firmware, hardware design files (schematics, PCB layouts, Gerbers, BOM exports), images, and documentation in this repository are the proprietary work of the copyright holder. No part of this repository may be reproduced, distributed, modified, or used — in source, binary, or hardware form — without prior express written permission. See LICENSE for the full notice.
Third-party libraries and toolchains (e.g., the IronBrick kit library, the Arduino core) remain under their own respective licenses.
Note
Want to build on, fork, or reference this project (e.g., for a specific event)? Reach out to the repository owner for permission.
| Sponsor | Support for JAGA |
|---|---|
| JLCPCB | PCB fabrication & assembly — the rev A custom board was fabricated and assembled by JLCPCB |
| EasyEDA | Online EDA platform for schematic capture & PCB design |
- The international sumo robotics community and the public mini sumo rulebooks that standardize the class.
- Silicon Valley of hobby robotics: open datasheets and driver libraries for DRV8833 / TB6612FNG-class motor drivers.
- Our sponsors — JLCPCB and EasyEDA — for making the custom board builds possible.
- Every opponent who taught us a new edge-recovery failure mode.
Built to push. Designed to hold the ring.
Star this repo if it helped your build!



