Skip to content
Team · Competitive Robotics

HAN Competitive
Robotics Team

FounderTechnical Lead

Jun 2025 – Present · Featherweight class · ESP32 · nRF24L01+ · FreeRTOS

The robot

Image placeholder

HAN featherweight combat robot
01 · Overview

As founder and technical lead of HAN's competitive robotics team, I built a featherweight combat robot's full control stack from scratch: a Python ground station, a 2.4 GHz radio bridge, and dual-core ESP32 firmware. One principle runs through the whole design: the driver station stays stateless, and the robot enforces every safety rule on its own.

02 · System Architecture
Node 1

Driver station

Laptop · Python / Pygame

Gamepad or keyboard input, arcade & tank mixing, the arming state machine.

Node 2

Radio bridge

nRF52840 dongle · Zephyr

A USB-CDC to 2.4 GHz bridge that relays packets to the robot.

Node 3

Robot

ESP32 DevKit · ESP-IDF

Receives packets and drives everything: motors, weapon, and all failsafes.

driver station → radio bridge → robot · one-way, un-ACKed ESB link by design

03 · Robot Hardware

Drive

Two bidirectional motors on left/right ESCs (GPIO 13/14).

Weapon

Brushless motor + 8BL150 150 A ESC, with a Hall encoder (2 ppr) read via the ESP32 PCNT peripheral.

PWM

All three ESCs run as 50 Hz servo PWM (1000–2000 µs) off a single MCPWM timer, so they stay phase-synced.

Radio

nRF24L01+ on SPI (8 MHz, manual CS), speaking Nordic ESB on channel 40 at 2 Mbps.

Sensors

Three BMP280s used as temperature sensors for two drive wheels and the weapon, across two I²C buses.

Power

Current-sense driver code is present but inactive; battery spec to be added.

Electronics bay

Image placeholder

ESP32, ESCs & internal wiring
04 · Firmware

Three FreeRTOS tasks split across both ESP32 cores, talking through a depth-1 overwrite queue (always-latest state) and C11 atomics for the thermal flags and encoder RPM.

Core 0 · pri 3

Radio RX & drive

Blocks on an interrupt semaphore rather than polling, writes the drive ESC outputs, and runs the packet-timeout failsafe.

Core 1 · pri 2

Weapon loop @ 100 Hz

A fixed-rate control loop paced precisely with vTaskDelayUntil.

Core 1 · pri 1

Thermal monitor @ 1 Hz

Polls the BMP280s and raises the thermal flags the other tasks act on.

What's actually wired up
  • Drive mixing lives in the ground station, not the robot. The robot maps each byte linearly to ±100% throttle; arcade/tank mixing, and a flip-recovery drive-invert, run in Python.
  • The weapon's PI controller runs open-loop. The closed-loop framework (anti-windup, 3000/5000 RPM targets) is in place, but the gains are zero, so it runs on a 50% feed-forward baseline. Encoder RPM is read and logged, but not yet closing the loop.
  • The radio link is one-way. The robot prints RPM and temperatures to local USB serial for debugging. Nothing is sent back to the driver.
05 · Safety Systems

The driver station is stateless; the robot enforces all of this independently.

Signal-loss failsafe

500 ms with no valid packet stops all motors and zeroes the weapon. It auto-recovers on the next good packet.

Killswitch → deep sleep

A killswitch bit latches a hard failsafe and drops the ESP32 into deep sleep; power-cycle only to recover. The station fires a 5-packet burst so a dropped one still lands.

Thermal deep-sleep @ 90 °C

Checked on every received packet (~20 ms), not in the slow 1 Hz loop, so an overheating pack trips it fast.

Per-motor cutoff @ 100 °C

The only reversible thermal protection, with 10 °C hysteresis. A failed or NaN sensor reading also cuts that motor.

Arming state machine

safe → idle → attack in the station; any disarm or failsafe forces neutral and drops straight back to safe.

Documented limitations

The things I know aren't done yet, and would close next:

  • No encoder-fault detection: if the Hall sensor disconnects, the weapon keeps spinning on the 50% feed-forward.
  • The newline-delimited serial framing can desync if a motor byte happens to be 0x0A.
  • The nRF link ACKs unnecessarily because of a feature-register setting.
06 · Stack
Embedded CESP-IDFFreeRTOSDual-core RTOSESP32nRF24L01+Nordic ESBZephyrPythonPygameMCPWMPCNTSPII²CESC / PWM controlC11 atomicsReal-time controlFailsafe design