ukBaz / python-bluezero

A simple Python interface to Bluez
MIT License
396 stars 112 forks source link

Slow performance #130

Closed vbisbest closed 7 years ago

vbisbest commented 7 years ago

I am using the blinkt_ble as a template for a high thoughput GATT service. I am doing a speed test and I am getting about 2 "writes" a second. I need about 50. Is there something in localGatt or blinkt to speed up how fast it can process incoming characteristic writes? Thanks.

ukBaz commented 7 years ago

There has been some discussion on the BlueZ mailing list about throughput speeds: http://marc.info/?l=linux-bluetooth&m=146852506602040&w=2

Seems like they never got to a conclusion on the discussion.

I have not done any speed sensitive activity so I have no experience. I would suggest raising this as a discussion on the BlueZ mailing list. More details available at: http://www.bluez.org/contact/

ukBaz commented 7 years ago

@vbisbest have you done any more with this? This has got me curious and I've been doing some thinking... So to think out loud:

It is not clear from your description above if your service is writing or is being written to. Are you able to share some more details? Do you know where the delay is happening?

As you will be having to do this asynchronously I am wondering if this is an issue with the event loop. As I've raised before there is some concern around python-dbus which seems to be around its use of DBus-GLib

I am relatively new to async myself so I found these links useful: https://youtu.be/iG6fr81xHKA https://stackoverflow.com/questions/33428804/role-of-mainloops-event-loops-in-dbus-service

If I make the assumption you are writing out data from your service... I assume you are using something like timeout_add(20, my_write_callback), is that happening faster than twice a second if your my_write_callback doesn't actually write? Have you tried using notifications rather than writes?

vbisbest commented 7 years ago

I have dug in more on this and have now given up on bluetooth for my project. Its just a limitation on how BLE works. There is a send interval built in and it cannot be changed. On iOS, you can only send 1 packet every 30ms. This is too slow for my audio application, everything lags behind. Luckily I am working with a Raspberry pi as the peripheral and I have now enabled it as a WiFi access point. So now I can use WiFi between the PI and the mobile devices without any limitations. Thanks for the help!

ukBaz commented 7 years ago

Thanks for the feedback. I'll close this ticket at this point.

For future reference I'll leave this link here as I think this is what you are talking about: https://punchthrough.com/blog/posts/maximizing-ble-throughput-on-ios-and-android

Did you look at Bluetooth BR/EDR profiles that support audio on Linux? https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/

viktor404 commented 5 years ago

I came across this trick to change the default Connection Interval setting in the following way:

echo 8 > /sys/kernel/debug/bluetooth/hci0/conn_min_interval echo 9 > /sys/kernel/debug/bluetooth/hci0/conn_max_interval

With this I managed to get pin read times down to 4.7millisec between a Zero W and a Bit:Commander

ukBaz commented 5 years ago

Do you have a link more information about these parameters.

I have seen various values talked about for these parameters and it would be good to understand the trade-offs of different values

WayneKeenan commented 5 years ago

You can make these changes more permanent and make them per device, as well as tweaking other settings too. (I think you have to pair the device to be able to get the config generated in the first place)

Have look at the [ConnectionParameters] section in info file in folders matching the pattern:
/var/lib/bluetooth/[host_adapter_BDADDR]/[device_BDADDR]`

e.g. I have on one of my Pi's a file:

/var/lib/bluetooth/B8:27:EB:76:xx:xx/C0:24:26:32:xx:xx

Contents:

[General]
Name=nrf52_123
AddressType=static
SupportedTechnologies=LE;
Trusted=false
Blocked=false
Services=00001800-0000-1000-8000-00805f9b34fb;00001801-0000-1000-8000-00805f9b34fb;6e400001-b5a3-f393-e0a9-e50e24dcca9e;

[ConnectionParameters]
MinInterval=6
MaxInterval=12
Latency=0
Timeout=400
WayneKeenan commented 5 years ago

@ukBaz I think the kernel config values are in units of 1.25 ms and I've previously found this was interesting read for understanding the tweaking: https://punchthrough.com/pt-blog-post/maximizing-ble-throughput-on-ios-and-android/

I think I managed to quadruple the data thru put in my application between a Pi and a nrf52 device.

ukBaz commented 5 years ago

Good reference. Thanks @WayneKeenan