Object Oriented Programming in FiPy using Bluetooth node to node communication



  • We are attempting to achieve node to node communication via BLE. We've achieved communication when we wrote and uploaded a main file and no libraries onto each device. Currently, we are trying to use an objected oriented approach and have a separate Bluetooth class in order to simplify our main file. We are having trouble connecting to Bluetooth now(thes slave is not sending out advertisements), and we're wondering if it's a firmware issue, a python syntax issue, or an issue with our understanding of BLE communication between nodes. Below is our Bluetooth class: This is the same between the slave and the master.

    import time
    import pycom
    from network import Bluetooth
    
    class Bt:
        def __init__(self):
            self.bluetooth = Bluetooth()
            self.connection = None
            self.service = None
            self.characteristic = None
            self.sent_count = 0
    
        def connect_to_slave(self):
            connected = False
            while not connected:
                print("connecting to slave...?")
                self.bluetooth.stop_scan()
                self.bluetooth.start_scan(-1)
                advertisement = self.bluetooth.get_adv()
                if advertisement == None:
                    continue
                print(self.bluetooth.resolve_adv_data(advertisement.data, Bluetooth.ADV_NAME_CMPL))
                if advertisement and self.bluetooth.resolve_adv_data(advertisement.data, Bluetooth.ADV_NAME_CMPL) == 'SWYM_Pycom-Joseph':
                    connected = True
                    try:
                        self.connection = self.bluetooth.connect(advertisement.mac)
                        services = self.connection.services()
                        for service in services:
                            print("in for loop services")
                            if service.uuid() == b'1234567890123456':
                                print("service found")
                                chars = services.characteristics()
                                for char in chars:
                                    print("in for loop for chars")
                                    if char.uuid() == b'ab34567890123456':
                                        print("connected to slave")
                                        self.characteristic = char
                    except:
                        print("Error while connecting or reading from the BLE device")
    
        def send_data(self):
            try:
                message = 'BLE payload #{}'.format(self.sent_count)
                payload = bytes(message, 'utf-8')
                print("about to print")
                self.characteristic.write(payload)
                self.sent_count += 1
                change_led_color(0x00ff00) #green
                time.sleep(2)
            except OSError:
                self.connection = None
                print("Exit out of Bluetooth")
    
    	def is_connected(self):
    		if self.connection == None:
    			return False
    		return True
        #slave functions
        def conn_cb(self, bt_o):
            events = bt_o.events()
            if events & Bluetooth.CLIENT_CONNECTED:
                print("Pycom is connected")
                pycom.heartbeat(False)
                pycom.rgbled(0x3355ff)
                time.sleep(2)
            elif events & Bluetooth.CLIENT_DISCONNECTED:
                print("Pycom is disconnected")
                pycom.heartbeat(True)
                self.connection = None
    
        def advertise(self):
            self.bluetooth.set_advertisement(name='SWYM_Pycom-Joseph', service_uuid=b'1234567890123456')
            self.bluetooth.advertise(True)
            print("advertisement being sent")
            #pycom.rgbled(0xbb33ff)
            self.service = self.bluetooth.service(uuid= b'1234567890123456', isprimary=True)
            self.characteristic = self.service.characteristic(uuid=b'ab34567890123456', value=5)
    
        def char1_cb_handler(chr):
            #global bytesCount
            events = chr.events()
            # Bluetooth.CHAR_WRITE_EVENT might be a boolean flag indicating characteristic write event.
            if events & Bluetooth.CHAR_WRITE_EVENT:
                global counter_ble
                chrono.stop()
                print(chr.value().decode("utf-8") + "-Received, Counter: " + str(counter_ble))
                print(chrono.read_ms())
                chrono.reset()
                chrono.start()
            # Bluetooth.CHAR_READ_EVENT might be boolean flag indicating characteristic read event.
            elif events & Bluetooth.CHAR_READ_EVENT:
                print("Read request with value = {}".format(chr.value()))
    
        def register_callback(self):
            self.bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler = self.conn_cb)
    
        def write_callback(self):
            self.characteristic.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.char1_cb_handler)
    

    Below is our slave device's main:

    from bluetooth import Bt
    bluetooth = Bt()
    bluetooth.advertise()
    bluetooth.register_callback()
    bluetooth.write_callback()```
    
    

    Below is our master device's main:

    from bluetooth import Bt
    bluetooth = Bt()
    bluetooth.connect_to_slave()
    while True:
      bluetooth.send_data()
    

    Any input would be great! Thank you so much.



  • @dan said in Object Oriented Programming in FiPy using Bluetooth node to node communication:

    at are not supported

    Hello!
    Thank you so much for your response, it was extremely helpful. I'm having trouble understanding why the triggers are not supported. I feel as if I used it similarly to the example code in the link you posted. I'm getting the error "Unhandled exception in callback handler, TypeError: function takes 1 positional arguments but 2 were given." I thought that neither the trigger or handler was a positional argument rather keyword arguments. My code is very similar to the Documentation in https://docs.pycom.io/chapter/firmwareapi/pycom/network/bluetooth/gattscharacteristic.html
    Do you know what the problem may be?
    Thank you!



  • Hi @sunny,

    Indeed, your code doesn't seem to work. You don't need to stop and start the scan in the while not connected loop. I've removed lines 17-18 (stop & start scan) and started scanning just before the loop and stopped it before connected =True. Then it connected and crashed in send_data (line 48 at self.characteristic.write(payload)).

    You have a typo in line 32, chars = services.characteristics(). You need to use service not services.

    Then write_callback crashed (I think), you're using triggers, that are not supported. See the available options here

    Let me know if you're still having issues with it, or if you have any questions!


 

Hello World?

Pylife on Kickstarter - November 2018








Back Us On Kickstarter >

Pycom on Twitter