ricardoquesada / bluepad32

Bluetooth gamepad, mouse and keyboard support for ESP32 and PicoW
https://bluepad32.readthedocs.io/
Other
503 stars 53 forks source link

[Bug]: Xbox controllers using FW 5.x don't support rumble #69

Closed ricardoquesada closed 3 months ago

ricardoquesada commented 4 months ago

What happened?

Rumble works in Xbox controllers when they are using firmware 3.x and 4.x But not when using FW 5.x.

This is because v5.x is using BLE, and the the new way to rumble was not implemented

Bluepad32 Version

latest from develop branch

Bluepad32 version custom

Example: Using Git develop branch commit hash #xxxxxxx

Bluepad32 Platform

Other

Platform version

All

Controller

Xbox Wireless controller

ESP32 chip

ESP32

ESP32 board

ESP32-S3-WROOM1 DevKit from Lolin. This is the store URL: https://example.com

OS

None

Relevant log output

No response

Relevant sketch

No response

wiredopposite commented 3 months ago

Hey I hope this helps, I'll work on it a little more today and see if I can get somewhere with these

SERVICE_UUID_VENDOR         = "00000001-5f60-4c4f-9c83-a7953298d40d"
SERVICE_UUID_VENDOR_CHAR_1  = "00000002-5f60-4c4f-9c83-a7953298d40d"
SERVICE_UUID_VENDOR_CHAR_2  = "00000003-5f60-4c4f-9c83-a7953298d40d"
SERVICE_UUID_VENDOR_CHAR_3  = "00000004-5f60-4c4f-9c83-a7953298d40d"

SERVICE_UUID_GENERIC_ACCESS_PROFILE = "00001800-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_GENERIC_ACCESS_PROFILE_CHAR_1 = "00002a00-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_GENERIC_ACCESS_PROFILE_CHAR_2 = "00002a01-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_GENERIC_ACCESS_PROFILE_CHAR_3 = "00002a04-0000-1000-8000-00805f9b34fb"

SERVICE_UUID_GENERIC_ATTRIBUTE_PROFILE  = "00001801-0000-1000-8000-00805f9b34fb"

SERVICE_UUID_DEVICE_INFORMATION         = "0000180a-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_DEVICE_INFORMATION_CHAR_1  = "00002a29-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_DEVICE_INFORMATION_CHAR_2  = "00002a50-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_DEVICE_INFORMATION_CHAR_3  = "00002a26-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_DEVICE_INFORMATION_CHAR_4  = "00002a25-0000-1000-8000-00805f9b34fb"

SERVICE_UUID_BATTERY        = "0000180f-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_BATTERY_CHAR_1 = "00002a19-0000-1000-8000-00805f9b34fb"

SERVICE_UUID_HID        = "00001812-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_HID_CHAR_1 = "00002a4a-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_HID_CHAR_2 = "00002a4c-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_HID_CHAR_3 = "00002a4b-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_HID_CHAR_4 = "00002a4d-0000-1000-8000-00805f9b34fb"
SERVICE_UUID_HID_CHAR_5 = "00002a4d-0000-1000-8000-00805f9b34fb"
microbmen commented 3 months ago

wondering if this helps anyone with anything... https://github.com/quantus/xbox-one-controller-protocol#0x09-activate-rumble

ricardoquesada commented 3 months ago

Thanks @wiredopposite , @microbmen

Apparently it is easier that I thought. The "rumble report" seems to be the same. And the service that I need to use is the one that I'm already connected.

So in theory I just need to call hids_client_send_write_report() instead of uni_hid_device_send_intr_report() (???)

ricardoquesada commented 3 months ago

seems to be work, closing it as fixed.

Requires this patch in BTstack though: https://github.com/bluekitchen/btstack/pull/574

wiredopposite commented 3 months ago

Thanks, I'm testing it out and sending rumble with Steam works (I think it sends a 100% value), but when actually playing a game that sends varying rumble values it seems to disconnect the controller immediately and the gamepad state reported by Bluepad32 gets stuck on the last state reported by the controller. It works fine up until the rumble data is sent and it doesn't happen with non-Xbox controllers.

I'm not sure if I did something wrong including the new version of BTStack and Bluepad32 in my ESP32 PlatformIO project, I replaced BTStack with PR 574 and Bluepad32 with commit 1bd46a7, is there something else I'd need to do?

ricardoquesada commented 3 months ago

weird... which board are you using ? Also I'm a bit confused. How Steam and Bluepad32 are related ?

wiredopposite commented 3 months ago

weird... which board are you using ? Also I'm a bit confused. How Steam and Bluepad32 are related ?

I'm using a normal ESP32 dev board, connected via i2c to an RP2040 emulating an XInput controller (gets right/left uint8 motor values from host), those are sent to the ESP32 and setRumble is set based on the higher of those values.

void process_rumble_data(ControllerPtr gamepad, i2c_gamepad_in_data& rumble_data)
{
    uint8_t rumble_strength = max(rumble_data.left_rumble, rumble_data.right_rumble);

    if (rumble_strength > 0)
    {
        gamepad->setRumble(rumble_strength, 0x10); // disconnects Xbox controller if called too often
    }
}

I thought maybe I was updating rumble too often so I tried only polling rumble and calling setRumble once every 100ms, but that results in Xbox controller rumble working on the first setRumble call, but not any subsequent calls, while it still works normally on my other DS4/Dualsense controllers. That way the Xbox controller does not disconnect, it is weird.

Edit: I wrote a simple test to send rumble to the controller every second, it sends the first one, then prints "Xbox: Failed to send rumble report, error=0xc" every other time, maybe you can tell me if this is actually a bug or if my project is just setup incorrectly: https://github.com/wiredopposite/bluepad32_rumbletest

ricardoquesada commented 3 months ago

@wiredopposite ah... yep. how did you patch BTstack... you need my patch. Probably you patched it but forgot to "install" it ?

wiredopposite commented 3 months ago

@wiredopposite ah... yep. how did you patch BTstack... you need my patch. Probably you patched it but forgot to "install" it ?

Yes you're right, I'm not totally sure what exactly was wrong but after completely restarting fresh it's now working as expected, thanks