B4R Question ESP32 and BlueTooth

KiloBravo

Active Member
Licensed User
I am trying to get my head wrapped around Blue-Tooth. Lots of information to digest.
Basically I am trying to get an ESP32 to talk to a wireless BT controller. I want to use the controller (Con) to move a mobile platform. So Con >BT> ESP32 >WIFI> ESP8266 >Wired> Motors. I tried a few different wired joysticks and didn't like them. everything works fine except Con >> BT >> ESP32 piece.
The controller is a generic one that says it supports Nintendo Switch or some Android Phone games. The box lists BT 2.0. but it probably uses BLE as well ?
This is the Reverse Engineering of the Switch Controller Protocol ( https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering )
I did try Erel's example for rESP32SimpleBLE and it works fine. So my question is what BT stack should I be using with B4R and the ESP32 ?
EspressIf
https://github.com/espressif/arduino-esp32/tree/master/libraries/BLE or https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial
Can I use the Arduino BLE if I wrap it or use inline C ? I am guessing this does not Support the ESP32 since that board is not listed ???
What about BlueKitchen ? Someone got pretty far using this BT stack and lib to talk to a Nintendo Pro Controller but they were using a RaspberryPi.
Anybody do anything similar or have some examples you can point me to, especially with pairing an unknown device.
My confusion there is I can "see" the Advertised Name, but not the MAC or BD_AADR from the device before I can pair with it ???
Thanks !
 

rayzrocket

Member
Licensed User
Longtime User
I'm probably of no help, but I've done similar things.
Are you trying to get your ESP32 to communicate to your 'con' via BTserial while the ESP32 communicates to ESP8266 via WiFi?
If so, see https://www.esp32.com/viewtopic.php?t=6707
I have used Espressif compiler using just a regular text editor to write code .
Espressif Get Started
The methods to read MAC..etc. of advertised devices maybe buried in Espressif's libs and may not be avail in the ESP32 lib integrated to Arduino.
Those who really know what they are doing may be able to get ArduinoIDE to do it all, but I have been unable to do so.
BLE?
I found that BLE was too slow for my needs, around 5,400kbp at best?, so I didn't pursue it fully. Regular Bluetooth serial is much faster, but I gave up on that for my iOS app due to 'Apple' reasons. I currently have iPhoneXR<WiFI>ESP32<wire>HC12<433mhzRF>HC12<wire>Atmega1608mcu working. I'm finding the HC12 to be limited to 38,400baud due to range and data dropout.
I hope u succeed!
 
Upvote 0

KiloBravo

Active Member
Licensed User
My "project" is controlling a mobile base from ESP32. Everything works fine. I had done a lot of it last year and then work/family got in the way. LOL
I did have two KY-023 joysticks (Thanks to whoever posted that ! I did give you a thumbs up ) hardwired to an ESP32. I read the Joysticks with the ADC on the ESP32.
I then send data over UDP to the base which has an ESP8266. That is then hardwired to the motor controllers. That all works fine. But, I didn't like the motion of the KY-023 Joysticks. When you push it half way up it it reads 1024 on the ADC. So it is hard to get fine control with it.

I thought I would get a wireless game controller and replace the hardwired joysticks with the game controller. (which people call Con apparently.)
So Contoller w/BT to ESP32. Then the ESP32 sends off that info to the ESP8266 using UDP.
My additional reading here >>> https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/issues/7 found this comment ...
It's not BLE, it's standard Bluetooth. Most of the examples are using Linux and a RasbPI or some other chip not an ESP32. Most of the folks are Gamers and they are interested in talking to the Game Console as a Controller. I want to talk to the Controller, I do not even have a Game Console.
The main issue I have right now is trying to pair the ESP32 with the BT Wireless Game Controller. Apparently I need to know the MAC Address of the Game Controller, the BD_ADDR (BT Address ?), and possibly a LTK (Life Time Key). The dekuNukem Git Hub site documents all the Reports and Sub Reports for Input and Output.
I will keep plugging away at it. I am new to BT. One of the issues is everyone assumes everyone knows all the acronyms.
The other is folks seem to switch between talking about a wired USB connection and Wireless BT connection. It makes it hard for me to follow which one they are referencing. Thanks!
 
Upvote 0

KiloBravo

Active Member
Licensed User
This post helped clear up a lot for me in regards to Classis/BLE BlueTooth, at least for what I am trying to do.
Trying to pair the wireless pro controller with my phone gave me it's BD_ADDR even though it did not connect.
Reading through this post for the 5th time is getting me to the point where I know how much I don't know.
This was a great post as well.
Putting it all together I am hopeful I can get something working.
If some here had a HID Host Demo written in b4r I would have had this working a week ago! LOL !
 
Upvote 0

KiloBravo

Active Member
Licensed User
Upvote 0

KiloBravo

Active Member
Licensed User
Still working on this. Found this on Git Hub...
He has lots of examples, but uses the ESP-IDF. At least it uses the BT Stack that comes with the ESP-IDF.
His examples are great and his code is well written. :)
I thought the Arduino Env was annoying compared to B4R. That was before I set up the ESP-IDF. LOL
I did manage to get his BT_Discovery example working tonight.
I (1278) GAP: Discovery started.
I (4018) GAP: Device found: a0:5a:5c:01:e8:7c <<< That is the BD_ADDR of my Game Controller.
I (4018) GAP: --Class of Device: 0x2504 <<< That is the correct COD for my "GamePad"
I (4018) GAP: --RSSI: -43
I (4018) GAP: Found a target device, address a0:5a:5c:01:e8:7c, name
I (4028) GAP: Cancel device discovery ...
I (4038) GAP: Device discovery stopped.
I (4038) GAP: Discover services ...
W (8308) BT_SDP: SDP - Wrong type: 0x09 in attr_rsp

Onward and Upward ! Tomorrow is another day full of opportunities !
 
Upvote 0

KiloBravo

Active Member
Licensed User
Still working on this. The JSNOWDEN33 Link does what I want but uses BlueKitchen Stack.
This guy does something very similar to what I wanted with this project. Controller to ESP32 to Console.
I just want the Controller to ESP32.
NathanReeves/BlueCubeModv2
As far as I can tell he ADDED to the ESP-IF implementation of the BlueDroid BT Stack.
NathanReeves/esp-idf/components
He seems to have expanded what ESP-IDF did with their BlueDroid implementation.
It looks like he implemented a lot of the low level functionality that BlueKitchen has in their BT Stack.
esp_hidd_api.h
esp_hidd_api.c
This was based of a fork from Molorius/esp-idf
Molorius had an issue open with EspressIf on this. Seems they added some of the functionality in the the BTSerial examples with their recent release. (4.1?Beta?)
But not all of it. No idea, if EspressIf ever will add it all or go a different direction.
Right now I am trying to get the BlueCubeModv2 to compile and load into the ESP32. Having some issues with the change from MAKE to CMAKE.

I would assume the files he created could be added to the Arduino BT Serial Lib and eventually wrapped into a B4R lib.
It would be great to have all that BT functionality in a B4R lib. But, it would probably take me a year to do it if I didn't have day job.

Learning about BlueTooth is like drinking from a fire hose. Also, the Switch compatible "Pro Controller" has a unique sync protocol.
I should have just ordered a PS4 compatible game controller (already an Arduino Lib for that). I am not trying to connect to a Switch Game Console anyway.

I may just go back to trying to find some decent joysticks to control my mobile base.
All the B4R code was working fine with the esp32 on one side side sending UDP packets to an esp8266 on the mobile base side.
Joysticks >>> ESP32 >>>UDP Packets>>>ESP8266>>>Left/Right Motor Controllers.
Using two of these Infineon boards for the left and right motor control from a re-purposed Jazzy Select 6 Power Chair . (I got it for a good price, free)
DCMOTORCONTRBTN8982TOBO1-ND from DigiKey

I may be the only one reading this post ! LOL !!!
 
Upvote 0

dominsch

New Member
Hey are you still working on this? I'm also trying to connect an esp32 to switch pro controller clone.
I'm using the ESP-IDF 4.4 with the Bluedroid stack and I'm getting the same "Wrong type: 0x09 in attr_rsp" error.
I modified the file hci_hal_h4.c that handles the communication between the HCI and Bluedroid to print out the data sent.
The connection is created successfully with the device giving us the following information:
- Name: Pro Controller
- Mac: XX:XX:XX:XX:XX:XX
- Rssi
- Device Class: 0x2504 (joystick)
- Manufacturer Name: 05D6 (Zhuhai Jieli technology Co.,Ltd)

After that there are a bunch of asynchronous data packets and I'm not sure what format they are in.
They contain strings like W i r e l e s s G a m e p a d , G a m e p a d and N i n t e n d o.

They might be using the HID protocol? I hope that if someone reads this in a year or two this helps them a little.
 
Upvote 0

dominsch

New Member
All right a quick update.
The problem was that the gamepad isn't using the Service Discovery Protocol correctly. This causes the discovery to stop prematurely because it can't parse the response. To fix this we have to patch a file in the ESP-IDF named esp-idf/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c.
In the function static *save_attr_seq add the following lines:

C:
UINT32      seq_len, attr_len;
UINT16      attr_id;
UINT8       type, *p_seq_end;
tSDP_DISC_REC *p_rec;

type = *p++;
        
//start of patch
if ((type >> 3) == UINT_DESC_TYPE) {
    //this could potentially read random data and crash your program
    p-=4;
    type = *p++;
}
//end of patch
        
if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
    SDP_TRACE_WARNING ("SDP - Wrong type, want data sequence: 0x%02x in attr_rsp\n", type);               
    return (NULL);       
}

I don't know why but the SDP wants you to have 2 sequences at the beginning of the response and the gamepad only sends one. The first sequence is discarded anyway so we make it think the first sequence is the second one. The documentation on this is in the bluetooth spec which has 3000 pages and can be found if you look for the pdf on google.

With this fixed I was able to run the HID host demo from the idf:

I (8878) ESP_HIDH_DEMO: a0:5a:5c:14:fa:d5 OPEN:
BDA:a0:5a:5c:14:fa:d5, Status: OK, Connected: YES, Handle: 0, Usage: GAMEPAD
Name: , Manufacturer: , Serial Number:
PID: 0x2009, VID: 0x057e, VERSION: 0x0001
Report Map Length: 170
VENDOR OUTPUT REPORT, ID: 18, Length: 48
VENDOR OUTPUT REPORT, ID: 17, Length: 48
VENDOR OUTPUT REPORT, ID: 16, Length: 48
VENDOR OUTPUT REPORT, ID: 1, Length: 48
VENDOR INPUT REPORT, ID: 63, Length: 11
VENDOR INPUT REPORT, ID: 51, Length: 361
VENDOR INPUT REPORT, ID: 50, Length: 361
VENDOR INPUT REPORT, ID: 49, Length: 361
VENDOR INPUT REPORT, ID: 48, Length: 48
GAMEPAD INPUT REPORT, ID: 33, Length: 48
 
Upvote 0

Gura 73

New Member
All right a quick update.
The problem was that the gamepad isn't using the Service Discovery Protocol correctly. This causes the discovery to stop prematurely because it can't parse the response. To fix this we have to patch a file in the ESP-IDF named esp-idf/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c.
In the function static *save_attr_seq add the following lines:

C:
UINT32      seq_len, attr_len;
UINT16      attr_id;
UINT8       type, *p_seq_end;
tSDP_DISC_REC *p_rec;

type = *p++;
       
//start of patch
if ((type >> 3) == UINT_DESC_TYPE) {
    //this could potentially read random data and crash your program
    p-=4;
    type = *p++;
}
//end of patch
       
if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
    SDP_TRACE_WARNING ("SDP - Wrong type, want data sequence: 0x%02x in attr_rsp\n", type);              
    return (NULL);      
}

I don't know why but the SDP wants you to have 2 sequences at the beginning of the response and the gamepad only sends one. The first sequence is discarded anyway so we make it think the first sequence is the second one. The documentation on this is in the bluetooth spec which has 3000 pages and can be found if you look for the pdf on google.

With this fixed I was able to run the HID host demo from the idf:

I (8878) ESP_HIDH_DEMO: a0:5a:5c:14:fa:d5 OPEN:
BDA:a0:5a:5c:14:fa:d5, Status: OK, Connected: YES, Handle: 0, Usage: GAMEPAD
Name: , Manufacturer: , Serial Number:
PID: 0x2009, VID: 0x057e, VERSION: 0x0001
Report Map Length: 170
VENDOR OUTPUT REPORT, ID: 18, Length: 48
VENDOR OUTPUT REPORT, ID: 17, Length: 48
VENDOR OUTPUT REPORT, ID: 16, Length: 48
VENDOR OUTPUT REPORT, ID: 1, Length: 48
VENDOR INPUT REPORT, ID: 63, Length: 11
VENDOR INPUT REPORT, ID: 51, Length: 361
VENDOR INPUT REPORT, ID: 50, Length: 361
VENDOR INPUT REPORT, ID: 49, Length: 361
VENDOR INPUT REPORT, ID: 48, Length: 48
GAMEPAD INPUT REPORT, ID: 33, Length: 48
Hello Dominsch!
I saw your entry on this forum and decided to write here.
I have a similar problem, I cannot connect a non-original PS 4 controller to ESP 32. I am trying to do this in the Arduino IDE development environment. I am using PS4-ESP32 library for Arduino IDE. But when I try to connect, I always get a negative result. I suspect that my problem is similar to yours, but since I'm a newbie and I wanted to ask you for help. Thanks in advance.
 
Upvote 0
Top