BLE does not connect
-
Hello. I am having a problem with BLE connection to the sensor. It was working fine for few weeks but now GPy returns exception on bluetooth.connect(mac_adr).
First I faced with this issue when GPy was working as webserver through WiFi and reading data from BLE sensors and sending it to the browser. Since some time GPy began to refuse restarting BLE scanning saying "operation already in progress" while bluetooth.isscanning() was False. Then bluetooth.connect(mac) began to return an exception.
Scanning works well and receives the advs and parses rssi, mac and other data. But even the examples from pycom.io don't work. The firmware version is the latest. I tried to refresh the firmware using Upgrade Tool and to erase the NVS and Config but it does not help. Downgrade neither helped. "time.sleep(0.05)" and "timeout=3000" instruction does not influence on the result. GPy does not connect to any device. The parsing the name of the sensor does not play any role.from machine import Pin import ubinascii from network import Bluetooth from network import WLAN import time ant = Pin('P12', mode=Pin.OUT) led = Pin('P23', mode=Pin.OUT) print("External antenna") ant.value(1) led.value(1) bluetooth = Bluetooth() bluetooth.start_scan(20) while bluetooth.isscanning(): adv = bluetooth.get_adv() if adv: data = bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) if data == 'TS00000503': try: time.sleep(0.05) print('i\'m here') connection = bluetooth.connect(adv.mac,timeout=15000) # connection = bluetooth.connect(adv.mac) print('Connected') services = connection.services() for service in services: chars = service.characteristics() for char in chars: if (char.properties() & Bluetooth.PROP_READ): print('char {} value = {}'.format(char.uuid(), char.read())) print(str(char.properties())) elif (char.properties() & Bluetooth.PROP_WRITE): print('char {}'.format(char.uuid())) print(str(char.properties())) connection.disconnect() print('Disconnected') except: print('exception') continue break print("Adv from device {}".format(ubinascii.hexlify(adv.mac))) bluetooth.deinit()
Using timeout returns
>>> >>> External antenna i'm here timed out Adv from device b'f4e0d51c9059' ♦♦>
Using connect(mac) without timeout returns
>>> >>> External antenna i'm here connection refused Adv from device b'f4e0d51c9059' ♦♦>
Please, advice.
-
@Meriç-SARIIŞIK Thank you for your help. Unfortunatelly, I have only one GPy. But I did few test.
The BLE server test works fine. Android smartphone with BLE scanner app can easily discover, connect and read the GPy. The result is below.>>> Client connected Client disconnected Client connected Client disconnected
I changed the name and mac in the client script to ones from my sensor. This script also does not connect.
>>> >>> change_adv() mac: b'\xf4\xe0\xd5\x1c\x90Y' Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 19, in change_adv OSError: connection refused >>>
But I discovered an interesting thing: if I run the BLE server first and run change_adv() after that thus GPy is able to connect to my sensor. My custom scripts connect successfully also. Note that "Client connected" and "Client disconnected" appear in the console but are absent in the change_adv().
>>> >>> change_adv() mac: b'\xf4\xe0\xd5\x1c\x90Y' Client connected services = conn.services() service: 6145 service: 6144 service: b'\x96KV\x94\xc0ms\x9a\x91L\xcc(\xb80\x02G' service: b'f\x9a\x0c \x00\x08\xa7\xba\xe3\x11\x06\x85\xc0\xf7\x97\x8a' >>> Client disconnected
The mac and the services are from my sensor. This situation makes me think the problem is in the firmware. But I re-updated the firmware, CONFIG, and NVS and it does not help.
-
Hi Aleksandr,
I was trying to reproduce your issue, but I couldn't do that. Can you please check your devices with these two scripts below on two GPy. Also, I don't know which firmware version you are using. I use development version which is 1.20.3.b3. Those examples work well. Please let me know when you try it.
# Client import time def change_adv(a=0, b=0, c=0): from network import Bluetooth bt = Bluetooth() bt.start_scan(-1) while True: adv = bt.get_adv() if adv and (bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'pypypypypy'): bt.stop_scan() print("mac:", adv.mac) if (adv.mac == b'0\xae\xa4X\xea\xbe'): pass else: break conn = bt.connect(adv.mac) try: services = conn.services() print("services = conn.services()") for service in services: u = service.uuid() print("service:", u) time.sleep(0.50) if isinstance(u, int): pass else: if u == b'1234567890123456': chars = service.characteristics() for char in chars: c_uuid = char.uuid() print("Prop(read: 2, write: 8):", char.properties()) print("char:", c_uuid) print("value:", char.read()) if c_uuid == b'ab34567890123456': value = bytes([a]) char.write(value) else: print(" ") conn.disconnect() break except Exception as e: print(e) if conn: conn.disconnect() bt.deinit() print("Error while connecting or reading from the BLE device") break else: time.sleep(0.050)
# Server from network import Bluetooth def conn_cb (bt_o): events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") def char1_cb_handler(chr, data): events, value = data if events & Bluetooth.CHAR_READ_EVENT: print('Read request on advertising interval') elif events & Bluetooth.CHAR_WRITE_EVENT: print("Write request on advertising interval") bluetooth = Bluetooth() srv_uuid=b'1234567890123456' bluetooth.set_advertisement(name='pypypypypy', service_uuid=srv_uuid) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) srv1 = bluetooth.service(uuid=srv_uuid, isprimary=True) char_uuid=b'ab34567890123456' chr1 = srv1.characteristic(uuid=char_uuid, value=2) char1_cb = chr1.callback(trigger=(Bluetooth.CHAR_WRITE_EVENT), handler=char1_cb_handler) bluetooth.advertise(True)
-
Hello, Gijs. Thanks for your fast reply. I set pybytes_on_boot(False). Other parameters were already set to False. It makes no difference whether WiFi is disabled or not. Now I have
>>> Heartbeat on boot: False WiFi on boot: False LTE modem on boot: False Pybytes on boot: False Smart config on boot: False Watchdog on boot: False ♦♦>
I had both WiFi and BLE working together and it was working correct. Once my colleague informed me that the script stopped working on his GPy. I faced this issue on my GPy the next day. I tested two scripts. The first script uses WiFi and BLE simultaneously plus three threads are running (web-server, BLE scanning, and timer). This script was broken first. But the second script (based on pycom examples like in the first post) was working well and connecting to the sensor. Later the second script started working every other time and finally lost the ability to connect at all. As the result, my GPy is unable to set up the BLE connection but the scanning works fine. To my mind, it is a software problem but I could not fix it.
The following is the part of script running "while(True)" and the results are paranormal and unexplainable.
# after adv has been received print("reading data... " + str(data)) try: connection = ble.connect(mac, timeout=10000) except: print('Connection false') print('is_scan: ' + str(ble.isscanning())) if not ble.isscanning(): print("restart scanning") ble.stop_scan() print('-- stopped --') try: ble.start_scan(-1) except Exception as e: print(e) ble.deinit() print('-- deinited --') ble.init() print('-- inited --') try: ble.start_scan(-1) except Exception as e: print(e)
reading data... TS00000503 Connection false is_scan: False restart scanning -- stopped -- operation already in progress -- deinited -- -- inited -- reading data... TS00000503 Connection false is_scan: False restart scanning -- stopped -- operation already in progress -- deinited -- -- inited --
I found out that the init process helps to start scanning again but the connection is not establishing.
Is there any debug options in BLE library to give an opportunity to find the problem? May be there is some utility to fully erase the flash of GPy or compare it with the source? Does the Pycom Upgrade Utility erase and rewrite the firmware and all the libraries to update the accidentally spoiled files?
-
The issue is (most probably) related to simultaneous use of the WiFi and BLE modules. As WiFi and BLE use the same radio, it could indeed return 'operation already in progress' error, as the radio is already in use by another process. Please disable the WiFi when using BLE and vice versa.
You check the 'on-boot' parameters as well:import pycom print('Heartbeat on boot: \t', pycom.heartbeat_on_boot()) print('WiFi on boot: \t\t', pycom.wifi_on_boot()) print('LTE modem on boot: \t', pycom.lte_modem_en_on_boot()) print('Pybytes on boot: \t', pycom.pybytes_on_boot()) print('Smart config on boot: \t', pycom.smart_config_on_boot()) print('Watchdog on boot: \t', pycom.wdt_on_boot())
If either Wifi, Pybytes (when using Pybytes on Wifi) or Smart config on boot are true, set them to 'False'
Let me know