ESP32-C3 Zero + VL53L1X ToF sensor + 3x LEDs with WiFi AP web calibration UI, rolling average smoothing, auto-sleep, and NVS persistence. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Car parking distance sensor using an ESP32-C3 Zero, VL53L1X Time-of-Flight laser sensor, and 3x 10mm LEDs (green/yellow/red). Wall-mounted in a garage, it measures distance to an approaching car and displays proximity via LED states. Includes a WiFi AP with web UI for remote calibration.
Build & Flash Commands
pio run— compile firmwarepio run -t upload— flash to ESP32-C3 (port:/dev/ttyACM0)pio device monitor— serial monitor (115200 baud)pio run -t upload && pio device monitor— flash and monitor in one shot
Note: close the serial monitor before flashing, or the port will be busy.
Architecture
Single-file firmware (src/main.cpp) using Arduino framework on PlatformIO. Three subsystems:
- Sensor — VL53L1X on I2C (GPIO 5 SDA, GPIO 6 SCL), continuous mode at 50ms intervals
- LEDs — 3x 10mm through-hole on GPIO 2 (green), GPIO 3 (yellow), GPIO 4 (red), active HIGH with 220Ω resistors
- WiFi/Web — ESP32 runs as AP (SSID:
ParkingSensor, pass:carpark1). Web server on192.168.4.1provides:- Live distance readout (polls
/api/statusat 300ms) - One-tap calibration (
POST /api/calibrate) — sets current distance as the stop point - Manual stop distance input (
POST /api/set?stop=N)
- Live distance readout (polls
LED Behaviour
LEDs off when distance > stop + 1000mm (ZONE_GREEN + 200mm headroom). Within range, zones are calculated as offsets above the calibrated stop distance:
| Zone | Distance | LEDs |
|---|---|---|
| Far | > stop + 800mm | Green |
| Approaching | stop + 400 – stop + 800mm | Green + Yellow |
| Close | stop + 100 – stop + 400mm | Yellow + Red |
| Very close | stop – stop + 100mm | Red solid |
| STOP | < stop | Red flashing |
Signal Processing
- Rolling average: 5-sample moving average of valid readings smooths jitter
- Bad reading filter: readings with
range_status != 0are discarded (status 7 = wrap-around is common at range edges) - Zero filter: distance 0 (no target) is discarded
- Auto-sleep: LEDs turn off after 30s of stable distance (30mm tolerance), wake on movement
Calibration & Persistence
The stop distance is stored in NVS (ESP32 flash) via the Preferences library. It survives power cycles. Zone offsets are #define constants (ZONE_RED 100, ZONE_YELLOW 400, ZONE_GREEN 800) at the top of src/main.cpp. Stable tolerance (STABLE_TOLERANCE 30mm) and sleep timeout (SLEEP_TIMEOUT 30000ms) are also tuneable.
Hardware
- Board: ESP32-C3 Zero (board target:
esp32-c3-devkitm-1) - Sensor: VL53L1X ToF (I2C, Pololu library
pololu/VL53L1X@^1.3.1) - LEDs: 10mm through-hole (green, yellow, red) with 220Ω resistors
- Power: USB-C
- Build flags:
-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1(required for serial over USB on C3 Zero)