You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The LED Glasses driver nRF52840 using CircuitPython connects to a BLE light bulb and controls it well for 25 seconds, but after 25 seconds it seems to hang the next time a characteristic is accessed. There isn't any Exception, but the code stops running and Ctrl-C doesn't give a REPL prompt. The only way to recover is to reset the CPU.
If after 25 seconds, I call connect() again before accessing a characteristic, it usually works properly.
In case it helps to note, there's a hack in my pair() below to force a call to _discover_remote(). I imagine there's a more proper procedure.
The MAC address of the peripheral is hard-coded (but redacted) into the central's code below.
The code in the BLE peripheral is closed source, so I can't change it.
Are there any further experiments that could help narrow down the cause of this? I'd like to be able to connect to multiple peripherals (with the same UUID), but the pairing fails if I keep re-executing connect() on different peripherals.
import time
from time import sleep
import board
from _bleio import Address
from adafruit_ble import BLERadio, BLEConnection
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement,SolicitServicesAdvertisement, Advertisement
from adafruit_ble.uuid import VendorUUID, UUID
from adafruit_ble.services import Service
from adafruit_ble.characteristics import Characteristic
from adafruit_ble.characteristics.int import Uint8Characteristic, Uint16Characteristic
from adafruit_ble.attributes import Attribute
from adafruit_ble.uuid import VendorUUID, UUID
class HueService(Service):
"""Service that allows for setting the power, brightness and color"""
uuid = VendorUUID("932c32bd-0000-47a2-835a-a8d455b859dd")
#rwproperties=Characteristic.READ|Characteristic.WRITE|Characteristic.NOTIFY|Characteristic.WRITE_NO_RESPONSE,
brightness = Uint8Characteristic(
uuid=VendorUUID("932c32bd-0003-47a2-835a-a8d455b859dd"),
properties=Characteristic.READ|Characteristic.WRITE,
read_perm = Attribute.OPEN,
write_perm=Attribute.LESC_ENCRYPT_WITH_MITM)
class HueLight():
HUEserviceUUID = VendorUUID("932c32bd-0000-47a2-835a-a8d455b859dd")
#Basic note: variables defined here are shared by all instances
#scanning happens on the one BLERadio(), but connections are per instance
ble = BLERadio()
address_list = []
def __init__(self,address):
self.light_connection = None #BLEConnection()
#convert an int to a byte array
if isinstance(address,int): #address is integer
self.address_bytes = address.to_bytes(6,"little")
else:
self.address_bytes = bytes(address)
#print("init address",self.address_bytes)
#keep track of all lights
self.address_list.append(self.address_bytes)
self.index=len(self.address_list)-1
#self.connect()
def connect(self,pair=True):
#peer_address=Address(int(self.address_bytes).to_bytes(6,"little"))
if self.light_connection is not None:
print("Warning: light_connection is",self.light_connection)
self.light_connection = self.ble.connect(Address(self.address_bytes,1))
#TODO try without pairing after initial pair
if pair:
print("Checking pairing")
if not self.light_connection.paired:
self.pair()
else:
print("Already paired")
print("Connected?",self.light_connection.connected)
print("bonded?",self.light_connection.paired)
def connect_to_advertisement(self):
print("Index:",self.index)
if not self.light_connection or not self.light_connection.paired:
print("Scanning for {}...".format(self.address_bytes))
advertisements=SolicitServicesAdvertisement()
advertisements.solicited_services.append(HueService)
for adv in self.ble.start_scan(timeout=60):
if adv.address.address_bytes == self.address_bytes:
self.light_connection = self.ble.connect(adv)
if not self.light_connection.paired:
self.pair()
else:
print("Already paired")
self.ble.stop_scan()
break
self.ble.stop_scan()
def pair(self):
#this uuid is arbitrary
uuid = VendorUUID("932c32bd-0002-47a2-835a-a8d455b859dd")
#just need to run __contains__ which runs _discover_remote()
if uuid in self.light_connection:
pass
#self.light_connection._discover_remote(uuid)
print("Bonding...")
try:
self.light_connection.pair()
except Exception as err:
print("Error in pairing: {}".format(err))
if self.light_connection.paired:
print("Paired")
def connected(self):
return self.light_connection.connected
def disconnect(self):
self.light_connection.disconnect()
def get_brightness(self):
return self.light_connection[HueService].brightness
def set_brightness(self,brightness):
self.light_connection[HueService].brightness=brightness
ambient2=HueLight(0xfedcba098765) #set to real MAC address of peripheral
ambient2.connect_to_advertisement()
read_brightness=ambient2.get_brightness()
new_brightness=((read_brightness+100) % 230) +20
ambient2.set_brightness(new_brightness)
print("Set to",new_brightness)
sleep(29)
print("Connected?",ambient2.connected())
#Try uncommending the line below to avoid system hanging <-----------------------------------
#ambient2.connect()
print("If connect() is not called after the sleep, the system will hang here.")
read_brightness=ambient2.get_brightness()
print("Got brightness")
new_brightness=((read_brightness+100) % 230) +20
ambient2.set_brightness(new_brightness)
print("Set to",new_brightness)
sleep(1)
read_brightness=ambient2.get_brightness()
print("Current brightness",read_brightness)
#ambient2.connect()
ambient2.disconnect()
The text was updated successfully, but these errors were encountered:
The LED Glasses driver nRF52840 using CircuitPython connects to a BLE light bulb and controls it well for 25 seconds, but after 25 seconds it seems to hang the next time a characteristic is accessed. There isn't any Exception, but the code stops running and Ctrl-C doesn't give a REPL prompt. The only way to recover is to reset the CPU.
If after 25 seconds, I call connect() again before accessing a characteristic, it usually works properly.
In case it helps to note, there's a hack in my pair() below to force a call to _discover_remote(). I imagine there's a more proper procedure.
The MAC address of the peripheral is hard-coded (but redacted) into the central's code below.
The code in the BLE peripheral is closed source, so I can't change it.
Are there any further experiments that could help narrow down the cause of this? I'd like to be able to connect to multiple peripherals (with the same UUID), but the pairing fails if I keep re-executing connect() on different peripherals.
The text was updated successfully, but these errors were encountered: