A 1 kg / 20×20 cm sumo combat robot built for the Makers Club sumo competition at Constructor University Bremen. A single ESP32 handles Bluetooth gamepad input, the two drive motors, and a linear-actuator flipper.
The objective is sumo-style: push the opposing robot out of the ring. That set the design constraints — stay inside the 1 kg and 20×20 cm limits, put as much of the mass as possible over the drive wheels, and survive being rammed.
The robot runs a 4S LiPo pack (two 2S packs in series) through a fused, switched main feed into two regulated rails: +12 V for the motor drivers and +5 V for the ESP32. Drive is tank-style from an Xbox controller over Bluetooth, with a linear actuator driving a pivot-lever flipper arm.
| Weight limit | 1 kg |
| Size limit | 20×20 cm |
| Printed-part mass | ~300 g (estimated) |
| Total mass | ~838 g (estimated, not verified on a calibrated scale) |
| Drive motors | 2× 25GA-370, 12 V, 100 RPM |
| Drive motor driver | TB6612FNG dual H-bridge |
| Actuator | Linear actuator, 12 V, 60 N, 25 mm stroke |
| Actuator driver | Dual H-bridge actuator driver, represented functionally as U4 in the schematic |
| Controller | ESP32 (Bluetooth, Bluepad32) |
| Battery | 2× 7.4 V 2200 mAh LiPo in series (14.8 V nominal / 16.8 V maximum) |
| Chassis | PETG, adapted from a third-party design |
| Wheel grip | 1 mm SBR rubber self-adhesive strip |
I independently created the Fritzing electrical schematic and developed the ESP32 control integration. I also contributed to the Fusion 360 mechanical design and worked with teammates to build, assemble, wire and integrate the final robot.
Embedded — ESP32, C++, FreeRTOS task design and inter-core data handoff, hardware PWM (LEDC), Bluepad32 / Bluetooth gamepad integration, failsafe and safe-state design.
Electrical — H-bridge motor drivers (TB6612FNG), power distribution and rail budgeting, buck regulation, fusing and switching, common-ground design, schematic capture in Fritzing.
Mechanical — Fusion 360, PETG and additive manufacturing, print-settings selection for load-bearing parts, mechanism integration.
Tooling — PlatformIO (pinned, reproducible builds), Git.
Xbox controller ──Bluetooth──▶ ESP32
│
Core 0: Bluetooth polling, input capture
│ (copied command state)
Core 1: motor + actuator control loop
┌────────┴────────┐
TB6612FNG Actuator driver
┌───┴───┐ │
Left Right Linear actuator
motor motor (flipper)
Power path:
2S LiPo + 2S LiPo in series (14.8 V nom / 16.8 V max)
│
Fuse ──▶ Master switch ──▶ RAW_4S
│
├──▶ 12 V buck ──▶ +12V_MOTOR ──▶ TB6612FNG VM
│ └──▶ actuator driver VS
│
└──▶ 5 V buck ──▶ +5V_LOGIC ──▶ ESP32 VIN/5V
└──▶ 3.3 V out ──▶ TB6612FNG VCC
All negatives and grounds tie to one COMMON_GND node.
The 12 V rail exists because of a hard constraint: the TB6612FNG's absolute maximum VM is 15 V, and its recommended operating maximum is lower still. A fully charged 4S pack sits at 16.8 V, which is above that absolute maximum, so the pack cannot feed VM directly. Regulating the motor rail to a fixed 12 V keeps VM inside the device's operating range across the whole discharge curve.
Full pin-by-pin reference: wiring/wiring_notes.md.
Functional Fritzing schematic of the robot's power and control architecture. All ground symbols represent the same COMMON_GND electrical node. Some control wires visually share routes because of Fritzing's grid and connector geometry; critical nets were individually verified using Fritzing's connectivity highlighting. U4 represents the actuator's dual H-bridge driver functionally; its VSS and ENB wiring is not prescribed here because carrier-board implementations differ — see Engineering notes below.
This schematic is documentation of the intended architecture. It is not a simulation, and it is not evidence of electrical safety or thermal adequacy.
This schematic image was created with Fritzing. It incorporates Fritzing part
graphics (CC BY-SA 3.0) and is therefore shared under
CC BY-SA 3.0, not under this
repository's MIT licence — see THIRD_PARTY_NOTICES.md.
ESP32 → TB6612FNG (drive motors)
| TB6612FNG pin | ESP32 GPIO | Function |
|---|---|---|
| PWMA | GPIO 14 | Left motor PWM |
| AIN1 | GPIO 27 | Left motor direction A |
| AIN2 | GPIO 26 | Left motor direction B |
| BIN1 | GPIO 25 | Right motor direction A |
| BIN2 | GPIO 33 | Right motor direction B |
| PWMB | GPIO 32 | Right motor PWM |
| STBY | GPIO 13 | Standby — HIGH enables the driver |
| VM | +12V_MOTOR | Motor supply |
| VCC | ESP32 3.3 V | Logic supply |
| GND | COMMON_GND | Ground |
| TB6612FNG output | Connects to |
|---|---|
| AO1 / AO2 | Left motor |
| BO1 / BO2 | Right motor |
ESP32 → actuator driver
| Driver pin | ESP32 GPIO | Function |
|---|---|---|
| IN3 | GPIO 16 | Actuator direction input 1 |
| IN4 | GPIO 17 | Actuator direction input 2 |
| VS | +12V_MOTOR | Actuator supply |
| GND | COMMON_GND | Ground |
| OUT3 / OUT4 | — | Actuator leads |
| VSS, ENB | — | Not prescribed — carrier-dependent, see Engineering notes |
GPIO16 drives IN3 and GPIO17 drives IN4 — the two direction inputs of the
actuator H-bridge channel. Which of them produces physical extension depends on
how the actuator leads are landed on OUT3/OUT4; that direction is set during
bench testing, either by swapping the two leads or by setting INVERT_ACTUATOR
in the firmware.
On the physical robot, high-current returns should land on a proper common power-ground distribution point, not routed through the ESP32 board or a breadboard.
Stack: C++ on the Arduino-ESP32 core (FreeRTOS), built with PlatformIO. Bluetooth gamepad support via Bluepad32.
Two tasks pinned to separate cores:
- Core 0 — Bluetooth task. Calls
BP32.update()and owns the Bluepad32 controller object. It copies the axes, buttons and connection flag it needs into a small plain-old-data command struct and publishes that under a spinlock. The controller object itself never leaves this task. - Core 1 — control task. Runs on a fixed 2 ms period, consumes the published command struct, mixes tank drive, applies the slew-rate limiter, and writes the motor and actuator outputs.
Motion smoothing. A deterministic slew-rate limiter bounds how fast the
commanded PWM magnitude can change: at most 5 counts per 2 ms control period,
so a full 0 → 255 transition takes roughly 102 ms. SLEW_STEP_PWM and
CONTROL_PERIOD_MS are configurable starting parameters rather than fixed
constants — they can be tuned for a given robot's traction, mass distribution
and desired responsiveness once measured on hardware.
Turbo (Y button). Bypasses command smoothing and immediately applies the current joystick command. It is not a power boost — at half stick it produces half output, just without the slew limit.
Failsafe behaviour.
- No controller connected — at boot, on disconnect, or on loss of link — both PWM outputs go to zero immediately, the actuator stops, and the TB6612FNG is put into standby (STBY LOW). This path bypasses the slew limiter entirely.
- On reconnect, the smoothed drive state is reset to zero before STBY is re-asserted, so a stale command can never produce motion.
- Actuator: neither button pressed, or both pressed together, stops the actuator. Exactly one button commands that direction.
Controls
| Input | Action |
|---|---|
| Left stick Y | Forward / backward |
| Right stick X | Turn |
| Y button | Bypass command smoothing; apply current joystick command immediately |
| R1 (hold) | Drive actuator one way |
| L1 (hold) | Drive actuator the other way |
Implementation: esp32/src/main.cpp.
Flashing and bench-test procedure: UPLOAD_GUIDE.md,
including a TEST_MODE self-test (disabled by default) and inversion flags for
correcting motor and actuator direction without rewiring.
The chassis is adapted from the third-party Sumo Robot Combate chassis design previously published on Cults3D, with enlarged front openings for the flipper mechanism. It was not designed from scratch. Its licence could not be verified, so no model files are redistributed here. The flipper arm is a pivot-lever mechanism sized to get useful mechanical advantage out of the actuator's 25 mm stroke; an early parametric OpenSCAD attempt did not produce a print-ready part and was replaced by the Fusion 360 design that was actually printed.
All structural parts are PETG. Wheel grip is 1 mm self-adhesive SBR rubber strip.
No CAD files are distributed in this repository. No editable Fusion 360 or STEP source is included, and the third-party chassis models are not redistributed — see Credits and licence.
Power and wiring integration on the bench — bringing up the ESP32, buck converters, motor drivers and motors, checking each stage before connecting the next:
Final printed chassis with the linear actuator and electronics mounted:
The Ghost Robot was mechanically assembled and electrically integrated as a complete, functioning platform: chassis, drivetrain, actuator, power distribution and control electronics came together into one robot that competed in the Makers Club sumo event. Its drive motors and linear actuator were exercised from an Xbox controller over Bluetooth during bench integration and testing.
I independently created the complete Fritzing electrical schematic covering the robot's power distribution, motor drivers and control wiring, and developed the ESP32 firmware that drives the robot.
This repository documents that work and provides:
- the ESP32 firmware source, built around a dual-core FreeRTOS architecture;
- a pinned, reproducible PlatformIO build that compiles from a clean checkout;
- the wiring architecture and a pin-by-pin reference;
- build and integration photographs; and
- documentation covering the electrical design, firmware behaviour and mechanical integration.
The firmware in this repository is built around a safety-focused control architecture:
- Neutral startup — every output is explicitly driven to a safe state before either FreeRTOS task starts, rather than relying on power-on register defaults.
- Single-writer hardware ownership — only the motor-control task ever writes to the motor driver, the actuator driver or the standby line, which removes an entire class of cross-task race conditions.
- Controller-loss shutdown — losing the Bluetooth link drives both motors and the actuator to zero and puts the driver into standby, bypassing motion smoothing entirely.
- Neutral-state reconnect handling — reconnecting always starts from a zeroed command state before the driver is re-enabled, so a stale command can never move the robot.
- Actuator conflict handling — pressing both actuator buttons together stops the actuator rather than picking a direction.
- Configurable motion smoothing — a deterministic slew-rate limiter bounds how fast commanded motor power can change; see Firmware architecture above for the parameters.
The actuator driver is represented functionally as U4 in the schematic, because the exact carrier-board variant used was not preserved. Its module-specific logic-supply (VSS) and enable (ENB) configuration is therefore not presented as a universal wiring instruction — carrier-board implementations differ enough between manufacturers that a specific pinout here could mislead anyone reproducing the design with different hardware.
Anyone reproducing the robot should select motor drivers, converters, fusing,
connectors and wiring based on the measured startup and stall currents of their
own hardware, rather than assuming the values used here. Detailed first-power
and bring-up guidance is in UPLOAD_GUIDE.md.
.
├── esp32/
│ ├── platformio.ini Pinned build configuration
│ └── src/main.cpp Drive + actuator firmware
├── wiring/
│ └── wiring_notes.md Pin-by-pin wiring reference
├── cad/
│ └── README.md Mechanical design notes (no model files)
├── media/
│ ├── final_chassis_hero.jpeg
│ ├── final_chassis.jpeg
│ ├── power_wiring_bench.png
│ └── wiring_overview_fritzing.png
├── UPLOAD_GUIDE.md Flashing and first-power procedure
├── THIRD_PARTY_NOTICES.md Third-party attributions
├── LICENSE MIT (original code and documentation)
└── README.md
Build it:
cd esp32
pio runThe chassis is adapted from the third-party Sumo Robot Combate chassis design previously published on Cults3D. Its licence could not be verified, so no third-party CAD models are redistributed here.
Bluetooth gamepad support is provided by Bluepad32 by Ricardo Quesada.
The schematic image media/wiring_overview_fritzing.png was created with
Fritzing and is shared under
CC BY-SA 3.0, because it
incorporates Fritzing part graphics.
Original firmware and documentation in this repository are released under the
MIT licence. That licence covers this repository's own code and
documentation only — it grants no rights to third-party designs, models,
libraries or part graphics. See
THIRD_PARTY_NOTICES.md.



