This project turns an ESP8266 into a compact VESC handlebar/remote controller with an onboard display. It reads an analog throttle and a digital brake input, commands a Flipsky/VESC over UART, and drives a repurposed LENZOD-style 6-position display (TM1637-like signaling) to show speed, battery level, and brake status.
- Reads analog throttle on A0 and maps it to a 0..1 command with deadband and smoothing.
- Reads digital brake with debounce + hysteresis and applies controlled regen braking.
- Talks to a VESC over UART using
VescUart:- Drive mode: Current control (default)
- Optional: Speed/RPM control (code supports it)
- Calculates speed from VESC eRPM and displays it.
- Estimates battery percentage from pack voltage and shows bar graph + low-batt indicator.
- Lights UI indicators for:
- MPH/KMH selection (compile-time)
- Brake active indicator
- ESP8266 (e.g., NodeMCU / Wemos D1 mini)
- Flipsky/VESC with UART enabled
- Analog throttle (pot/hall with analog output to A0)
- Brake switch (active LOW recommended)
- LENZOD display module or compatible 6-position segment unit
- Driven using TM1637-style two-wire clock/data (bit-banged)
| Function | ESP8266 Pin |
|---|---|
| VESC RX (ESP receives) | D6 |
| VESC TX (ESP sends) | D5 |
| Brake input (active LOW) | D7 |
| Throttle analog | A0 |
| Mode toggle (reserved) | D0 |
| Display CLK | D1 |
| Display DIO | D2 |
If your board labels differ, adjust the PIN_* constants in main.cpp.
- Raw ADC is clamped to:
THR_MIN = 300THR_MAX = 842
- A small deadband helps eliminate noise:
THR_DEADBAND = 20
- Output is smoothed with an EMA:
EMA_ALPHA = 0.25
- A mild expo curve is applied:
THR_EXP = 0.1
Default is Current control:
MAX_DRIVE_CURRENT = 10.0A
Speed/RPM mode is supported in code:
MAX_RPM = 800MOTOR_POLE_PAIRS = 15MAX_ERPM = pole_pairs * max_rpm
You can switch the default by changing:
static ControlMode g_mode = ControlMode::Current;- Brake input is debounced using an integrator counter with hysteresis.
- When active, braking current ramps smoothly:
MAX_BRAKE_CURRENT = 2.5A
- A minimum “brake feel” threshold is applied so regen doesn’t feel too weak at light throttle:
BRAKE_MIN_LEVEL = 0.60
- Brake smoothing:
BRAKE_EMA = 0.30
The display code is a low-level TM1637-style implementation tailored to this 6-position layout.
- Speed: two-digit display (0–99)
- Battery bars: 0–5 bars
- Low battery warning: dedicated indicator when <20%
- Brake active icon: indicator set when brake is engaged
- Units: MPH/KMH indicator chosen at compile time
Set at compile time:
static const bool USE_MPH = true;Battery % is a simple linear estimate from voltage:
static const float VBAT_EMPTY = 32.0f;
static const float VBAT_FULL = 40.0f;Adjust these for your pack chemistry and series count.
- Install PlatformIO, build and compile
- Ensure common ground between ESP8266 and VESC UART.
- VESC UART is typically 3.3V logic tolerant, but verify your model.
- If your throttle outputs >1.0V, you may need a divider depending on your ESP8266 board’s A0 range.
This project directly commands motor current and is intended for experienced builders.
By using this code and/or following any wiring guidance in this repository, you acknowledge and agree that:
- You are doing so at your own risk.
- The author(s) are not responsible for any damages, injuries, or losses resulting from the use or misuse of this project, including but not limited to damage to your scooter, VESC, battery pack, wiring, or other components.
Electric scooter battery packs can be dangerous. High-current lithium battery systems can cause:
- fire
- severe burns
- electric shock
- damage from short circuits or improper wiring
This build should only be attempted by someone who is comfortable working with electrical systems and understands basic battery safety practices. If you are not confident in your ability to safely modify a high-current vehicle electrical system, do not attempt this project.
Before live testing:
- Verify all wiring with the battery disconnected.
- Use conservative current limits.
- Test with the wheel off the ground.