devdesk 568339367e Update EMA during stabilization period to track startup current
Instead of seeding EMA with first reading after stabilization, now
continuously update EMA during the 500ms stabilization window. This
ensures EMA represents normal running current rather than potentially
high stall current if motor hits end stop immediately.
2026-02-05 18:29:33 +02:00

BTS7960 Motor Controller

ESP32-based DC motor controller with web interface, using BTS7960 dual H-bridge driver with current sensing and stall protection.

Hardware

Components

Component Model/Specification
Microcontroller ESP32 LOLIN32 Rev1
Motor Driver BTS7960 Dual H-Bridge Module
Power Supply 12V DC
Sense Resistors 2× 1kΩ (for current sensing)

BTS7960 Module Reference

Wiring

Motor Control Pins

BTS7960 Pin ESP32 GPIO Function
RPWM GPIO25 Forward PWM
LPWM GPIO26 Reverse PWM
R_EN GPIO27 Right Enable
L_EN GPIO14 Left Enable
VCC 3.3V Logic Power
GND GND Ground

Current Sensing Circuit

The BTS7960 has IS (Current Sense) pins that output current proportional to motor load. A resistor converts this to voltage for ESP32 ADC.

BTS7960 Module                    ESP32
┌─────────────────┐              ┌──────┐
│                 │              │      │
│  R_IS (pin 7)  ─┼──────┬───────┤GPIO34│
│                 │      │       │      │
│                 │     [R1]     │      │
│                 │     1kΩ      │      │
│                 │      │       │      │
│  GND           ─┼──────┴───────┤GND   │
│                 │              │      │
│  L_IS (pin 8)  ─┼──────┬───────┤GPIO35│
│                 │      │       │      │
│                 │     [R2]     │      │
│                 │     1kΩ      │      │
│                 │      │       │      │
│  GND           ─┼──────┴───────┤GND   │
└─────────────────┘              └──────┘
Connection Details
R_IS → GPIO34 Through 1kΩ resistor to GND
L_IS → GPIO35 Through 1kΩ resistor to GND

Note: GPIO34 and GPIO35 are input-only pins on ESP32, ideal for ADC readings.

Current Sensing Math

Parameter Value Formula
Sense Ratio 8500:1 I_sense = I_motor / 8500
Sense Resistor 1kΩ V_sense = I_sense × R
At 4A motor current 0.47V (4 / 8500) × 1000
Max readable current 28A (3.3V × 8500) / 1000

Configuration

Key settings in include/config.h:

Setting Default Description
STALL_CURRENT_THRESHOLD 4.0A Current triggering stall detection
STALL_DETECT_TIME_MS 500ms Duration before stall confirmed
PWM_FREQ 20kHz PWM frequency (reduces motor noise)
CURRENT_SENSING_ENABLED true Enable/disable in src/motor.cpp

Network

Setting Value
WiFi SSID tami
Static IP 10.81.2.185
HTTP Port 80

Build & Upload

pio run              # Build
pio run -t upload    # Build and upload
pio device monitor   # Serial monitor (115200 baud)

Stall Protection

When motor current exceeds 4.0A for 500ms continuously:

  1. Stall is detected
  2. Motor stops immediately
  3. Serial log: STALL PROTECTION: Stopping motor (current: X.XXA)

To resume operation, send a new speed/direction command via the web interface.

Description
a walker
Readme 331 KiB
Languages
C++ 90.2%
C 9.8%