Forum Archive

Problems to disconnect Arduino 33 Nano BleSense from Ble

ProgrammingGo

Hi,

I am using an Arduino 33 Nano Ble which has BLE functionality. So I was looking on the examples given in Pythonista how to use the cb module to connect to a BLE device.
Everything is clear and I am able to connect over Pythonista that is running on my iPad to the Arduino board. For the beginning, I used the example code here which I adapted slightly: http://omz-software.com/pythonista/docs/ios/cb.html
I have only one problem, when I am disconnecting from Bluetooth (pressing the x button in Pythonista) the app tells me that the board is disconnected, but the Arduino keeps still the Bluetooth connection alive. I tried it with an BLE app (LightBlue) from the Appstore and I am not having this problem. Do you know how I could solve it?
I have the feeling that the did_disconnect callback does not work good.
Can you give me some suggestions?

mikael

@ProgrammingGo, I could be completely wrong, but looking at Apple’s CBPeripheral class, which I am sure Pythonista has wrapped, there is no apparent way to do an explicit disconnect.

Thus I would not be surprised if the reset() method in Pythonista were more of a thing where Pythonista forgets all about the connection, but does not enforce an actual disconnect.

Ugly, but an option that comes to mind would be to call a Shortcut to cycle the device Bluetooth.

(All the above from someone who has never really played with ble peripherals on Pythonista.)

mikael

@ProgrammingGo, what does this show when you have Arduino connected?

import objc_util


CBCentralManager = objc_util.ObjCClass('CBCentralManager')

cb_manager = CBCentralManager.alloc().init()

print(cb_manager.retrieveConnectedPeripherals())

If you get something, CBCentralManager has cancelPeripheralConnection_ method that you could try with object retrieved above. There is even a cancelPeripheralConnection_force_ method, but it seems undocumented.

From the Apple doc:

”Because other apps may still have a connection to the peripheral, canceling a local connection doesn’t guarantee that the underlying physical link is immediately disconnected. From the app’s perspective, however, the peripheral is effectively disconnected, and the central manager object calls the centralManager(_:didDisconnectPeripheral:error:) method of its delegate object.”

ProgrammingGo

Hi mikael,

thank you for your response. Where should I integrate this code? should it be in the did_disconnect function of the example, or should I run this code as standalone?

ProgrammingGo

Hi mikael,

I was trying but it did not work out. Should I exchange it with the cb.reset() for the delegate where the following code is??

try:
     while True: pass
except KeyboardInterrupt:
cb.reset()
ProgrammingGo

I found in the cb module description a similar function, but is it object-related : cb.cancel_peripheral_connection(peripheral)
and in the keyboard interrupt I do not have the reference to the peripheral object, see example which I am using from the documentation

mikael

@ProgrammingGo, in did_discover_peripheral, I see setting the self.peripheral. I would think that is what you need.

ProgrammingGo

Hi mikael,
I tried it out but I am getting the error message "no Objective-c class named"CBCentralManager"

WHat I am doing wrong?

ProgrammingGo

I tried like that:

 def did_discover_peripheral(self, p):
        if p.name and 'Polar' in p.name and not self.peripheral:
            self.peripheral = p
            print('Connecting to heart rate monitor...')
            cb.connect_peripheral(p)

           CBCentralManager = objc_util.ObjCClass('CBCentralManager')

            cb_manager = CBCentralManager.alloc().init()

           print(cb_manager.retrieveConnectedPeripherals())

but I not get anything out from it. Only connecting to heart rate monitor