Esp32-snippets: ESP32 BLE HID send crush symbols in the product description

Created on 28 Sep 2018  Â·  45Comments  Â·  Source: nkolban/esp32-snippets

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?

All 45 comments

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

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

  • Changing the values of PNP I noticed an interesting feature.
    When the variable reaches the Unity editor, it is inverted:

joytest4

  • This leads to the thought that string manufacture also comes to be broken. Therefore, you can see the hieroglyphs and strange symbols in the name of the device.

  • After i swapped parts of the variable:

//hid-> pnp (0x02, 0x0810, 0xe501, 0x0106);
//CHANGE TO
hid-> pnp (0x02, 0x1008, 0x01e5, 0x0601);
  • I saw that in the UNITY3D editor they came as they should be.

joytest5

  • It seems to me that the bytes of the manufacturer are also inverted
    It remains to understand how to properly pass on the manufacture data?
    std::string name = "esp-community";
    hid->manufacturer()->setValue(name);

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

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

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

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;
  }
  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

Another sleepless night with ESP32 BLEt...

  • For a start I want to show is an example of a gamepad I made on a RN42 chip
    Everything works perfectly. We can see the name of the manufacturer and the name of the joystick.
    joytest6

  • I tried everything I could.
    I even changed the source so that it sends one character A to the manufactory on the init of device.
    const uint8_t pMode[] = {0x14};

BLECharacteristic*  BLEHIDDevice::manufacturer() {
    m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a29, BLECharacteristic::PROPERTY_READ);
    const uint8_t pMode[] = {0x14};
    m_manufacturerCharacteristic->setValue((uint8_t*)pMode, 1);
    return m_manufacturerCharacteristic;
}
  • I do tests on a PC and on an iPhone. On the iPhone I saw the symbol of the manufactory .
    joytest10

  • But the PC could not figure it out.
    In addition, I noticed another strange feature.
    Each reconnect of the ESP produces different symbols. As if bytes break in different sequences.

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.

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.

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

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

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.

I am using app on android, nRF connect.

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.

Hi,
any progress here?

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.

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

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..._

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

@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 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

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.

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

@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 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.

  • Just download the repository of INPUT SYSTEM. (This is ready to open Unity3D project)
    https://github.com/Unity-Technologies/InputSystem
  • Then open the Unity.
  • Choose to OPEN a project.
  • Choose the unzipped folder of "InputSystem" (master).
  • Open the project.
  • And look in the window of the Input Debugger:

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:

  • HID parameters.
  • button presses.
  • gamepad axes.
  • ect.

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.

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

How do I change this three files:

  • BLEHIDDevice.cpp
  • BLEHIDDevice.h
  • BLECharacteristic.h

to send string in UTF16?

my c++ is bad.

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.

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

@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 uint16_t chars._

@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 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._

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.

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.

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

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

How can I find your YT channel?

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

my channel is chegewaras

@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

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

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

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.

Looks you are having some support from unity team.

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JasXSL picture JasXSL  Â·  3Comments

Smeedy picture Smeedy  Â·  5Comments

Lakoja picture Lakoja  Â·  8Comments

mahdikan picture mahdikan  Â·  4Comments

hansmbakker picture hansmbakker  Â·  6Comments