When pingpong detected a stall and switched direction, only _stalled
and _stallStartTime were reset, leaving _stallCandidateCount and
_motorStartTime unchanged. This caused motor inrush current after
direction change to immediately trigger another stall, creating an
infinite oscillation loop.
Now calls resetStallDetection() which properly resets all stall state
including triggering the STALL_STABILIZE_MS grace period to ignore
inrush current.
- Use exponential moving average (EMA) to track normal running current
- Detect stall when current spikes above average by STALL_DELTA_THRESHOLD (2.0A)
- Add stabilization period (500ms) after motor start to let EMA settle
- Stall confirmation requires spike to persist for STALL_CONFIRM_MS (100ms)
- EMA stops updating during stall to prevent threshold creep
- Removes dependency on absolute current threshold that varied with speed
- Add MIN_PWM_PERCENT (20%) to ensure motor starts reliably
- Add CURRENT_CALIBRATION factor (0.33) for accurate current readings
- Add stall-based return option for pingpong mode (returns on stall instead of time)
- Update stall detection: 7A threshold, 1000ms confirm time
- Add DISABLE_STALL_DETECT config option
- Keep last speed setting when motor stops (UI improvement)
- Update webserver UI with 'Return on stall only' checkbox
- Adjust stall current threshold to 4A and detection time to 2500ms
- Add comprehensive README with hardware specs, wiring diagrams
- Include current sensing circuit documentation and math
- Improve motor and webserver implementations
- Implement MotorController class with PWM speed control (0-100%)
- Add bidirectional control (forward/reverse) via LEDC PWM at 20kHz
- Include optional current sensing and stall detection
- Create responsive web UI with speed slider and direction buttons
- Configure WiFi with static IP (10.81.2.185)
- Use built-in WebServer library for ESP32 Arduino 3.x compatibility