Repository navigation
3. Communication Protocol
The Thrustmaster T248 wheel and wheelbase communicate over a UART interface.
Configuration:
- Baud rate: 115200
- Format: 8E1 (8 data bits, even parity, 1 stop bit)
- Master: Wheelbase
- Slave: Wheel
The wheelbase controls all timing and initiates cyclic exchanges.
Compared to other Thrustmaster wheels:
- Older models (T300, T150, TMX, T500) → SPI
- Newer models (T818) → CAN-BUS
The T248/T124 uses UART with even parity at 115200 baud.
Wheel connector pins (observed):
| Pin | Function | Notes |
|---|---|---|
| TX (PA2) | Data to wheelbase | Testpad 7, via 27.5Ω series resistor |
| RX (PA3) | Data from wheelbase | Testpad 6 |
| RESET (TP9) | Reset wheel MCU | Used during startup |
| PA14 (TP8) | Mode button / GPIO | Likely involved in boot or firmware update |
Communication is divided into three main phases:
- Startup Sequence
- Normal Operation
- Shutdown Sequence
Note: If the wheel is powered on without the wheelbase, communication differs entirely. Pulseview captures are provided for analysis.
-
Wheelbase pulls RESET line high for ~400 ms → resets wheel MCU
-
~100 ms later, wheelbase starts sending keep-alive frames
- Wheel does not respond yet
-
After another ~100 ms, wheel finishes booting and sends a “hello” frame twice:
F4 02 00 02 AA E1 FF DE
-
Wheelbase responds to each frame:
F0 00 00 00
-
Normal operation begins:
- 4 Hz button messages
- Keep-alive frames
- Screen data (if supported by game)


Wheelbase cyclically transmits four 4-byte frames:
D0 00 00 00
D1 00 FF 01
D2 00 00 00
D3 00 00 00
- Frames rotate every 250 ms (e.g., D0 → D1 → D2 → D3 → next cycle D3 → D0 → …)
- Wheel must respond to each frame:
F0 00 00 00


- Sent every 250 ms (B0 and B1 frame) or immediately after a button press (only B0 frame)
- Alternating frames:
-
B0 xx xx xx→ button data -
B1 00 00 00→ placeholder
Only the B0 frame is evaluated by the wheelbase. The button states are encoded in the B0 frame as follows:
Byte 0:
- static 0xB0
Byte 1:
- DPAD Right
- Display
- Mode
- Encoder Left Up
- Encoder Left Down
- Encoder Right Up
- Encoder Right Down
Byte 2:
- BTN 9
- BTN 10
- BTN 22
- BTN 23
- BTN 13
- DPAD Up
- DPAD Down
- DPAD Left
Byte 3:
- BTN 1–8

In addition the wheelbase sends a general-purpose data frame used for multiple functions.
Frame length: 18 bytes
Example:
F3 0E 00 00 05 45 20 31 20 2B A0 86 01 00 00 00 00 00
Observations:
- Byte 0–1: static
- Byte 5: message subtype
- 0x45 → Encoder-related data
- 0x20 → Default / idle state
- maybe additional types
This frame is sent:
- randomly in idle mode (non-encoder data)
- immediately after encoder interaction (encoder data)
- Byte 7: bits 0–2 encode the current encoder layer
- Byte 9: identifies the pressed encoder button (EX+, EX-, EXP)
-
Byte 10–11: encode the encoder action:
- no action / reset
- layer switch
- encoder button press

Display frames are transmitted by the wheelbase when a running game supports the T248 display.
Characteristics:
- Variable frame length
- Transmitted asynchronously (not tied to the 250 ms keep-alive cycle)
- Only active when telemetry data is available
- Byte 0: Frame identifier (0x2A or 0x42 observed)
- Byte 1: Frame counter (increments each transmission)
- Byte 2: Payload length
- Remaining bytes: Payload data
After each display frame, the wheel responds with a fixed 12-byte frame:
47 0C 2A 02 01 00 80 00 00 00 00 00
Observations:
- Byte 0 appears constant (0x47)
- Byte 1 likely encodes frame length (0x0C = 12 bytes)
- Exact functional meaning remains unclear
Display content remains visible for approximately ~2 seconds unless refreshed.
A short frame (observed on both UART and USB levels) appears to function as a display keep-alive / duration extender:
42 06 D0 63 06 00 E6 B8
(On USB level, this frame contains two additional leading header bytes.)
Repeated transmission extends the visible duration without modifying the displayed content.


- Triggered when wheelbase is disconnected from PC
- Wheelbase sends twice:
FD 01 00 00
- Wheel does not respond
- High frame redundancy
- Frequent acknowledgments
- Rotating frame order
- Unused headroom in certain frames
(Contribution by Lolig4 – February 2026)
Additional reverse engineering work was contributed by GitHub user Lolig4, focusing on the USB/HID communication between the PC and the T248 wheelbase.
While this project primarily analyzes the UART communication between wheelbase and wheel, this contribution provides insight into the upstream USB protocol layer.
- USB traffic captured using Wireshark + USBPcap
- Test environment: Forza Horizon 5 (display-supported title)
- Relevant packets filtered and exported as JSON
- Python script used to extract value-changing frames
- Frame injection performed using:
- Arduino Pro Mini (3.3 V)
- USB Host Shield
Key observation:
Display frames seen on the USB side are structurally nearly identical to the UART display frames documented in this project.
Difference:
- USB frames contain two additional leading header bytes
- Remaining structure matches UART payload format very closely
This suggests that the wheelbase performs little to no deep reinterpretation of display data and may forward display payloads with minimal transformation.
Three primary reports must be transmitted together to update display content:
rpt1rpt2rpt3
If only these three reports are sent once, the display content remains visible for approximately ~2 seconds.
An additional short report:
rpt10
Acts as a display duration extender, increasing visible time by ~2 seconds per transmission without modifying content.
The implementation is based on the function: SendTestChar(uint8_t ch)
Source file: SendTestChar.c
Contains:
- ASCII character (center display)
- RPM value
- Speed value
- Bargraph intensity value
Notable behavior:
- ASCII characters A–Z and 0–9 are working
- Bargraph behaves like a multi-bit intensity value (likely ~10-bit range)
- High values (~0x03FF) cause all 9 bars to blink
- Empirically derived values produce visually clean 0–9 bar levels
Contains:
- Driver position values (0-99, only last 2 digits of certain value)
- Lap position values
- Additional numeric display fields
Purpose not yet fully understood. However:
- It is required for proper display updates
- Omitting it prevents stable display behavior
So far, the following behaviors are possible:
- Display of ASCII characters
- Control of bottom bargraph intensity
- Speed value injection
- Driver/lap position field control
- Display persistence control via keep-alive frame
This shows, that the wheelbase sends all the data and the wheel decides, which to display
The following files are archived in this folder:
SendTestChar.cUSB_Forza5_Trace1.jsonUSB_Forza5_Trace2.jsonUSB_Forza5_Trace3.jsonhid_data_extractor.py
These contain raw USB captures and helper tooling for HID frame extraction.
For full context, discussion details, and additional technical remarks, see the complete conversation in this GitHub Issue.
This contribution is particularly valuable because:
- It confirms structural similarities between USB and UART display frames.
- It provides additional insight into how the wheelbase handles display updates.
- It supports future research into full display decoding and firmware behavior.
Special thanks to Lolig4 for sharing this research and capture data.