adabru / BleWinrtDll

BLE for Unity 3d in Windows without UWP.
Do What The F*ck You Want To Public License
168 stars 52 forks source link

How can i get more than 30 packets a second. #38

Open Ugobyte opened 1 year ago

Ugobyte commented 1 year ago

Firstly, thanks for this great .DLL

I have a BLE device that streams data 30 times a second. Each data contains 5 bytes. This .DLL seems to handle in-coming data with ease when my BLE device is streaming at 30/sec. However, when I set my BLE device to stream at 60/second, there is a lot of delays and corrupted data. Same as 45/sec. Even at 38/sec, I'm still seeing some delays. It seems like this .DLL can only handle a maximum of 30 characteristic updates per second.

Is this something that can easily be changed? Or am I doing something wrong.

adabru commented 1 year ago

First I would try another Bluetooth dongle, they can greatly differ in their throughput. For my project I tried 3 different ones until the last one had the performance I'd expect from BLE. I think the delays and corrupted data are coming from data-congestion. See also https://github.com/adabru/BleWinrtDll/issues/4.

Furthermore you can try merging multiple packages together, like sending 15 bytes at 20/sec. If you're concerned about latency, you can make sure to use threads. In my case they saved around 15-20ms for a wired connection.

I doubt you can get much over 60 user packages per second with standard hardware. Maybe 90-100/s. As reference, there is some design guideline that seems to limit the connection interval for their products to 15ms: https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf , chapter 41.6 Connection Parameters. With a good Bluetooth dongle, you can try to set the connection interval to zero. The document also reminds that you can save energy by merging packages

Ugobyte commented 1 year ago

Thank you! You just helped me think in the right direction.

I should've mentioned that my BLE device is an ESP32. I looked at my GATT characteristic that streams out the data, it turns out i added BLECharacteristic::PROPERTY_INDICATE as an option. I removed that option and now I can stream up to 60/sec with no delays nor corrupted data.

So for anyone who may have this issue in the future, if you created a GATT Characteristic in your ESP-32 BLE Code that is meant to stream data as fast as possible. Do not add the BLECharacteristic::PROPERTY_INDICATE option. The indicate option is a blocking call that waits for an ack from the other side.

My characteristic was assign this way at first: MyCharacteristic = MyService->createCharacteristic(MY_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_INDICATE);
This was slow.

Now my characteristic is assigned this way: MyCharacteristic = MyService->createCharacteristic(MY_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); This is fast.

Thanks @adabru You're a genius.