aed3 / PS4-esp32

Use a ps4 controller with an esp32
328 stars 103 forks source link

No longer wants to connect. #18

Closed DaveVdE closed 3 years ago

DaveVdE commented 3 years ago

I've tried everything.

I had it working fine. Pairing was not a big deal, I used a Raspberry Pi to pair it with bluetoothctl, then powered it down and used the Pi's BT mac address in my sketch.

That worked better than I thought. I had it running on a Wemos D1 R32 with a CNC shield for my ongoing motorized camera slider project, I had it working on M5StickC's to drive a RoverC using the PS4 controller.

Then, yesterday evening, after assembling some parts for my slider, I wanted to test it with my board and stepper, but it didn't want to connect. It would flash briefly, but then power off immediately. This morning it still wanted to connect to a StickC that I programmed to show the battery level (which was at 8, but stopped charging at 10), so that still worked. Then this afternoon I wanted to diagnose the problem only to find out that it didn't want to connect to any of my boards anymore.

I powered up the Bluetooth of the RPi again and sure, it connects there. I tried changing the MAC address using SixaxisPairTool, I paired it fine with my phone (then I removed that pairing, of course). Also, if I don't have any of my boards powered up and acting like a BT host, the controller would keep blinking that it couldn't find a device to connect to. As soon as I power up a board, the connection is made. And then it's dropped.

There's no onConnect call happening, so I'm thinking it's somewhere in the BT stack? I don't know. I didn't update the library or the Arduino framework, so I'm at a loss at what might be causing this.

If there's anyone who has any idea of what I might try or how I could find more detailed information on the events going on, let me know. I have some tools available (including an ESP Prog) but I'd have to know where to start.

DaveVdE commented 3 years ago

OK.

TL;DR: I had to erase the flash using esptool.py erase_flash and reflash it to get it to connect again.

Some of my boards had no issue. I still have no clue what happened.

DaveVdE commented 3 years ago

I've been doing some reading, just to get a clearer understanding of the Bluetooth stack on the ESP32 but also to understand better what I've experienced with the failures to connect and how the erasing of the flash (and not merely re-uploading of the sketch) solved the issue.

It seems that the usual form of pairing can't be initiated from ESP32 side for Bluetooth Classic since the APIs are not provided. I was also able to read that the "link key is stored by the Host automatically". It may be that this key is stored in the flash memory (probably using the EEPROM emulation layer that is provided).

dogtopus commented 2 years ago

Ah that's probably why cloning the BDADDR works. I was wondering why it will ever work because the device will refuse to talk to the host if the link key differs. However I guess having link key omitted in the host side probably triggered some half pairing state that caused the link key to be renegotiated or just simply resent from the DS4.

BTW another way to pair a DS4 without worrying about the pairing process too much is to use the USB pairing protocol. Use the pair info report (GET REPORT 0x12) to get the BDADDR of the controller and use the pair report (SET REPORT 0x13) to send a randomly generated link key and the ESP32's BDADDR to the DS4. After this you can upload the controller's BDADDR along with the link key to the ESP32 via serial port, etc. and the pair is done. This will require a companion app but is less hacky than overriding ESP32's BDADDR and less likely to upset other devices that are sharing the BDADDR with the ESP32.

Similar protocol for DS5 also exists, and switch pro controller also does similar thing IIRC.