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