A wireless RC Batmobile with a 4-DOF robotic arm mounted on top. Two ESP32 boards talk over ESP-NOW: one reads the custom controller (joystick, rotary encoder steering wheel, 4 potentiometers), the other drives the car and the arm in real time.
CONTROLLER (master ESP32) CAR (receiver ESP32)
├─ Joystick Y-axis → drive command ├─ L298N → 2x brushed DC motors (rear)
├─ KY-040 encoder → steering angle 0-180 ├─ PCA9685 ch0 → steering servo
└─ 4x potentiometer → arm joint angles └─ PCA9685 ch1-4 → 4x MG90S arm servos
│ ▲
└────────────── ESP-NOW packet ──────────────┘
{pot1..4, steeringAngle, command}
The master samples every input, packs it into a single struct, and fires it over ESP-NOW every 150 ms. The receiver decodes the packet, sets motor direction and PWM speed through the L298N, and writes five servo channels on the PCA9685. If the radio link drops for more than 1 second, the receiver stops the motors and re-centers the steering on its own.
The controller is its own build: a 3D printed steering wheel geared to a KY-040 rotary encoder for full 0-180 degree steering resolution, a joystick for throttle, and four potentiometers, one per arm joint, so the whole arm can be posed live while driving.
| Part | Details |
|---|---|
| 2x ESP32 (38-pin WROOM) | master controller + receiver |
| L298N motor driver | 2x 6V brushed DC drive motors |
| Adafruit PCA9685 | 16-channel I2C PWM board, runs all 5 servos |
| 5x MG90S micro servo | steering + 4 arm joints |
| KY-040 rotary encoder | precision steering, quadrature-decoded in an ISR |
| Dual-axis joystick | throttle forward/backward |
| 4x 10k potentiometer | one per arm joint |
| 3S LiPo 11.1V 2200mAh | main power |
| HEYXI UBEC 5V/6V | clean regulated servo power |
The chassis is fully 3D printed (based on the OpenRC F1 platform) plus a printed 4-joint arm, printed body panels, gears, axles, and a printed steering wheel for the controller. The body shell is a 4-piece printed Batmobile cover (50 cm long, 1:10 scale) with a removable top hatch for battery access. Full parts list, STL inventory, assembly schematics, and fastener counts are in the project report.
src/master.ino— controller: input sampling, encoder ISR with safe-range clamping, ESP-NOW transmitsrc/receiver.ino— car: packet decode, motor control, servo mapping, 1 s failsafe timeout
- ESP32 pins 36 (VP) and 39 (VN) are input-only ADCs. They work for reading potentiometers but can never be digital outputs or PWM.
- The L298N sings at low duty cycles. At ~27% duty the 1 kHz PWM sits right in the audible range and the motor windings resonate with it. Raising the PWM frequency (or a modern driver) kills the noise.
- Servo stability is a power problem. Jitter disappeared after moving servo power to a dedicated UBEC and tying grounds between the ESP32, L298N, and UBEC.
- A failsafe is not optional on a wireless car. The receiver treats 1 s of radio silence as a stop command.
The complete write-up lives in docs/Batmobile-and-Robot-Arm-Report.pdf: requirements, Gantt chart, every 3D printed part with renders, wiring schematics, source code, and the debugging story.



