Connecting GPy to Blynk using BLE



  • Hi all - first post here, please excuse if I use the wrong terminology in places.

    I'm trying to connect my pycom GPy to Blynk over BLE. I am using the Blynk library from @vskymanskyy shown here. The WiFi side of things works perfect, I'm trying to translate those successful connection steps over to BLE. I've tried modifying the BLE code provided all sorts of ways, but can never seem to get the GPy to subscription to 'complete' - The button in Blynk never goes past 'Connecting...'. I am a receiving a subscription notification, which either returns blank (most of the time), or sometimes returns the first/second 20 bits of my Auth key. I can actually read/write to the Blynk client, but it seems to time out after 2 seconds as I never 'fully' subscribe somehow. I've tried sending the blynk connection commands all sorts of ways, no result. Please see the latest version of my code before. The library blynklib remains unchanged, except that I removed the login send command from the _connect function and moved it here.

    from network import Bluetooth
    from binascii import unhexlify
    from BlynkLib import BlynkProtocol
    import machine, time
    import struct
    
    BLYNK_AUTH = 'Qqf94Ym7hetRt0jI7PkX9pIZBNVC_5Io'
    
    def unhex(s):
        return bytes(reversed(unhexlify(s.replace('-',''))))
    
    class BlynkBLE(BlynkProtocol):
        def __init__(self, auth, **kwargs):
            self.bout = b''
            BlynkProtocol.__init__(self, auth, **kwargs)
    
        def connect(self):
            print('BLE connect')
            bluetooth = Bluetooth()
            bluetooth.set_advertisement(name='Blynk')
    
            def conn_cb(bt):
                events = bt.events()
                if  events & Bluetooth.CLIENT_CONNECTED:
                    self.bout = b''
                    print("Client connected")
                    time.sleep(0.05)
                    self.tx.value(b'\x1d\x00\x01\x00 Qqf94Ym7hetRt0j') #Send over BLE
                    self.tx.value(b'I7PkX9pIZBNVC_5Io')
                elif events & Bluetooth.CLIENT_DISCONNECTED:
                    print("Client disconnected")
                    BlynkProtocol.disconnect(self)
    
            bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
    
            nus = bluetooth.service(uuid=unhex('6E400001-B5A3-F393-E0A9-E50E24DCCA9E'), isprimary=True, nbr_chars=2)
            self.rx = nus.characteristic(uuid=unhex('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'),
                                         properties=Bluetooth.PROP_WRITE | Bluetooth.PROP_WRITE_NR,
                                         value='')
            self.tx = nus.characteristic(uuid=unhex('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'),
                                         properties=Bluetooth.PROP_READ | Bluetooth.PROP_NOTIFY,
                                         value='')
    
            bluetooth.advertise(True)
    
            def rx_cb(chr):
                data = chr.value()
                print('BLE data received')
                print('>', data)
                cmd, i, dlen = struct.unpack("!BHH", data[:5]) #Unpack the data in self.bins
                if cmd == 2 or cmd > 64:
                    #self._send(6)
                    print('connect send')
                    self.tx.value(b'\x1d\x00\x01\x00 Qqf94Ym7hetRt0j') #Send over BLE
                    self.tx.value(b'I7PkX9pIZBNVC_5Io')
                self.process_BLE(bytes(data))
                #self.process(bytes(data))
    
            def tx_subsc(chr):
                print("Client subscribed", chr.value())
                BlynkProtocol.connect(self)
    
            self.tx.callback(trigger=Bluetooth.CHAR_SUBSCRIBE_EVENT, handler=tx_subsc)
            self.rx.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=rx_cb)
    
        def process_BLE(self, data):
            cmd1, id1, dlen1 = struct.unpack("!BHH", data[:5]) #Unpack the data in self.bins
            print('command:',cmd1,',id:',id1,'dlen:',dlen1)
            if cmd1 > 64 or cmd1 == 2:
                msg = struct.pack("!BHH", 6, 1, 0)
                print('msg:',msg)
            elif cmd1 == 0 and id1 > 1:
                msg = struct.pack("!BHH", 6, id1+1, 0)
            elif cmd1 == 0 and id1 == 1:
                msg = b'\x11\x00\x02\x00+ver\x000.2.0\x00h-beat\x0010\x00buff-in\x001024\x00dev\x00python'
    
            while len(msg):
                data = msg[:20]
                msg = msg[20:]
                print('BLE data send:')
                print('<', data)
                self.tx.value(data)
    
        def _write(self, data):
            self.bout += data
    
        def run(self):
            #self.process()
    
            while len(self.bout):
                data = self.bout[:20]
                self.bout = self.bout[20:]
                print('BLE data send, run loop:')
                print('<', data)
                self.tx.value(data)
    
    blynk = BlynkBLE(BLYNK_AUTH)
    
    @blynk.ON("connected")
    def blynk_connected(ping):
        print('Blynk ready. Ping:', ping, 'ms')
    
    def runLoop():
        print('run loop')
        while True:
            blynk.run()
            time.sleep(0.1)
            #machine.idle()
    
    # Run blynk in the main thread:
    runLoop()
    

    The following gets returned:

    BLynk Protocol Init Start
    BLE connect
    BLynk Protocol Init End
    INIT:BlynkProtocol.ON()
    <function blynk_connected at 0x3f9b0c60>
    connected
    {'connected': <function blynk_connected at 0x3f9b0c60>}
    run loop
    Client connected
    Client subscribed b'\x06\x02r\x00\x00'
    BLynk Protocol Connect Start
    BLE data received
    > b'I7PkX9pIZBNVC_5Io'
    connect send
    command: 73 ,id: 14160 dlen: 27480
    msg: b'\x06\x00\x01\x00\x00'
    BLE data send:
    < b'\x06\x00\x01\x00\x00'
    BLE data received
    > b'\x00\x02r\x00\xc8'
    command: 0 ,id: 626 dlen: 200
    BLE data send:
    < b'\x06\x02s\x00\x00'
    BLE data received
    > b'\x00\x02r\x00\xc8'
    command: 0 ,id: 626 dlen: 200
    BLE data send:
    < b'\x06\x02s\x00\x00'
    BLE data received
    > b'\x00\x00\x01\x00\xc8'
    command: 0 ,id: 1 dlen: 200
    BLE data send:
    < b'\x11\x00\x02\x00+ver\x000.2.0\x00h-bea'
    BLE data send:
    < b't\x0010\x00buff-in\x001024\x00de'
    BLE data send:
    < b'v\x00python'
    BLE data received
    > b'\x00\x02s\x00\xc8'
    command: 0 ,id: 627 dlen: 200
    BLE data send:
    < b'\x06\x02t\x00\x00'
    BLE data received
    > b'\x00\x02s\x00\xc8'
    command: 0 ,id: 627 dlen: 200
    BLE data send:
    < b'\x06\x02t\x00\x00'
    BLE data received
    > b'\x00\x00\x02\x00\xc8'
    command: 0 ,id: 2 dlen: 200
    BLE data send:
    

    As you can see, it seems to connect, but weirdly. It continues on like this for a few seconds and then disconnects. I've combed through all the forums, I've tried pinging this thing 100 different ways and in different boot up sequences. Any help would be greatly appreciated.


Log in to reply
 

Pycom on Twitter