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


Log in to reply
 

Pycom on Twitter