Is it possible to use LoPy as BLE GATT_Server and GATT_Client at the same time?
-
Hi,
I'm working on a Farm Net project that tracking cows and build up their "social graph" for further research. I decided to use LoPy+Pytrack as the tracking and communication device for each cow. But right now I have one question about BLE module of LoPy:
Can I use LoPy as BLE GATT_Server and GATT_Client at the same time?
So the LoPy could advertise its device_id and also get the device_id from other LoPy, in this way I could build up a "social graph" for each cow.
Is it possible?
Because right now I have tested BLE communication between two LoPy, and each as GATT server and client at the same timeby merging the example code. The problem is when one node is connected to another one, the role of each device won't change anymore. The codes are shown below:- Server code:
#Global variables used in this file BLEConnectionCounter = 0 # count the connection by clients ################ BLE & LoRa Node ################ # This node will act as both BLE client and a # # LoRa node device # ################################################# ###### First, set up BLE server service ###### def BLEServer(): pycom.heartbeat(False) bluetooth = Bluetooth() #create a bluetooth object bluetooth.set_advertisement(name='LoPyServer'+str(globalvar.device_id), service_uuid=b'3333333333333333') #using callback conn_cb to check client's connection ##Function: conn_cb(callback for bluetooth object events checking) ##Description:check there is any client connected to the service def conn_cb (bt_o): events = bt_o.events()#using events to check if there is any client connected to the service if events & Bluetooth.CLIENT_CONNECTED:#2 print("Client connected") pycom.rgbled(0x007f00) # green elif events & Bluetooth.CLIENT_DISCONNECTED:#4 bt_o.disconnect_client()# in this way other client will have the chance to connect? print("Client disconnected") pycom.rgbled(0x7f0000) # red time.sleep(3) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) bluetooth.advertise(True) #set up BLE service srv1 = bluetooth.service(uuid=b'3333333333333333', isprimary=True) #set up service character chr1 = srv1.characteristic(uuid=b'3333333333333333', properties = Bluetooth.PROP_READ | Bluetooth.PROP_WRITE,value=5) def char1_cb_handler(chr): global BLEConnectionCounter events = chr.events() print('events is '+str(events)) if events & Bluetooth.CHAR_WRITE_EVENT:#16 print("Write request with value = {}".format(chr.value())) elif events & Bluetooth.CHAR_READ_EVENT:#8 #modify here to send its device_id to other clients BLEConnectionCounter += 1 return str(globalvar.device_id)+' '+str(BLEConnectionCounter) #using the callback to send the data to other clients chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler)
- Client code:
###### Second, initialize as one LoRa node device and BLE client ###### def BLEClient(): ###### set up BLE client service ###### bluetooth_client = Bluetooth() #bluetooth_client.init(id=0, mode=Bluetooth.BLE, antenna=None) bluetooth_client.start_scan(10) #server_name1 = bluetooth_client.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) counter = 50 #while True: while counter > 0: print(counter) counter -= 1 #Gets an named tuple with the advertisement data received during the scanning. #The structure is (mac, addr_type, adv_type, rssi, data) adv = bluetooth_client.get_adv() #if get a valid advertisement from one server if adv: server_name = bluetooth_client.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) if checkValidServer(server_name): try: #Opens a BLE connection with the device specified by the mac_addr argument conn = bluetooth_client.connect(adv.mac) services = conn.services() #Yunwei - it seems that only when the type of uuid is bytes then could read the data from server for service in services: time.sleep(0.050) if type(service.uuid()) == bytes: chars = service.characteristics() for char in chars: print('char properties is '+str(properties)) if (char.properties() & Bluetooth.PROP_READ): print('char {} value = {}'.format(char.uuid(), char.read())) #Use LoRa to send the data out #s.send(char.read()) time.sleep(2) if (char.properties() & Bluetooth.PROP_WRITE): print('write to server!') char.write(b'x02') time.sleep(2) #Yunwei #Give other clients the chance to connect conn.disconnect() time.sleep(3) bluetooth_client.start_scan(10) print('connected?',conn.isconnected()) time.sleep(3) except: print("Error while connecting or reading from the BLE device") time.sleep(1) if(bluetooth_client.isscanning()): bluetooth_client.stop_scan() bluetooth_client.deinit() time.sleep(1) bluetooth_client.init() time.sleep(1) bluetooth_client.start_scan(10) else: bluetooth_client.deinit() time.sleep(1) bluetooth_client.init() time.sleep(1) bluetooth_client.start_scan(10) print('Scan again') else: print('adv is None!') time.sleep(3) bluetooth_client.stop_scan() bluetooth_client.deinit() print('out of loop!')
The firmware version is:
sysname='LoPy', nodename='LoPy', release='1.17.5.b6', version='v1.8.6-849-56d00234 on 2018-05-18', machine='LoPy with ESP32', lorawan='1.0.2'Hope you guys could help me!