Issues using Bluetooth with SiPy



  • I have been trying to use the SiPy board as a Bluetooth hub to read several devices with the same name and send the data from a specific characteristic via Sigfox and WiFi.

    As I said, I am using a SiPy board with:

    (sysname='SiPy', nodename='SiPy', release='1.6.13.b1', version='v1.8.6-607-g9c8a0e9e on 2017-05-01', machine='SiPy with ESP32', sigfox='1.0.1')
    

    The boot.py file sets up the WiFi connection:

    from machine import UART
    import os
    uart = UART(0, 115200)
    os.dupterm(uart)
    
    import machine
    from network import WLAN
    
    wlan = WLAN(mode=WLAN.STA)
    nets = wlan.scan()
    for net in nets:
        if net.ssid == 'NetName':
            wlan.connect(net.ssid, auth=(net.sec, 'Password'), timeout=5000)
            while not wlan.isconnected():
                machine.idle()
            break
    

    The main.py program is based in the examples in the documentation shown here, here and this forum topic.

    from network import Bluetooth
    import binascii
    import time
    import urequests
    import gc
    
    def digit_to_char(digit):
        if digit < 10: return chr(ord('0') + digit)
        else: return chr(ord('a') + digit - 10)
    
    def str_base(number,base):
        if number < 0:
            return '-' + str_base(-number,base)
        else:
            (d,m) = divmod(number,base)
            if d:
                return str_base(d,base) + digit_to_char(m)
            else:
                return digit_to_char(m)
    
    def password_generate(deviceID):
        a=devID[0]^0x50
        b=devID[1]^0x50
        c=devID[2]^0x50
        d=devID[3]^0x50
        e=devID[4]^0x50
        f=devID[5]^0x50
        g=devID[6]^0x50
        h=devID[7]^0x50
    
        password=a
        password=(password<<8)+b
        password=(password<<8)+c
        password=(password<<8)+d
        password=(password<<8)+e
        password=(password<<8)+f
        password=(password<<8)+g
        password=(password<<8)+h
    
        PASSb16=str_base(password, 16)
    
        return PASSb16
    
    while True:
        bluetooth = Bluetooth()
        devID=0
        bluetooth.start_scan(-1)
        adv = None
    
        while True:
            adv = bluetooth.get_adv()
            if adv and bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'DeviceName': 
                try:
                    conn=bluetooth.connect(adv.mac)
                    services = conn.services()
                    
                    for service in services:
                        time.sleep(0.050)
                        service.uuid()
                        chars = service.characteristics()
                        for char in chars:
                            if (char.properties() & Bluetooth.PROP_READ):
                                char.uuid()
                                if (char.uuid() == 10787):
                                    devID=char.read()
                                    print('DeviceID = {}'.format(binascii.hexlify(devID)))
                                    pword=password_generate(devID)
                                if devID:
                                    if (char.uuid() == 65521):
                                        char.write(binascii.unhexlify(pword))
                                        char1= binascii.hexlify(char.read())
                                        print('MagRead = '+str(char1))
                                        urequests.request("POST","http://requestb.in/1csszaw1",'{"DeviceID":'+str(binascii.hexlify(devID))+',"MagRead":'+str(char1)+'}').text
                    break
                except:
                    bluetooth.start_scan(-1)
                    continue
                break
        bluetooth.stop_scan()
        conn.disconnect()
        gc.collect()
    

    Running the program I got constant Guru Meditation Errors or freezes, so I decided to change the program so that it could connect to any device; going from:

     while True:
            adv = bluetooth.get_adv()
            if adv and bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'DeviceName': 
                try:
    

    to:

     while True:
            adv = bluetooth.get_adv()
            if adv: 
                try:
    

    This worked better but I still got the same problems as before.

    I then reduced the program to it basic functionality to find where exactly it was failing.

    from network import Bluetooth
    import time
    import gc
    
    bluetooth = Bluetooth()
    while True:
        bluetooth.start_scan(-1)
        adv = None
        while True:
            time.sleep(0.3)
            print('1')
            adv = bluetooth.get_adv()
            if adv and bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'DeviceName':
                print('22')
                try:
                    print('333')
                    conn=bluetooth.connect(adv.mac)
                    print('4444')
                    services = conn.services()
                    print('55555')
                except:
                    print('AAAAAA')
                    bluetooth.start_scan(-1)
                    continue
                break
        conn.disconnect()
        bluetooth.stop_scan()
        gc.collect()
    

    I found that most of the time the program would fail when trying to connect to the device or read the services. It also got stuck several times in the if statement not finding a device even when there was one advertising. It would also connect to the device and freeze, and after a soft reboot it would stay connected to the device.

    Am I doing something incorrectly? Should I try to optimize it further? Or is it a firmware/hardware issue?



  • @Jurassic-Pork @jmarcelino
    I tried it, and as far as I can see the result is the same.



  • @thrag

    The full program works like this:

    Running main.py
    BTDM CONTROLLER VERSION: 010101
    BTDM ROM VERSION 0101
    BD_ADDR: 24:0A:C4:00:FA:CA
    NVDS MAGIC FAILED
    RF Init OK with coex
    Enable Classic BT
    Enable Low Energy
    DeviceID = b'28dbafedff3ace00'
    MagRead = b'2e'
    

    After the first successful connection it gets stuck and doesn't connect to anything.

    The simplified version of the program:

    Running main.py
    BTDM CONTROLLER VERSION: 010101
    BTDM ROM VERSION 0101
    BD_ADDR: 24:0A:C4:00:FA:CA
    NVDS MAGIC FAILED
    RF Init OK with coex
    Enable Classic BT
    Enable Low Energy
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    22
    333
    4444
    AAAAAA
    1
    1
    1
    1
    1
    1
    1
    22
    333
    4444
    AAAAAA
    1
    22
    333
    4444
    AAAAAA
    1
    1
    1
    22
    333
    4444
    55555
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    ASSERT_PARAM(10 0), in lld_pdu.c at line 1260
    


  • @thrag
    I am using firmware version 1.6.13.b1.



  • @jmarcelino hi. It sounds like you have something working. Could you tell me the version of firmware you are using.

    Any chance you could share a snippet of working code?

    Thanks



  • @adg
    Try calling bluetooth.stop_scan() before the connect().



  • hello,
    @adg
    have you tried to stop scan before to connect to a bluetooth device ?

    if adv and bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'DeviceName':
                print('22')
                try:
                    bluetooth.stop_scan()
                    print('333')
    
    


Pycom on Twitter