Random BLE connection Issues



  • Hi,

    I'm creating a BLE (and maybe WiFi) to LoRAWan Gateway using a FiPy.

    The idea is the following: connect the FiPy as Client to many BLE nodes (I use many devices as BLE servers: a classic ESP32, another LoPy4 and a Texas Instruments Sensor Node), collects the DATA associated to the target UUID, put them together with a proper parsing system in order to include both MAC address and data (I think I'll switch to LPPCayenne), and send them over LoRAWan using the ABP example provided from Pycom.

    All works - quite - fine, but there is an issues: sometimes, I don't know why, the FiPy board which act as BLE GW got stuck while connecting to any other client. It can happen many times in a minute or it can run also for one hour without issues. I have to implement a WatchDog to reset the board after 60 seconds when it gets stuck in this way, because there aren't other way to exit from this "blocking function". Unfortunately I can't find a solution. I tried many things but I can't figure out.

    Here you can find my code:

    """ OTAA Node example compatible with the LoPy Nano Gateway """
    
    from network import WLAN
    from network import LoRa
    from network import Bluetooth
    from machine import Pin
    from machine import WDT
    from util import BluetoothUuid
    import machine
    #import bme280_float
    import socket
    import ubinascii
    import struct
    import micropython
    import time
    import json
    
    # Init WhatchDog
    wdt = WDT(timeout=60000)  # enable it with a timeout of 30 seconds
    
    # Initialize I2C and BME280 sensor.
    i2c = machine.I2C(0,pins=('P23','P22'))
    #bme = bme280_float.BME280(i2c=i2c)
    
    # bluetooth definition
    bluetooth = Bluetooth()
    bluetooth.init(antenna=Bluetooth.INT_ANT)
    
    # Initialize LoRa in LORAWAN mode.
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
    
    # create and configure as an access point
    wlan = WLAN(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'1234567890'), channel=8, antenna=WLAN.EXT_ANT)
    Pin('P12', mode=Pin.OUT)(True)
    
    # create an ABP authentication params
    dev_addr = struct.unpack(">l", ubinascii.unhexlify('xxx'))[0] # these settings can be found from TTN
    nwk_swkey = ubinascii.unhexlify('xxx') # these settings can be found from TTN
    app_swkey = ubinascii.unhexlify('xxx') # these settings can be found from TTN
    
    # join a network using ABP (Activation By Personalisation)
    lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
    
    # remove all the non-default channels
    for i in range(3, 16):
        lora.remove_channel(i)
    
    # set the 3 default channels to the same frequency
    lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5)
    lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5)
    lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5)
    
    # create a LoRa socket
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    
    # set the LoRaWAN data rate
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
    
    time.sleep(5.0)
    
    """ Your own code can be written below! """
    # start scanning with no timeout
    target0=ubinascii.unhexlify(b'cc50e39c5d46')
    target1=ubinascii.unhexlify(b'30aea443d5ea')
    target2=ubinascii.unhexlify(b'68c90b067b8f')
    target3=ubinascii.unhexlify(b'30aea4754fd2')
    target = {target1,target2,target3}
    
    # Mac Address Array
    blescanmac = []
    
    while True:
        #create mac address array
        blescanmac.clear()
        print("Scanning BLE devices")
        bluetooth.start_scan(5)
        t_end = time.time() + 6
        while time.time() < t_end:             
            #collect adv packet from BLE scan
            adv=bluetooth.get_adv()
            #if there are ADV packets
            if adv:
                print(".")
                #obluetoothain Mac Address
                mac=ubinascii.hexlify(adv.mac)
                #chekc if I already have it in Mac array
                blescanmac.append(mac) 
        
        #Print Scan result
        blescanmac = list(dict.fromkeys(blescanmac))
        print("Number of detected BLE devices: "+ str(len(blescanmac)))
        print("BLE Mac Addresses: ")
        print(blescanmac)
    
        #Feed WatchDog 
        wdt.feed()
        #Create Array for Data
        bledata = []
        #Try to enstablish connection
        #for dev in target:
        for dev in blescanmac:
            #print('Try to connet to {}'.format(ubinascii.hexlify(dev)))
            print('Try to connet to {}'.format(dev))
            time.sleep(0.050)
            #if ubinascii.hexlify(dev) in blescanmac:
            if dev in blescanmac:           
                try:
                    #conn = bluetooth.connect(dev)
                    conn = bluetooth.connect(ubinascii.unhexlify(dev))
                    print('Connected to {}'.format(dev))
                    services = conn.services()
                    print('Look for services')
                    #print(services)
                    time.sleep(0.050)
                    
                    for service in services:
                        #servS=BluetoothUuid.from_bytes_le(service.uuid())
                        #print(servive.instance())
                        #print('service found: {}'.format(BluetoothUuid.from_bytes_le(service)))
                        print('Check if there is my service')
                        if (service.uuid()==b'74\xb54\x1a<\xb4\x99\x16H\xb8\x85\xb1Y\xe4\xc8'):
                            chars = service.characteristics()
                            #bledata.append(ubinascii.hexlify(dev).decode('UTF-8'))
                            bledata.append(dev.decode('UTF-8'))
                            bledata.append("*")
                            time.sleep(0.050)                     
                            for char in chars:
                                if (char.properties() & Bluetooth.PROP_READ):
                                    print('char {} value = {}'.format(BluetoothUuid.from_bytes_le(char.uuid()), char.read()))
                                    bledata.append(char.read().decode('UTF-8'))
                                    bledata.append("&")
                        else:
                            print("Desidered service not found!")
    
                    time.sleep(0.050)
                    conn.disconnect()
                except:
                    print("Error while connecting or reading from the BLE device")
            else:
                print("BLE device not found")
    
        print("BLE devices retrived data:")
        print(bledata)
        #result=json.dumps(bme.values)
        result="test"
        payload = ''.join([str(elem) for elem in bledata]) 
        pkt = b'{}'.format(bledata)
        
        if len(payload)>1:
            print('Sending:', payload)
            s.send(payload)
        else:
            print("Nothing to send!")
        #Feed WatchDog 
        wdt.feed()
        time.sleep(15)
        print('Giro di boa!')
    
    

    PS: The BLE servers are quite reliable, since I have no issues connecting to them as client using many smartphones. Also, one of them is a final product by Texas Instruments, however I have the same issues also with this device.

    Anyone can help me? thanks


Log in to reply
 

Pycom on Twitter