Skip to content

Repository files navigation

LogiWheelHost

Build License: MIT Platform: ESP32-S3 Arduino library Release

A Logitech racing wheel connected to an ESP32-S3 development board

Plug a Logitech racing wheel into an ESP32‑S3 and read it. Clean, normalized steering, pedals, buttons and shifter — with the tricky Logitech native‑mode switch handled for you.

Read a Logitech Driving Force racing wheel (G29, G923, G920, G27, G25, DFGT, Driving Force Pro) on an ESP32‑S3 over USB host, and get clean, normalized inputs: steering -1..+1, pedals 0..1, buttons, D‑pad, and optionally the H‑shifter gear.

MIT licensed. Header‑only. Built on the excellent EspUsbHost library.

Features

  • 🎛️ Normalized inputssteer −1..+1, pedals 0..1, no raw‑byte wrangling
  • 🔌 Native‑mode switch handled — including the painful G923 PlayStation→PC switch
  • 🕹️ Whole Driving Force family — G29 / G923 / G920 / G27 / G25 / DFGT / DFP
  • 💡 G923 RPM LED bar control in one call
  • 🪶 Header‑only, ~1 dependency (EspUsbHost), MIT

How it works: wheel to ESP32-S3 to clean values to your code


Why this exists — the native‑mode switch

Logitech wheels don't just stream their axes when you plug them in. They boot in a restricted mode that only reports neutral or combined‑axis data until the host sends one HID output report to unlock separate pedals, full 16‑bit steering, all the buttons and the shifter. The G923 is worse: in its default PlayStation mode it streams only neutral reports (it's waiting for a PlayStation authentication a generic host can't provide) until you switch it to PC ("Classic") mode.

Figuring those commands out is the hard part. This library ships them per‑wheel, so a G29 or G923 just works — plug it into an ESP32‑S3 and read steer / throttle / brake.

Supported wheels

Anything in the Logitech Driving Force family (VID 0x046D): G29, G920, G923 (PS/Xbox/PC), G25, G27, Driving Force Pro, Driving Force GT. Others in the family will likely work — turn on the debug dump and check.

Hardware

  • An ESP32‑S3 (its native USB can act as a host; a plain ESP32 or C3 cannot).
  • The wheel's USB D+/D‑ wired to the S3's native‑USB D+/D‑.
  • 5V injected onto the wheel's VBUS — the S3 can't power a wheel.
  • A common ground between the S3 and the wheel's 5V supply.

Wiring: Logitech wheel USB to ESP32-S3 with 5V VBUS injection and common ground

See WIRING.md for the full details.

Install

  1. Install the dependency (Arduino IDE Library Manager, or CLI):
    arduino-cli lib install "EspUsbHost"        # tested with 2.7.2
    
  2. Install this library: Sketch → Include Library → Add .ZIP Library…, or drop the folder into your Arduino libraries/, or:
    arduino-cli lib install --git-url https://github.com/botsofcog/LogiWheelHost
    
  3. In the IDE, select an ESP32‑S3 board and leave USB Mode at the default OTG mode so the native USB can host.

Quick start

#include <LogiWheelHost.h>

LogiWheelHost wheel;

void setup() {
  Serial.begin(115200);
  wheel.begin();          // or wheel.begin(onInput) for a callback
}

void loop() {
  wheel.tick();           // services the G923 mode switch
  if (wheel.connected()) {
    LogiWheelInput in = wheel.latest();
    // in.steer   -1.0 .. +1.0
    // in.throttle / in.brake / in.clutch   0.0 .. 1.0
    myServo.write(90 + (int)(in.steer * 90));
    myMotor.setDuty(in.throttle - in.brake);
  }
}

See examples/SerialMonitor for a complete sketch that prints every input and mirrors the throttle onto the G923 RPM LED bar.

API

LogiWheelInput

field type meaning
steer float -1.0 full left … +1.0 full right (deadzone + invert applied)
throttle brake clutch float 0.0 released … 1.0 floored
steerRaw uint16_t raw 16‑bit steering (centre ~32768)
throttleRaw brakeRaw clutchRaw uint8_t raw pedals (idle 255)
buttons uint32_t raw button bitfield (report[0..3])
hat uint8_t D‑pad: 0=N 2=E 4=S 6=W 8=centre
gear int8_t H‑shifter gear (if LOGIWHEEL_SHIFTER=1), else UNKNOWN
stampMs uint32_t millis() when this reading arrived

LogiWheelHost

method does
begin(cb = nullptr) start the USB host; optional callback void(const LogiWheelInput&) fired on each reading
tick() call every loop() — services the deferred G923 PS→PC switch
connected() is a recognised wheel plugged in?
latest() thread‑safe snapshot of the last reading
setRpmLeds(0..6) light N LEDs on the G923 RPM bar (ignored on wheels without it)
pressed(in, LOGIWHEEL_BTN_*) static helper: is that button set in in.buttons?

The optional callback runs in EspUsbHost's background task — keep it short, or just poll latest() from loop().

Named button masks (LOGIWHEEL_BTN_X, _TRIANGLE, _L_PADDLE, _BACK, …) are provided as a starting point confirmed on a G923 in PC mode. Verify them on your wheel with the debug dump.

Configuration

Every knob is a -D build flag (override in your build, no library edits). Common ones:

flag default what
LOGIWHEEL_STEER_USABLE 32767 raw counts each side of centre that map to full lock (±1.0). Lower = a smaller turn reaches full lock.
LOGIWHEEL_STEER_DEADZONE 300 raw counts around centre ignored
LOGIWHEEL_STEER_INVERT 0 1 if left/right come out reversed
LOGIWHEEL_PEDAL_DEADZONE 10 slack at the top of pedal travel
LOGIWHEEL_SHIFTER 0 1 to decode a Driving Force Shifter's gear
LOGIWHEEL_DEBUG 0 1 prints the raw HID report (calibration)
LOGIWHEEL_OFF_STEER_LO/HI, _THROTTLE, _BRAKE, _CLUTCH 4/5/6/7/8 report byte offsets — fix these if an axis reads wrong

Calibration (the one hardware step)

If an axis reads wrong on your wheel, build once with -DLOGIWHEEL_DEBUG=1, open the Serial Monitor, and press each control one at a time. The dump prints only when the report changes, so you'll see exactly which byte moves — then set the matching LOGIWHEEL_OFF_* offset. The mode‑switch commands and PID list are already handled for you.

Credits

  • USB host layer: EspUsbHost by TANAKA Masayuki.
  • The Logitech native‑mode command family is documented by the Linux new‑lg4ff driver and the GIMX project; the G923 PS→PC switch mirrors the usb_modeswitch entry for 046d:c267.
  • Extracted and generalized from an ESP32 arcade steering‑wheel controller.

License

MIT — do whatever you like; attribution appreciated, no warranty.

About

Read a Logitech Driving Force racing wheel (G29/G923/G27/G920/G25/DFGT) on an ESP32-S3 over USB host — clean normalized steering, pedals, buttons, shifter. Handles the Logitech native-mode switch. MIT.

Topics

Resources

Stars

31 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages