Compiled by YzzSoft Studio (Langzhou Wanderer)
For developers who want to add PS5 controller Bluetooth support to their games
Based on global open-source community reverse engineering — not official Sony documentation
PS5 controller uses the same HID Report ID 0x01 for both USB and Bluetooth — but with completely different byte layouts. If you parse Bluetooth data using the USB layout, you'll get garbage for stick directions and button states.
| Format | Report ID | Size | Connection | Completeness |
|---|---|---|---|---|
| USB 0x01 | 0x01 | ~64 bytes | USB Wired | Complete |
| BT 0x01 | 0x01 | 78 bytes | Bluetooth (Simplified) | Sticks+Buttons+Triggers Only |
| BT 0x31 | 0x31 | 78 bytes | Bluetooth (Full) | All Sensors+Battery |
Key Discovery: BT 0x01 and USB 0x01 share the same Report ID but NOT the same layout!
| Field | USB 0x01 | BT 0x01 | BT 0x31 |
|---|---|---|---|
| Left Stick X | data[1] | data[1] | data[2] |
| Left Stick Y | data[2] | data[2] | data[3] |
| Right Stick X | data[3] | data[3] | data[4] |
| Right Stick Y | data[4] | data[4] | data[5] |
Range:0x00~0xFF, center ~0x80. Left=0x00, Right=0xFF(X-axis); Up=0x00, Down=0xFF(Y-axis).
| Field | USB 0x01 | BT 0x01 | BT 0x31 |
|---|---|---|---|
| L2 Analog | data[5] | data[8] | data[6] |
| R2 Analog | data[6] | data[9] | data[7] |
| Field | USB 0x01 | BT 0x01 | BT 0x31 |
|---|---|---|---|
| D-Pad + Face Buttons | data[8] | data[5] | data[9] |
| Shoulders + System | data[9] | data[6] | data[10] |
| PS / Touchpad / Mute | data[10] | data[7] | data[11] |
Byte 1 (D-Pad + Face Buttons):
bits 3-0: D-Pad hat switch (0=Up,1=Up-Right,2=Right,3=Down-Right,4=Down,5=Down-Left,6=Left,7=Up-Left,8~15=Neutral)
bit 4: Square (□)
bit 5: Cross (✕)
bit 6: Circle (○)
bit 7: Triangle (△)
Byte 2 (Shoulders + System Buttons):
bit 0: L1
bit 1: R1
bit 2: L2 Button (digital)
bit 3: R2 Button (digital)
bit 4: Create (Share)
bit 5: Options
bit 6: L3 (Left Stick Click)
bit 7: R3 (Right Stick Click)
Byte 3 (PS + Touch + Mute):
bit 0: PS Button
bit 1: TouchPad Click
bit 2: Mute (Microphone)
Bluetooth connection defaults to BT 0x01 simplified mode — no battery info, no sensor data, no multi-touch. Send a GET FEATURE REPORT to trigger the switch:
// Read calibration data (Feature Report 0x05) — triggers mode switch
BYTE calib[42] = {0}; // 41 bytes data + 1 byte Report ID
calib[0] = 0x05;
HidD_GetFeature(hDevice, calib, sizeof(calib));
// Controller automatically switches from BT 0x01 to BT 0x31
This method comes from Linux kernel hid-playstation.c and open-source community reverse engineering.
Battery data only available in BT 0x31 full report:
data[54] (0x31 format only):
bits 0-3: Battery level (0~10, 0=0%, 10=100%)
bit 4: Charging status (1=Charging, 0=Discharging)
BT 0x01 simplified report does NOT include battery data. USB 0x01 battery at data[53].
PS5 DualSense adaptive triggers are USB-only on PC. Sony restricts adaptive triggers and HD haptic feedback to USB in firmware. This is a product strategy decision, not a bandwidth limitation — Bluetooth 5.0 has more than enough bandwidth. Third-party tools (like DSX) partially restore this via virtual USB device workarounds, proving Bluetooth HID output channels can carry adaptive trigger data.
// —— Tri-offset variables ——
int stickOfs = 0, trigOfs = 0, btnOfs = 0;
if (data[0] == 0x31 && size >= 78) {
// BT 0x31 full mode: all fields offset +1
stickOfs = trigOfs = btnOfs = 1;
} else if (data[0] == 0x01) {
if (size >= 78) {
// BT 0x01 simplified: sticks same, triggers & buttons swapped
stickOfs = 0;
trigOfs = 3; // triggers at data[8~9]
btnOfs = -3; // buttons at data[5~7]
}
// else: USB 64-byte — all offsets 0, no processing needed
}
// —— Read data ——
leftStickX = data[1 + stickOfs];
leftStickY = data[2 + stickOfs];
rightStickX = data[3 + stickOfs];
rightStickY = data[4 + stickOfs];
leftTrigger = data[5 + trigOfs];
rightTrigger = data[6 + trigOfs];
uint8_t btn0 = data[8 + btnOfs]; // D-Pad + face buttons
uint8_t btn1 = data[9 + btnOfs]; // shoulders + system
uint8_t btn2 = data[10 + btnOfs]; // PS/touchpad/mute
Core information sourced from the following open-source projects and communities:
| Source | Contribution |
|---|---|
| Linux Kernel hid-playstation.c | Complete driver reference, by Roderick Colenbrander |
| nondebug/dualsense (GitHub) | HID report descriptors, BT 0x01 10-byte mapping |
| controllers.fandom.com | Data structure docs, calibration switching |
| PS5 Developer Wiki | HID command set, touchpad protocol |
| dsremap | Reverse engineering docs, 0x01→0x31 switch |
| dsfm / brc-xyz (GitHub) | GET FEATURE 0x05 method confirmation |
| J_0k3r (CSDN) | PS5 Bluetooth traffic packet capture analysis |
YzzPadView is a PS5 controller desktop button indicator developed by Langzhou Wanderer (YzzSoft Studio). Completely free, no registration, no activation. Supports Windows 10/11, DualSense standard and Edge Elite.
World premiere: June 27, 2026. Full tri-offset system and BT 0x01→0x31 calibration switching implemented as described in this document.
If this document helped your game development, please mention Langzhou Wanderer and YzzSoft Studio in your credits. This is the result of years of work by our global open-source community.