IanHarvey / bluepy

Python interface to Bluetooth LE on Linux
Other
1.6k stars 491 forks source link

Raspberry Pi 4 unable to connecto to device if is too close according to RSSI #411

Closed fabocode closed 3 years ago

fabocode commented 4 years ago

I have 2 pi's (4 and 3B+) both have the same software but I have an oximeter sensor that is unable to connect to the raspberry pi 4 when the RSSI is lower than -50 dBm (-30 to -50). If I go a bit farther, with RSSI values greater than -50 (-50 to -70) I'm able to connect to the device and even get readings from notifications (however, this readings are unaccurate).

[bluetooth]# power on
00:a0:50:31:2b:6d
device recognized: 00:a0:50:31:2b:6d rssi: -34
going to connect to  BerryMed
device connected:  BerryMed
characteristic_target Characteristic <49535343-1e4d-4bd9-ba61-23c647249616>
ccc_handle 15
[ERROR]: device disconnected, a BTLEDisconnectError happened:  [Device disconnected]
[DEBUG]: run: [sudo hciconfig hci0 reset]
[DEBUG]: run: [sudo hciconfig hci0 up]
[DEBUG]: run: [echo "power on" | bluetoothctl]
Agent registered
[bluetooth]# power on
00:a0:50:31:2b:6d
device recognized: 00:a0:50:31:2b:6d rssi: -40
going to connect to  BerryMed
device connected:  BerryMed
characteristic_target Characteristic <49535343-1e4d-4bd9-ba61-23c647249616>
ccc_handle 15
[ERROR]: device disconnected, a BTLEDisconnectError happened:  [Device disconnected]
[DEBUG]: run: [sudo hciconfig hci0 reset]
[DEBUG]: run: [sudo hciconfig hci0 up]
[DEBUG]: run: [echo "power on" | bluetoothctl]
Agent registered
[bluetooth]# power on

On Pi3 this is event is not present. Raspberry Pi 3B+

Do anybody has an idea about what could possibly be the reason? One thing I could do is to change the bluetoothd version since bluepy last revision was supported at 4.47.

I'm not pasting code because I feel this is a problem more related to raspberry pi 4 OS system than my code in bluepy which is working great in PI 3B+.

Another thing that I have in mind is what I have being reading on this issues like in #396 and #409

Any help will be great.

CLDiego commented 4 years ago

It is a weird behaviour. Certainly one would expect to have no problems connecting with RSSI > -50dB.

Usually I get unreliable data if the RSSI < -65dB, in this case is best to use indications rather than notifications. If your hardware has some flow control, indications might solve the issue.

I can say from experience using the RN4871 (a BLE device without flow control) that indications help get all the data under lower RSSIs, but some prefix or similar should be added to the messages since the order in which they are received might differ from when they were sent (e.g. you might receive message 80 before message 50).

The other thing you could try is using a bluetooth dongle instead of relying on the PI bluetooth module.

Hope it helps!

fabocode commented 4 years ago

I'm starting to think that is other issue... I have been doing more tests and distance does not look to be the issue.

I tried with other sensors that I have, glucometers, weight scale, bpm, other oximeters but with this device in particular is what is giving problems.

I will print here what's the output from debugging:

device recognized: 00:a0:50:a2:ba:94 rssi: -47
Running  /usr/local/lib/python3.7/dist-packages/bluepy-1.3.0-py3.7.egg/bluepy/bluepy-helper
Sent:  conn 00:a0:50:a2:ba:94 public

Got: '# bluepy-helper.c version 1.3.0 built at 16:59:16 on Jul 29 2020\n'
Got: "rsp=$stat\x1estate=$tryconn\x1edst='00:a0:50:a2:ba:94\x1emtu=h0\x1esec='low\n"
Got: "rsp=$stat\x1estate=$conn\x1edst='00:a0:50:a2:ba:94\x1emtu=h0\x1esec='low\n"
device connected: BerryMed
serv: 49535343-fe7d-4ae5-8fa9-9fafd205e455
Sent:  svcs 49535343-fe7d-4ae5-8fa9-9fafd205e455

Got: 'rsp=$find\x1ehstart=hC\x1ehend=h15\n'
char: 49535343-1e4d-4bd9-ba61-23c647249616
Sent:  char C 15

Got: "rsp=$find\x1ehnd=hD\x1eprops=h10\x1evhnd=hE\x1euuid='49535343-1e4d-4bd9-ba61-23c647249616\x1ehnd=h10\x1eprops=hC\x1evhnd=h11\x1euuid='49535343-8841-43f4-a8d4-ecbe34729bb3\x1ehnd=h12\x1eprops=hC\x1evhnd=h13\x1euuid='00005343-0000-1000-8000-00805f9b34fb\x1ehnd=h14\x1eprops=h2\x1evhnd=h15\x1euuid='00005344-0000-1000-8000-00805f9b34fb\n"
characteristic_target Characteristic <49535343-1e4d-4bd9-ba61-23c647249616>
ccc_handle 15
Sent:  wrr F 0100

Got: "rsp=$stat\x1estate=$disc\x1emtu=h0\x1esec='low\n"
Stopping  /usr/local/lib/python3.7/dist-packages/bluepy-1.3.0-py3.7.egg/bluepy/bluepy-helper
30/07/2020 10:53:38 oximeter disconnected. Ready.

So every time I want to subscribe with a notify to the selected characteristic, it shows this

Got: "rsp=$stat\x1estate=$disc\x1emtu=h0\x1esec='low\n"
Stopping  /usr/local/lib/python3.7/dist-packages/bluepy-1.3.0-py3.7.egg/bluepy/bluepy-helper

Is it possible that there is a relation with the Maximum Transmission Unit (MTU)?

I also have a ble usb dongle here but I have the same results as when I work with the built in ble module.

Do you know what exactly means this output ?

Another information to have in mind is that the traceback is the following:

Traceback (most recent call last):
  File "/home/pi/evexia/project2/src/ble_manager.py", line 341, in get_notify
    self.enable_notify(p, self.dev_service, self.dev_char)
  File "/home/pi/evexia/project2/src/ble_manager.py", line 187, in enable_notify
    periph.writeCharacteristic(ccc_handle, notification_value, withResponse=True)
  File "/usr/local/lib/python3.7/dist-packages/bluepy-1.3.0-py3.7.egg/bluepy/btle.py", line 563, in writeCharacteristic
    return self._getResp('wr')
  File "/usr/local/lib/python3.7/dist-packages/bluepy-1.3.0-py3.7.egg/bluepy/btle.py", line 427, in _getResp
    resp = self._waitResp(wantType + ['ntfy', 'ind'], timeout)
  File "/usr/local/lib/python3.7/dist-packages/bluepy-1.3.0-py3.7.egg/bluepy/btle.py", line 382, in _waitResp
    raise BTLEDisconnectError("Device disconnected", resp)
bluepy.btle.BTLEDisconnectError: Device disconnected

The thing is that I have also a raspberry pi 3 b+ and I don't have this issue with that device, I can read data easily.

Fast question: When you use a USB BLE dongle device, how can you use that new module to work with bluepy in code? I was checking with lsub and with hciconfig -a and I think there should be no difference in code

pi@raspberrypi:~/evexia/project2/src $ hciconfig -a
hci1:   Type: Primary  Bus: UART
        BD Address: DC:A6:32:BC:BA:5F  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING
        RX bytes:1834 acl:19 sco:0 events:98 errors:0
        TX bytes:3625 acl:21 sco:0 commands:71 errors:0
        Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
        Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
        Link policy: RSWITCH SNIFF
        Link mode: SLAVE ACCEPT
        Name: 'raspberrypi #2'
        Class: 0x480000
        Service Classes: Capturing, Telephony
        Device Class: Miscellaneous,
        HCI Version: 5.0 (0x9)  Revision: 0x13b
        LMP Version: 5.0 (0x9)  Subversion: 0x6119
        Manufacturer: Cypress Semiconductor Corporation (305)

# this should be the new USB BLE Dongle
hci0:   Type: Primary  Bus: USB
        BD Address: 00:1A:7D:DA:71:15  ACL MTU: 310:10  SCO MTU: 64:8
        UP RUNNING
        RX bytes:9935 acl:0 sco:0 events:359 errors:0
        TX bytes:5794 acl:0 sco:0 commands:209 errors:0
        Features: 0xff 0xff 0x8f 0xfe 0xdb 0xff 0x5b 0x87
        Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
        Link policy: RSWITCH HOLD SNIFF PARK
        Link mode: SLAVE ACCEPT
        Name: 'raspberrypi'
        Class: 0x480000
        Service Classes: Capturing, Telephony
        Device Class: Miscellaneous,
        HCI Version: 4.0 (0x6)  Revision: 0x22bb
        LMP Version: 4.0 (0x6)  Subversion: 0x22bb
        Manufacturer: Cambridge Silicon Radio (10)
CLDiego commented 4 years ago

From the debugging it looks like your PI is not able to keep the connection alive. Sounds like a similar issue like this one, and it seems it's still haven't been solved.

From the last comments it seems the issue can be solved with a specific version of bluez.

As I said, distance it's important you should always try to maintain your devices with at least rssi > -70dB if you want to get all your data packets. There are ways to circunvent this, e.g. using indications instead of notifications, and putting in place some sort of flow control within your devices. Guarding your data might also help when getting data in the wrong order, so you can manage to reorder it again.

The PIs use different chipsets depending on which version you are using, there is one that is more unreliable with BLE connections. I'm not sure if the PI 3B+ uses a different chipset than the 4.

In my experience increasing the MTU can help get more stable data streams. From what you say, it seems like your PI (acting as the central) is not able to set up the adequate connection parameters. Remember each BLE peripheral has its own connection parameters, and usually they work within certain range. So the central will try to work within those ranges, but if it can't achieve them it will disconnect. If your sensor allows it, you could play around changing those connection parameters.

With regards with the last question, I haven't kept up to date with bluepy so I'm not sure if you can select which bluetooth you want to use.

I would disable the onboard bluetooth, so that bluepy is forced to use the dongle.

Good luck!

fabocode commented 4 years ago

Hey @CLDiego thanks for your fast reply.

This link helped a lot. It really fixed the issue.

1st I tested disabling the built in bluetooth and then I tested the USB Dongle, worked perfectly.

Then I added the follow the steps from the comments and reboot. Worked nicely.

It will be great to know what exactly is the version for what was actually changed.

I checked the version for the bluez with bluetoothd -v and I still have the 5.50v but I guess is currently a mistery for me.

Thank you for your help.

mdxs commented 3 years ago

@fabocode As it appears you've solved it on your side, could you please close this issue?