Force feedback controller firmware for the RP2040 (Raspberry Pi Pico) targeting brushed DC motors with quadrature encoders.
USB VID/PID: 1209:0FFC — composite CDC serial + HID FFB wheel. v0.3.0
| GPIO | Signal |
|---|---|
| 0 | Motor L forward PWM |
| 1 | Motor L reverse PWM |
| 2 | Motor R forward PWM |
| 3 | Motor R reverse PWM |
| 4 | Motor enable (active high) |
| 5 | Fan PWM (SSR) |
| 9 | Encoder A |
| 10 | Encoder B |
| 16 | WS2812 status LED |
| 26 | Throttle ADC (pedal 0) |
| 27 | Brake ADC (pedal 1) |
| 28 | Clutch ADC (pedal 2) |
| 29 | Temp sensor ADC (thermocouple/NTC) |
| BOOTSEL | Press to recenter wheel |
- USB HID Force Feedback — 11 effect types, 40 simultaneous effects, full PID descriptor
- FFB Engine — spring, damper, friction, inertia, constant, ramp, periodic (sine/square/triangle/saw), envelope
- Dual Motor PWM — H-bridge control, per-motor gain, power curve, ~30kHz silent PWM
- PIO Quadrature Encoder — hardware-level decoding via RP2040 PIO+DMA
- Endstops — soft limits at maxdeg/2, configurable strength
- 3× ADC Pedals — throttle/brake/clutch with calibration
- Thermal Protection — software estimate or real sensor (thermocouple/NTC), fan curve, auto power limiting
- Flash Config — dual-block CRC storage, all settings persist across reboot
- WS2812 LED — temperature-based color (green/orange/red)
- Serial Protocol — OK/ERR/JSON commands, 100ms telemetry stream
- Companion App — native GUI for tuning, profiles, live telemetry
$env:PICO_SDK_PATH = "$env:USERPROFILE\.pico-sdk\sdk\2.3.0"
cmake -G "Ninja" -B build -S .
cmake --build buildFlash build/PicoFFB.uf2 via bootloader (hold BOOTSEL, plug USB).
- Flash firmware
- Open serial terminal at 115200 baud
- Type
centerto calibrate wheel center - Type
saveto persist
For full configuration, use the companion app:
pip install customtkinter pyserial
python companion/companion_app.py
ffb on/off | motor <v> | center | max <v> | curve <v> | gainl/r <v>
ppr <v> | maxdeg <v> | estopstr <v>
sspring/sdamper/sfriction/sinertia <v>
calmin <0-2> | calmax <0-2> | calib <0-2> | pedal_enabled <0/1>
thermalsrc <0-2> | tc_type <0-2> | tc_slope/tc_offset <v>
ntc_r25/ntc_beta/ntc_rfixed <v> | ntc_invert <0/1>
fanmin/fanstart/fanmax <v> | thstart/thramp <v> | temp
motor_enabled <0/1> | save | debug on/off | tel on/off | status | ver | dump
See ./PROTOCOL.md for full protocol documentation. Telemetry streams at 100ms via tel on. All command responses prefixed OK/ERR.
FFBHub/— prior RP2040 FFB firmware (descriptor donor)OpenFFBoard/— upstream STM32 firmware (effect math reference)