ESP32 RC Remote

A home-made, two-joystick remote control and a matching receiver, for driving my own radio-controlled builds without buying a commercial transmitter.

The handheld transmitter is a 3D-printed case around an ESP32-C3 board, two thumbsticks and a rechargeable battery. It talks straight to an ESP32 in the vehicle using ESP-NOW on 2.4 GHz, a direct board-to-board link with very little lag and no Wi-Fi router or phone signal needed. It's meant for custom RC projects such as off-road rigs or bait boats.

The finished orange 3D-printed remote from the front, with two black thumbsticks and the ESP32-C3 board mounted on top
The assembled transmitter.

How it works

  • Direct link. ESP-NOW sends short packets straight from one ESP32 to another, fixed to Wi-Fi channel 6 (2.437 GHz), with the transmitter at its maximum output of 19.5 dBm.
  • Four axes, two buttons. Each thumbstick gives an X and a Y reading, read by the ESP32-C3's 12-bit converter (0–4095), plus a push button.
  • About 20 updates a second. The transmitter sends every 50 ms.
  • Rechargeable. A single 18650 lithium-ion cell, charged over USB-C through a TP4056 board, with a step-up converter for the electronics.
  • Receiver. A classic ESP32 in the vehicle drives the motor controllers, servos or relays, and uses its onboard LED to show the link status and failsafe.

Parts and cost

PartQtyJobLocal (ZAR)Imported
ESP32-C3 SuperMini1Transmitter boardR75–R110R40–R55
ESP32 Dev Module (classic)1Receiver in the vehicleR90–R120R50–R70
Dual-axis joystick modules2Throttle and steeringR24–R50R15–R20
TP4056 charger module1USB-C charging and battery protectionR15–R25R8–R12
PETG filament~150 gCase panels and platesR45–R65R30–R40
M3 hardware and wiring—Screws, standoffs, silicone wireR20–R35R10–R15
TotalR269–R405R153–R212

The case

The transmitter is built from stacked, screwed-together panels. That keeps it stiff and means any part can be opened up to swap or service the electronics.

The remote taken apart into its stacked orange panels, with the joystick and boards visible between the layers The remote from the side and back, showing the battery compartment and the board mounted on top
Left: the stacked panels opened up. Right: the side and back, with the battery compartment.
  • Faceplate: recessed cut-outs so both thumbsticks move through their full range.
  • Standoffs: built-in bosses for M3 self-tapping screws or heat-set brass inserts.
  • Electronics: channels to hot-glue or plate-mount the TP4056 charger and the ESP32-C3 next to the USB cut-outs.

Print settings: PETG (tougher, more UV- and heat-resistant than PLA), 0.20 mm layers, 20–30% grid or gyroid infill, 3 walls and 4 top and bottom layers. Supports are only needed around the counter-bored M3 holes and a few cut-outs.

An earlier fit-up of the remote from the front, with one thumbstick fitted The underside of the remote held in a hand, with a board's red LED glowing inside the case
Left: an early fit-up with one thumbstick in. Right: the underside, with a board's LED glowing inside.

Wiring

Transmitter (ESP32-C3 SuperMini)

ModulePinESP32-C3Job
Left joystickVRXGPIO 0Left X axis (ADC1_CH0)
VRYGPIO 1Left Y axis (ADC1_CH1)
SWGPIO 6Push button (INPUT_PULLUP)
Right joystickVRXGPIO 2Right X axis (ADC1_CH2)
VRYGPIO 3Right Y axis (ADC1_CH3)
SWGPIO 7Push button (INPUT_PULLUP)
PowerVCC3.3VShared 3.3 V rail for the joysticks
GNDGNDShared ground

Receiver (classic ESP32)

OutputESP32Job
Status LEDGPIO 2Onboard LED: link and failsafe indicator
PWM / motor outputsSet per vehicleMotor controllers (ESCs), servos or relays

The data packet

Each transmission carries both sticks and both buttons in one small structure, which the receiver unpacks with the same definition:

typedef struct struct_message {
    int leftX;
    int leftY;
    bool leftBtn;
    int rightX;
    int rightY;
    bool rightBtn;
} struct_message;