nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.35k stars 710 forks source link

ESP32 BLE HID send crush symbols in the product description #659

Open ARPavel22 opened 5 years ago

ARPavel22 commented 5 years ago

Hi, and Thank you for your great work!

I'm trying to create a gamepad for the UNITY. Everything works perfectly. The code works.

But when ESP connect to a computer, one of the parameters of HID is NOT recognized correctly. Most likely it is "PRODUCT NAME".

I think that Chinese people sewed their own hieroglyphics during the testing phase of the motherboard.

You can test the work of a hid with a simple program: Joystic test program http://www.planetpointy.co.uk/joystick-test-application/

Here are screenshots of poor performance:

At first it seems that everything is fine: joytest1

When switching to RAW INPUT program starts freezing because of bad characters: joytest2

Here is from Unity3D editor: joytest3

The problem is not in the name of the Bluetooth device. It is displayed correctly.

Can I change the other settings of the HID device?

chegewara commented 5 years ago

You can use those function to setup hid specific parameters: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEHIDDevice.h#L43-L49

ARPavel22 commented 5 years ago

You can use those function to setup hid specific parameters: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEHIDDevice.h#L43-L49

Thank you for the quick response. You showed me the right way to search.

NOTICE: I work with code from this post -> https://github.com/nkolban/esp32-snippets/issues/632

joytest4

joytest5

chegewara commented 5 years ago

Hi, thanks for testing and explaining how you solved your issue. It is how bluetooth hid works, its so called little endian. Bytes order is swapped. What is strange its manufacturer name, in device manager ive been checking and it was displayed as it should be (some time ago). Could you check it please?

Also for vendorID you can check this site, espressif is 0x02E5(you dont have to use it): https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers

mitchjs commented 5 years ago

Isn’t USB little endian?

And all descriptor strings are UNICODE (I think UTF-16)

I think the function, should swap endianness of the vid/pid …

void pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version);

Just to make ones code cleaner

mitch

From: chegewara notifications@github.com Sent: Saturday, September 29, 2018 1:47 PM To: nkolban/esp32-snippets esp32-snippets@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: Re: [nkolban/esp32-snippets] ESP32 BLE HID send crush symbols in the product description (#659)

Hi, thanks for testing and explaining how you solved your issue. It is how bluetooth hid works, its so called little endian. Bytes order is swapped. What is strange its manufacturer name, in device manager ive been checking and it was displayed as it should be (some time ago). Could you check it please?

Also for vendorID you can check this site, espressif is 0x02E5(you dont have to use it): https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/nkolban/esp32-snippets/issues/659#issuecomment-425663290 , or mute the thread https://github.com/notifications/unsubscribe-auth/AAtpXyBxMlgbNGbO3IysmuaCBjzsdWqmks5uf7INgaJpZM4W-scp . https://github.com/notifications/beacon/AAtpXwaFCyS4VUs0BVKPYTSsbZUuxH49ks5uf7INgaJpZM4W-scp.gif

chegewara commented 5 years ago

The fields in the above table are in the order of LSO to MSO. Where LSO = Least Significant Octet and MSO = Most Significant Octet

https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.pnp_id.xml

ARPavel22 commented 5 years ago

The fields in the above table are in the order of LSO to MSO. Where LSO = Least Significant Octet and MSO = Most Significant Octet

https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.pnp_id.xml

I'm going to test your advice. But first I want to clarify the sequence of variables.

About HID INFO: hid->hidInfo(0x00,0x01);

  1. Country code: 0x00 = without country
  2. Some flags (which I did not understand) but just set 0x01

===================================================================

About PNP:

void BLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version) 

hid-> pnp (0x02, 0x1008, 0x01e5, 0x0601);
  1. SIG (Vendor ID Source): 0x01 = Bluetooth SIG assigned Company Identifier value from the Assigned Numbers document 0x02 = USB Implementer’s Forum assigned Vendor ID value (Should I use the first? 0x01)

  2. VID (Vendor ID) - Get from list: https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers

  3. PID (Product ID) ??? can i use 0x01?

  4. VERSION (Product Version) ??? can i use 0x01?

===================================================================

And last. What is passed in these two parameters? This is similar to the HID INFO? uint8_t val[] = {0x01, 0x00}; desc->setValue(val, 2);

  void onConnect(BLEServer* pServer){
    Serial.println("connected");
                // workaround after reconnect (see comment below) 
                BLEDescriptor *desc = input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
                uint8_t val[] = {0x01, 0x00};
                desc->setValue(val, 2);

                _connected = true;
  }
chegewara commented 5 years ago
  1. Im guessing you should use 0x01 since you want to build bluetooth hid device;
  2. To be honest i dont know if you can use espressif VID, esp32 is espressif board but final product is not; you should ask this on espressif/esp-idf github or on esp32.com forum
  3. and 4. You can use whatever you want for PID
  4. Yes. There is no info about value being little endian, but its the same case: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
ARPavel22 commented 5 years ago

Another sleepless night with ESP32 BLEt...

joytest71

P.S. :

I need the correct signature of the device in order to find it in the Unity3D input manager. The rest works as it should. The gamepad data is transmitted. So far I need to start another part of the project. But I will also return to this post because I can not finish the project without solving this problem.

chegewara commented 5 years ago

As you can see all works fine with iPhone, which means you have issue with unity3d bluetooth library. Like i said, you can check on windows in device manager how your hid device is recognized.

ARPavel22 commented 5 years ago

As you can see all works fine with iPhone, which means you have issue with unity3d bluetooth library. Like i said, you can check on windows in device manager how your hid device is recognized.

Perhaps this is a UNITY3D problem. I'll try to ask a question on their forum. But why then RN42 is recognized correctly?.. https://user-images.githubusercontent.com/38073729/46257090-b0912c80-c4bc-11e8-8067-ec1cb60d934b.png

chegewara commented 5 years ago

Could you intercept raw advertising packet from RN42 and from esp32?

ARPavel22 commented 5 years ago

Could you intercept raw advertising packet from RN42 and from esp32?

I will try to grab packets with this soft: https://www.hhdsoftware.com/device-monitoring-studio

If u can advice most simle soft or decision how to do this, please, send here.

chegewara commented 5 years ago

I am using app on android, nRF connect.

ARPavel22 commented 5 years ago

I am using app on android, nRF connect.

I do not have an android on hand. Only IOS version of nRF app:

logesp

And there is from device-monitoring-studio:

000000: Descriptor parsing failed. (UP), 2018-09-30 16:46:23,7194741

There is an assumption that there is a shift of a few bytes or something like that because of what everything breaks down.

chegewara commented 5 years ago

Hi, any progress here?

ARPavel22 commented 5 years ago

Hi, any progress here?

Hi. Unfortunately, I was busy with the rest of the project and wrote a question to UNITY3D just now.

Here is: https://forum.unity.com/threads/input-system-update.508660/page-7#post-3759496

I look forward to hearing from them and will investigate further.

chegewara commented 5 years ago

Maybe there is some option to change name parsing to utf8? Because it looks like it is parsed with unicode standard probably.

ARPavel22 commented 5 years ago

Maybe there is some option to change name parsing to utf8? Because it looks like it is parsed with unicode standard probably.

Good news. I received a response from the Unity team: https://forum.unity.com/threads/input-system-update.508660/page-7#post-3763249

We may be close to closing the issue...

chegewara commented 5 years ago

Ok, now you can tell them that they are wrong. This is bluetooth specs. https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.manufacturer_name_string.xml Of course they can say that you can send UTF-16 as array of uint8 bytes. You seems to have 2 options. Ask them to add UTF-8 support or convert name in unity from UTF8 to UTF16.

@ARPavel22 or send name from esp32 in UTF16

chegewara commented 5 years ago

@ARPavel22 Are you using generic library in unity or did you have to buy ble library from asset store? I would like to play with unity hid too.

ARPavel22 commented 5 years ago

@ARPavel22 Are you using generic library in unity or did you have to buy ble library from asset store? I would like to play with unity hid too.

There is new official INPUT SYSTEM (but in development yet): https://github.com/Unity-Technologies/InputSystem

For working with it repo you need Unity 2018.2.10f1 or upper

chegewara commented 5 years ago

Great, i will try it. Ive been searching for ble library but before i could not find any for free. Time to run unity3d. Thanks.

ARPavel22 commented 5 years ago

Great, i will try it. Ive been searching for ble library but before i could not find any for free. Time to run unity3d. Thanks.

I don't use BLE assets from store Just connect ESP32 BLE HID to my PC and its work. All connected HID devices found in Unity3D input manager automatically.

DOWNLOAD UNITY3D

chegewara commented 5 years ago

@ARPavel22 Could you share your unity3d code? At least part with hid device. I see unity3d input plugin is under development so i can see what i can do to help.

ARPavel22 commented 5 years ago

@ARPavel22 Could you share your unity3d code? At least part with hid device. I see unity3d input plugin is under development so i can see what i can do to help.

I did not write the code for joystick data processing. For now, I'm trying to figure out the device name.

inp Then in the list of devices, double-click on the MOUSE to test and you will see all the parameters.

In this window you can see all the parameters of HID devices:

chegewara commented 5 years ago

Ok, the problem is hard to solve. Unity devs are using standard windows HidD_GetManufacturerString. This function suppose to return wchar string. I have no idea how it should read hid this ble hid descriptor. Its not unity devs fault (my bad), you should rather ask microsoft community/devs why utf8 string which is properly read and parsed by windows drivers cant be passed properly in HidD_GetManufacturerString.

ARPavel22 commented 5 years ago

Ok, the problem is hard to solve. Unity devs are using standard windows HidD_GetManufacturerString. This function suppose to return wchar string. I have no idea how it should read hid this ble hid descriptor. Its not unity devs fault (my bad), you should rather ask microsoft community/devs why utf8 string which is properly read and parsed by windows drivers cant be passed properly in HidD_GetManufacturerString.

https://forum.unity.com/threads/input-system-update.508660/page-7#post-3764593

ARPavel22 commented 5 years ago

How do I change this three files:

to send string in UTF16?

my c++ is bad.

chegewara commented 5 years ago

try this in your unity code: https://docs.microsoft.com/en-us/dotnet/api/system.text.encoder?view=netframework-4.7.2

https://docs.microsoft.com/en-us/dotnet/api/system.text.utf8encoding?view=netframework-4.7.2

ARPavel22 commented 5 years ago

try this in your unity code: https://docs.microsoft.com/en-us/dotnet/api/system.text.encoder?view=netframework-4.7.2

It does not work. Unity3D gives access to the string already parsed. And it is either empty or mistakenly chosen manufactory of another connected device.

chegewara commented 5 years ago

@ARPavel22 This most likely wont solve your issue, but wont cause another. Fix your mine app code: BLEHIDDevice* hid; <--- delete static word

ARPavel22 commented 5 years ago

@ARPavel22 This most likely wont solve your issue, but wont cause another. Fix your mine app code: BLEHIDDevice* hid; <--- delete static word

I removed the static in the main program but it did not change anything.

_I still want to try sending uint16t chars.

chegewara commented 5 years ago

@ARPavel22 There's maybe one more problem with windows. In device manager my esp32 ble hid device is only enumerated in bluetooth category. I dont see it in sound, video and game controllers. Also in unity Input debug shows me esp32 as unsupported device even if input buttons are recognized (short video on YT).

ARPavel22 commented 5 years ago

@ARPavel22 There's maybe one more problem with windows. In device manager my esp32 ble hid device is only enumerated in bluetooth category. I dont see it in sound, video and game controllers. Also in unity Input debug shows me esp32 as unsupported device even if input buttons are recognized (short video on YT).

Try build this in arduino IDE: https://pastebin.com/Ca9XsiCG

Don't pay attention to the trash. The main thing that this example is recognized in Windows in sound, video and game controllers. Also in unity.

chegewara commented 5 years ago

I will, but this code is wrong: uint8_t b[] = {0x00, 0x00, brightness, 100 - brightness, brightness, 100 - brightness, brightness}; Your report map is telling me that you have 14 buttons (1 bit each) + 2 bits padding + 2 axis (byte each) = 4 bytes, but you are sending 7 bytes.

ARPavel22 commented 5 years ago

I will, but this code is wrong: uint8_t b[] = {0x00, 0x00, brightness, 100 - brightness, brightness, 100 - brightness, brightness}; Your report map is telling me that you have 14 buttons (1 bit each) + 2 bits padding + 2 axis (byte each) = 4 bytes, but you are sending 7 bytes.

Yes I know. But the sending function is never called.

chegewara commented 5 years ago

Yes, i know. I am preparing fix to it.

ARPavel22 commented 5 years ago

Yes, i know. I am preparing fix to it.

How can I find your YT channel?

chegewara commented 5 years ago

@ARPavel22 I can see your device as E502-1E5.

my channel is chegewaras

ARPavel22 commented 5 years ago

@ARPavel22 I can see your device as E502-1E5.

my channel is chegewaras

This is get from here: hid->pnp(0x01, 0x02E5, 0xe501, 0x0106); >>>>>>>>>>>> E502-1E5

chegewara commented 5 years ago

Try this code, its random generated value for buttons and axis. https://gist.github.com/chegewara/d3d2160f6be3ad2c1621daa6e666a115 hid

ARPavel22 commented 5 years ago

Try this code, its random generated value for buttons and axis. https://gist.github.com/chegewara/d3d2160f6be3ad2c1621daa6e666a115

Yes, the buttons and axes work, but I have successfully done this before. The device with your code is still recognized randomly:

kb

ARPavel22 commented 5 years ago

Look at this: https://forum.unity.com/threads/input-system-update.508660/page-7#post-3767413

Maybe on this time it was the first possible FIX.

chegewara commented 5 years ago

Looks you are having some support from unity team.

Dotby commented 3 years ago

Looks you are having some support from unity team..

Hello again. I started to port my work to the browser as it became possible to work with the WEB HID API. And even here I encountered the same problem. Windows wants UTF 16. If you have time, think about this task. image