RC Cars & BoatsTechnician

RC Car Speedometer and Battery Telemetry on Your Phone

A magnet, a Hall sensor and an ESP32 measure real speed and pack voltage and stream them to a web page.

LevelTechnician
Time2 h
Est. cost~$65
Steps5

How fast is your car really? A Hall-effect sensor counts wheel turns from a tiny magnet, and a voltage divider lets the ESP32 read the battery safely. The ESP32 hosts its own Wi-Fi hotspot, so it works in a parking lot.

⚠ SAFETY
Double-check the divider with a multimeter before connecting it to the ESP32 — the battery voltage would destroy the pin. LiPo batteries can catch fire if punctured, overcharged or shorted. Charge in a LiPo bag, never unattended, and always remove propellers while working on the bench.

Video tutorial

▶ Maker Creation LabWatch on YouTube ↗

Video by Maker Creation Lab, embedded from YouTube. The written steps below are our own and match the parts list.

Mission steps

  1. Mount the magnet and sensor

    Glue a small neodymium magnet inside a wheel hub and mount the Hall sensor 2–4 mm away on the suspension arm.

  2. Build the voltage divider

    For a 2S pack (8.4 V max) use 30 kΩ on top and 10 kΩ to ground: the ESP32 sees at most 2.1 V. Add a 100 nF capacitor across the bottom resistor.

  3. Wire the ESP32

    Hall output to GPIO4 (with pull-up), divider midpoint to an ADC pin (GPIO1–GPIO10 on the S3), power from the car's 5 V BEC.

  4. Flash the code

    Count pulses in an interrupt, convert to km/h with your wheel circumference, and serve JSON plus a tiny dashboard.

  5. Drive and read

    Connect your phone to the car's hotspot and open 192.168.4.1. Calibrate voltage against a multimeter.

Code

# MicroPython on ESP32-S3 (core logic)
from machine import Pin, ADC
import time, network

WHEEL_M = 0.33            # wheel circumference in metres
DIVIDER = (30 + 10) / 10  # 30k over 10k
pulses = 0
def tick(p):
    global pulses; pulses += 1
Pin(4, Pin.IN, Pin.PULL_UP).irq(trigger=Pin.IRQ_FALLING, handler=tick)
bat = ADC(Pin(1)); bat.atten(ADC.ATTN_11DB)

ap = network.WLAN(network.AP_IF); ap.active(True); ap.config(essid='RC-TELEMETRY')

while True:
    pulses = 0; time.sleep(1)
    kmh = pulses * WHEEL_M * 3.6
    volts = bat.read_uv() / 1e6 * DIVIDER
    print('%.1f km/h  %.2f V' % (kmh, volts))

Tip: test every script on the bench before installing it in a moving machine.

Questions

3S battery?

Max 12.6 V: use 47 kΩ over 10 kΩ (about 2.2 V at full charge) and update DIVIDER in the code.