Beispiel #1
0
    def isOwnerNearby(self):
        '''
        Logic here checks if a known BLE device is broadcasting nearby.
        If they are, return true. Else, return false
        '''
        # TODO remove
        return False
        bt = Bluetooth()
        bt.start_scan(ConfigBluetooth.SCAN_ALLOW_TIME)  # Scans for 10 seconds

        while bt.isscanning():
            adv = bt.get_adv()
            if adv and binascii.hexlify(adv.mac) == ConfigBluetooth.MAC_ADDR:
                try:
                    if self.debug:
                        print("Owner device found: {} Mac addr {}".format(
                            bt.resolve_adv_data(adv.data,
                                                Bluetooth.ADV_NAME_CMPL),
                            ConfigBluetooth.MAC_ADDR))
                    conn = bt.connect(adv.mac)
                    time.sleep(0.05)
                    conn.disconnect()
                    bt.stop_scan()
                except Exception:
                    bt.stop_scan()

                return True

            time.sleep(0.050)

        return False
Beispiel #2
0
def initConnection(address):
    pycom.rgbled(0xffff00)
    pycom.heartbeat(False)
    bluetooth = Bluetooth()
    bluetooth.start_scan(-1)
    bluetooth.init()
    while True:
        print("starting bluetooth")
        global connection
        devices = bluetooth.get_advertisements()
        try:
            if devices is not None and len(devices) > 0:
                for device in devices:
                    uuid = ubinascii.hexlify(device.mac)
                    if (str(uuid) == address):
                        print("foud the arduino")

                        connection = bluetooth.connect(device.mac)
                        print(device)

                        bluetooth.stop_scan()
                        global char
                        char = getBleChar()
                        pycom.rgbled(0x00ff00)
                        return device
        except:
            print("arduino refused connection trying again")
            pycom.heartbeat(True)
            closeConnection()
            continue
        time.sleep(0.05)
    pycom.rgbled(0xff0000)
    return None
Beispiel #3
0
def isBTDeviceNearby():
    bt = Bluetooth()

    while True:
        print("Scanning for owner BT device nearby...")
        bt.start_scan(10)  # Scans for 10 seconds

        while bt.isscanning():
            adv = bt.get_adv()
            if adv and binascii.hexlify(adv.mac) == ConfigBluetooth.MAC_ADDR:
                try:
                    print("Owner device found: {} Mac addr {}".format(
                        bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL),
                        ConfigBluetooth.MAC_ADDR))
                    conn = bt.connect(adv.mac)
                    time.sleep(0.05)
                    conn.disconnect()
                    bt.stop_scan()
                except Exception as e:
                    print("Exception {}".format(e))
                    bt.stop_scan()
                    break
            else:
                time.sleep(0.050)
Beispiel #4
0
    if adv:
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_NAME_CMPL))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_NAME_SHORT))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_FLAG))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_16SRV_PART))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_T16SRV_CMPL))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_32SRV_PART))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_32SRV_CMPL))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_128SRV_PART))
        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_128SRV_CMPL))

        print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_TX_PWR))
    time.sleep(4)
    if adv and bt.resolve_adv_data(adv.data,
                                   Bluetooth.ADV_NAME_CMPL) == 'Heart Rate':
        conn = bt.connect(adv.mac)
        services = conn.services()
        for service in services:
            time.sleep(0.050)
            if type(service.uuid()) == bytes:
                print('Reading chars from service = {}'.format(service.uuid()))
            else:
                print('Reading chars from service = %x' % service.uuid())
            chars = service.characteristics()
            for char in chars:
                if (char.properties() & Bluetooth.PROP_READ):
                    print('char {} value = {}'.format(char.uuid(),
                                                      char.read()))
        conn.disconnect()
        break
    else:
Beispiel #5
0
from machine import RTC

bluetooth = Bluetooth()
bluetooth.set_advertisement(name="lopy2", manufacturer_data="lopy_v2")
bluetooth.start_scan(
    -1)  #Change to 10 to have it searching for 10 sec instead if forever
#bluetooth.stop_scan()
adv = None
bluetooth.advertise(True)
while True:
    adv = bluetooth.get_adv()
    if adv and bluetooth.resolve_adv_data(adv.data,
                                          Bluetooth.ADV_NAME_CMPL) == 'lopy1':

        try:
            bluetooth.connect(adv.mac)

            print(
                bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_APPEARANCE))
            print("Connected to device with addr = {}".format(
                binascii.hexlify(adv.mac)))

            #bluetooth.connect(adv.mac)
            pycom.heartbeat(False)
            for cycles in range(1):  # stop after 1 cycles
                pycom.rgbled(0x000080)  # blue
                time.sleep(0.5)
                pycom.rgbled(0x000000)  # blue
                time.sleep(0.5)
                pycom.rgbled(0x000080)  # blue
                time.sleep(0.5)
Beispiel #6
0
def BLEAndLoRaFun():
    ###### First, initialize as one LoRa node device ######
    # initialize LoRa in LORAWAN mode.
    # Please pick the region that matches where you are using the device:
    # Asia = LoRa.AS923
    # Australia = LoRa.AU915
    # Europe = LoRa.EU868
    # United States = LoRa.US915
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)

    # create an ABP authentication params
    dev_addr = struct.unpack(">l", binascii.unhexlify('26021A14'))[0]
    nwk_swkey = binascii.unhexlify('BB515D851353D2AB5ACCD112F0F2C597')
    app_swkey = binascii.unhexlify('B74092CB7C5A79CAD681C384ABF925D2')

    # remove all the channels
    for channel in range(0, 72):
        lora.remove_channel(channel)

    # set all channels to the same frequency (must be before sending the OTAA join request)
    for channel in range(0, 72):
        lora.add_channel(channel,
                         frequency=config.LORA_FREQUENCY,
                         dr_min=0,
                         dr_max=3)

    # join a network using ABP (Activation By Personalization)
    lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))

    # create a LoRa socket
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)

    # set the LoRaWAN data rate
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)  # last parameter is 3

    # make the socket non-blocking
    s.setblocking(False)
    '''
	###### Second, set up BLE server service ######
    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:
            print("Client connected")
            pycom.rgbled(0x007f00) # green
        elif events & Bluetooth.CLIENT_DISCONNECTED:
            bt_o.disconnect_client()
            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', value=5)
    #char1_read_counter = 0
    def char1_cb_handler(chr):
        #global char1_read_counter
        #char1_read_counter += 1
        global BLEConnectionCounter
        events = chr.events()
        if  events & Bluetooth.CHAR_WRITE_EVENT:
            print("Write request with value = {}".format(chr.value()))
        else:
            #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
    char1_cb = chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler)
	'''
    ###### Third, 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()
        #servermac = ''#save the serer mac
        #use resolve_adv_data to resolve the 31 bytes of the advertisement message
        #Here is problem: when disconnect from server, then adv will always be null...

        #if get a valid advertisement from one server
        if adv:
            server_name = bluetooth_client.resolve_adv_data(
                adv.data, Bluetooth.ADV_NAME_CMPL)
            #print(server_name)
            if checkValidServer(server_name):
                try:
                    #Opens a BLE connection with the device specified by the mac_addr argument
                    #This function blocks until the connection succeeds or fails.
                    #print(adv.mac)
                    #global servermac#change servermac to global
                    #servermac = adv.mac
                    #counter += 1
                    conn = bluetooth_client.connect(adv.mac)
                    #print('connected?',conn.isconnected())
                    services = conn.services()
                    #print('This is service',services)
                    #print(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:
                                #check if the character properties is PROP_READ
                                properties = char.properties()
                                print('char properties is ' + str(properties))
                                if (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)
                                #10 & Bluetooth.PROP_WRITE
                                #10&Bluetooth.PROP_READ
                                if (properties & Bluetooth.PROP_WRITE):
                                    print('write to server!')
                                    char.write(b'x02')
                                    time.sleep(2)
                    #Yunwei
                    conn.disconnect()
                    #bluetooth_client.deinit()
                    bluetooth_client.stop_scan()
                    time.sleep(3)
                    bluetooth_client.deinit()
                    print('deinit')
                    time.sleep(3)
                    bluetooth_client.init()
                    #if(bluetooth_client.isscanning()):
                    #    bluetooth_client.stop_scan()
                    #bluetooth_client.deinit()
                    bluetooth_client.start_scan(10)
                    print('connected?', conn.isconnected())
                    #break
                    time.sleep(3)
                    gc.collect()
                    #if it's still scan, then need to stop scan first
                    #bluetooth_client.start_scan(-1)
                    '''
                    if(bluetooth_client.isscanning()):
                        bluetooth_client.stop_scan()
                        #then scan again
                        bluetooth_client.start_scan(-1)
                    '''
                except:
                    print(
                        "Error while connecting or reading from the BLE device"
                    )
                    #break
                    time.sleep(1)
                    if (bluetooth_client.isscanning()):
                        bluetooth_client.stop_scan()
                        bluetooth_client.deinit()
                        time.sleep(1)
                        bluetooth_client.deinit()
                        time.sleep(1)
                        #init again
                        bluetooth_client.init(id=0,
                                              mode=Bluetooth.BLE,
                                              antenna=None)
                        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)
            '''
            time.sleep(3)
            #if it's still scan, then need to stop scan first
            if(bluetooth_client.isscanning()):
                bluetooth_client.stop_scan()
                #then scan again
                bluetooth_client.start_scan(-1)
            '''
    #bluetooth_client.stop_scan()
    bluetooth_client.stop_scan()
    bluetooth_client.deinit()
    print('out of loop!')
def BLEClient():
    #Description: check if the BLE server is set up by another LoPy
    #Note: for convention reason, the LoPy server name will be "LoPyServer"+device_id
    def checkValidServer(server_name):
        if (server_name == None): return False
        else:
            #check if server_name contains "LoPyServer"
            if (re.match('LoPyServer*', server_name)):
                return True
            else:
                return False

    global rec_msg
    ###### Third, set up BLE client service ######
    bluetooth_client = Bluetooth()
    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:

        #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()
        #servermac = ''#save the serer mac
        #use resolve_adv_data to resolve the 31 bytes of the advertisement message
        #Here is problem: when disconnect from server, then adv will always be null...

        #if get a valid advertisement from one server
        if adv:
            server_name = bluetooth_client.resolve_adv_data(
                adv.data, Bluetooth.ADV_NAME_CMPL)
            #print(server_name)
            if checkValidServer(server_name):
                try:
                    #Opens a BLE connection with the device specified by the mac_addr argument
                    #This function blocks until the connection succeeds or fails.
                    #print(adv.mac)
                    #global servermac#change servermac to global
                    #servermac = adv.mac
                    #counter += 1
                    conn = bluetooth_client.connect(adv.mac)
                    #print('connected?',conn.isconnected())
                    services = conn.services()
                    #print('This is service',services)
                    #print(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:
                                #check if the character properties is PROP_READ
                                if (char.properties() & Bluetooth.PROP_READ):
                                    print('char {} value = {}'.format(
                                        char.uuid(), char.read()))
                                    #create lora msg
                                    rec_msg = str(char.read())
                                    counter -= 1
                                    #Use LoRa to send the data out
                                    #s.send(char.read())
                                    time.sleep(5)
                    #Yunwei
                    conn.disconnect()
                    print('connected?', conn.isconnected())
                    #break
                    time.sleep(3)
                    gc.collect()
                    bluetooth_client.start_scan(10)
                except:
                    print(
                        "Error while connecting or reading from the BLE device"
                    )
                    #break
                    time.sleep(1)
                    if (bluetooth_client.isscanning()):
                        bluetooth_client.stop_scan()
                        bluetooth_client.deinit()
                        time.sleep(1)
                        bluetooth_client.init()
                        time.sleep(1)
                        #init again
                        #bluetooth_client.init(id=0, mode=Bluetooth.BLE, antenna=None)
                        bluetooth_client.start_scan(10)
                    else:
                        bluetooth_client.deinit()
                        time.sleep(1)
                        bluetooth_client.init()
                        time.sleep(1)
                        bluetooth_client.start_scan(10)
    bluetooth_client.stop_scan()
    bluetooth_client.deinit()
class BluetoothApi:
    """Many examples integrated from
    https://microchipdeveloper.com/wireless:ble-gatt-data-organization
    https://development.pycom.io/firmwareapi/pycom/network/bluetooth/
    https://github.com/sandeepmistry/arduino-BLEPeripheral
    https://github.com/kriswiner/nRF52832DevBoard/blob/master/BMP280_nRF52.ino
    
    https://forum.pycom.io/topic/2826/how-to-send-data-to-characteristic-over-ble/17


    """
    def __init__(self):
        self.bt = None

    def start(self):
        """ """

        print('Starting Bluetooth')
        self.bt = Bluetooth()

        # Default
        #self.bt.init(id=0, mode=Bluetooth.BLE, antenna=Bluetooth.INT_ANT, modem_sleep=True)
        #self.bt.init(id=0, antenna=Bluetooth.INT_ANT, modem_sleep=False)
        self.bt.init(modem_sleep=False)

        return

        print('Entering main loop')
        while True:
            print('--- loop ---')

            adv = self.bt.get_adv()
            print('adv:', adv)

            # Give the system some breath.
            print('machine.idle()')
            machine.idle()

            utime.sleep(10.0)
            continue

    def scan(self, duration):
        """

        :param duration: 

        """
        duration = int(duration)
        print('Starting Bluetooth scan for {} seconds'.format(duration))
        self.bt.start_scan(duration)
        while self.bt.isscanning():
            #print('is-scanning')
            adv = self.bt.get_adv()
            if adv:
                # try to get the complete name
                name_short = self.bt.resolve_adv_data(adv.data,
                                                      Bluetooth.ADV_NAME_SHORT)
                name_complete = self.bt.resolve_adv_data(
                    adv.data, Bluetooth.ADV_NAME_CMPL)
                print('names:', name_short, name_complete)

                service_data = self.bt.resolve_adv_data(
                    adv.data, Bluetooth.ADV_SERVICE_DATA)
                print('service_data:', service_data)

                mfg_data = self.bt.resolve_adv_data(
                    adv.data, Bluetooth.ADV_MANUFACTURER_DATA)
                if mfg_data:
                    # try to get the manufacturer data (Apple's iBeacon data is sent here)
                    data = ubinascii.hexlify(mfg_data)
                    print('data:', data)

        print('Bluetooth scanning stopped')

    def find_heart_rate(self):
        """ """
        adv = self.bt.get_adv()
        if adv and self.bt.resolve_adv_data(
                adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate':
            try:
                conn = self.bt.connect(adv.mac, timeout=5000)
                services = conn.services()
                for service in services:
                    utime.sleep(0.050)
                    if type(service.uuid()) == bytes:
                        print('Reading chars from service = {}'.format(
                            service.uuid()))
                    else:
                        print('Reading chars from service = %x' %
                              service.uuid())
                    chars = service.characteristics()
                    for char in chars:
                        if (char.properties() & Bluetooth.PROP_READ):
                            print('char {} value = {}'.format(
                                char.uuid(), char.read()))
                conn.disconnect()
            except:
                print("Error while connecting or reading from the BLE device")
        else:
            utime.sleep(0.050)

        utime.sleep(10.0)

    def advertise(self):
        """https://development.pycom.io/firmwareapi/pycom/network/bluetooth/"""

        device_name = get_device_name()
        print('Advertising device {}'.format(device_name))
        # TODO: Get from settings
        self.bt.set_advertisement(name=device_name,
                                  service_uuid=b'1234567890123456')

        def conn_cb(bt_o):
            """

            :param bt_o: 

            """
            print("Callback happened")
            # Returns flags and clear internal registry
            events = bt_o.events()
            if events & Bluetooth.CLIENT_CONNECTED:
                print("Client connected:", events)
            elif events & Bluetooth.CLIENT_DISCONNECTED:
                print("Client disconnected")

        self.bt.callback(trigger=Bluetooth.CLIENT_CONNECTED
                         | Bluetooth.CLIENT_DISCONNECTED,
                         handler=conn_cb)

        self.bt.advertise(True)

    def start_service(self):
        """https://development.pycom.io/firmwareapi/pycom/network/bluetooth/gattsservice/
        https://development.pycom.io/firmwareapi/pycom/network/bluetooth/gattscharacteristic/
        
        https://www.bluetooth.com/specifications/gatt/characteristics/
        https://docs.python.org/3/library/struct.html
        
        The format field determines how a single value contained in the Characteristic Value is formatted.
        The information contained on this page is referenced in Bluetooth® Core Specification Volume 3, Part G, Section 3.3.3.5.2.
        https://www.bluetooth.com/specifications/assigned-numbers/format-types/


        """
        print('Starting service')

        # A. Battery Service
        # UUID: 180F
        # Abstract: The Battery Service exposes the state of a battery within a device
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.service.battery_service.xml
        battery = self.bt.service(uuid=0x180F,
                                  isprimary=True,
                                  nbr_chars=1,
                                  start=True)

        # Battery Level
        # UUID: 2A19
        # Abstract: The current charge level of a battery.
        #           100% represents fully charged while 0% represents fully discharged
        # Format: uint8
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.battery_level.xml
        battery_level = battery.characteristic(uuid=0x2A19, value=78)

        # B. Environmental Sensing Service (ESS)
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.service.environmental_sensing.xml
        # https://www.bluetooth.com/specifications/assigned-numbers/environmental-sensing-service-characteristics/
        # https://github.com/sandeepmistry/arduino-BLEPeripheral/issues/215
        # https://github.com/sandeepmistry/arduino-nRF5/issues/248
        environment = self.bt.service(uuid=0x181A,
                                      isprimary=True,
                                      nbr_chars=5,
                                      start=True)

        # Temperature
        # UUID: 2A6E
        # InformativeText: Unit is in degrees Celsius with a resolution of 0.01 degrees Celsius
        # Format: sint16
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature.xml
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature_measurement.xml
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature_type.xml
        # https://github.com/ARMmbed/ble/blob/master/ble/services/HealthThermometerService.h
        # https://github.com/ARMmbed/ble/blob/master/ble/services/EnvironmentalService.h

        # Temperature Celsius
        # UUID: 2A1F
        # Format: sint16
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature_celsius.xml
        self.temp = 42.42
        temperature = environment.characteristic(uuid=0x2A1F)

        def temp_getter(chr):
            """

            :param chr: 

            """
            print('Getting characteristic:', chr)
            value = sint16(self.temp * 10)
            print('Value:', value)
            self.temp += 1
            return value

        print('Adding characteristic callback')
        temperature_callback = temperature.callback(
            trigger=Bluetooth.CHAR_READ_EVENT, handler=temp_getter)

        # Temperature Measurement
        # UUID: 2A1C
        # Format: Variable length structure
        # Value Format: FLOAT (IEEE-11073 32-bit FLOAT)
        # Abstract: The Temperature Measurement characteristic is a variable length structure
        # containing a Flags field, a Temperature Measurement Value field and, based upon the
        # contents of the Flags field, optionally a Time Stamp field and/or a Temperature Type field.
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature_measurement.xml
        print('Adding Temperature Measurement')
        temperature_measurement = environment.characteristic(
            uuid=0x2A1C, value=encode_temperature_2a1c(42.428423))

        # Scientific Temperature
        # UUID: 2A3C
        # Format: float64 (IEEE-754 64-bit floating point)
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.scientific_temperature_celsius.xml
        # http://forum.espruino.com/conversations/306536/
        # https://stackoverflow.com/questions/36655172/how-to-read-a-ble-characteristic-float-in-swift

        # For the 'f', 'd' and 'e' conversion codes, the packed representation uses the IEEE 754
        # binary32, binary64 or binary16 format (for 'f', 'd' or 'e' respectively), regardless of
        # the floating-point format used by the platform.
        # https://docs.python.org/3/library/struct.html
        #print('Adding Scientific Measurement')
        #temperature_sci = environment.characteristic(uuid=0x2A3C, value=float64(42.42))

        # Humidity
        # UUID: 2A6F
        # InformativeText: Unit is in percent with a resolution of 0.01 percent
        # Format: uint16
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.humidity.xml
        humidity1 = environment.characteristic(uuid=0x2A6F,
                                               value=uint16(86.86 * 100))
        humidity2 = environment.characteristic(uuid=0x2A6F,
                                               value=uint16(50.55 * 100))

        # Pressure
        # UUID: 2A6D
        # InformativeText: Unit is in pascals with a resolution of 0.1 Pa
        # Format: uint32
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.pressure.xml

        # Weight
        # UUID: 2A98
        # InformativeText: Unit is in kilograms with a resolution of 0.005
        # Format: uint16
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.weight.xml
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.weight_measurement.xml
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.weight_scale_feature.xml
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.weight.xml
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.weight_measurement.xml
        # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.weight_scale_feature.xml
        weight = environment.characteristic(uuid=0x2A98,
                                            value=uint16(25.44 * 2 * 100))

        # GPS
        # https://forum.pycom.io/topic/5012/can-only-see-value-of-first-gatt-characteristic
        """
        lan = bt.service(0x1819, nbr_chars=3)
        # 0.001 precision
        lan.characteristic(uuid=0x2AAE, value=int(gps.lat * 1000))
        lan.characteristic(uuid=0x2AAF, value=int(gps.lon * 1000))
        lan.characteristic(uuid=0x2AB3, value=int(gps.alt * 1000))
        """

        # Generic Access
        # UUID: 1800
        # Abstract: The generic_access service contains generic information
        # about the device. All available Characteristics are readonly.
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.generic_access.xml

        # Generic Attribute Service
        # UUID: 1801
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.generic_attribute.xml
        # String Characteristic
        # UUID: 2A3D
        # A generic UTF8 string which may be used in Services requiring strings.
        # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.string.xml
        srv1 = self.bt.service(uuid=BluetoothUuid.to_bytes_le(
            '15ECCA29-0B6E-40B3-9181-BE9509B53200'),
                               isprimary=True,
                               nbr_chars=2,
                               start=True)
        #generic_attribute = self.bt.service(uuid=0x1800, isprimary=True, nbr_chars=2, start=True)
        #wifi_ssid = generic_attribute.characteristic(uuid=0x2A3D, properties=Bluetooth.PROP_BROADCAST | Bluetooth.PROP_INDICATE | Bluetooth.PROP_NOTIFY | Bluetooth.PROP_READ | Bluetooth.PROP_WRITE, value="default")
        #wifi_ssid = generic_attribute.characteristic(uuid=0x2A3D, properties=Bluetooth.PROP_NOTIFY | Bluetooth.PROP_READ | Bluetooth.PROP_WRITE, value="default")
        wifi_ssid = srv1.characteristic(uuid=0x2A3D)
        #wifi_password = generic_attribute.characteristic(uuid=0x2A3D, properties=Bluetooth.PROP_READ | Bluetooth.PROP_WRITE)
        #print('wifi_ssid:', wifi_ssid, dir(wifi_ssid))
        #cfg = wifi_ssid.config()
        #print('cfg:', cfg)
        #wifi_ssid.config(name='hallodri')

        print('wifi_ssid:', wifi_ssid)
        print('wifi_ssid:', dir(wifi_ssid))

        def wifi_callback(characteristic):
            """

            :param characteristic: 

            """
            print('Characteristic callback:', characteristic)
            #print('attr_obj:', characteristic.attr_obj)
            events = characteristic.events()
            if events & Bluetooth.CHAR_WRITE_EVENT:
                print("Write request with value = {}".format(
                    characteristic.value()))
            else:
                pass
            value = characteristic.value()
            print('Reading characteristic:', value)

        print('Adding characteristic callback')
        wifi_ssid_callback = wifi_ssid.callback(
            trigger=Bluetooth.CHAR_READ_EVENT | Bluetooth.CHAR_WRITE_EVENT,
            handler=wifi_callback)
        #wifi_password_callback = wifi_password.callback(trigger=Bluetooth.CHAR_READ_EVENT | Bluetooth.CHAR_WRITE_EVENT, handler=wifi_callback)

        #print('instance:', wifi_ssid.instance())

        # Characteristic User Description
        # UUID: 0x2901,0x2902
        print(wifi_ssid_callback)
        print(dir(wifi_ssid_callback))
        srv1.characteristic(uuid=0x2901, value="hello world 1")
Beispiel #9
0
class MoveHub(object):
    def __init__(self, address):
        self.address = address
        self.conn = None
        self.last_color_C = ''
        self.last_color_D = ''
        self.last_distance_C = ''
        self.last_distance_D = ''
        self.last_brightness_C = 0
        self.last_brightness_D = 0
        self.last_angle_A = ''
        self.last_angle_B = ''
        self.last_angle_C = ''
        self.last_angle_D = ''
        self.last_angle_AB = ''
        self.last_button = ''
        self.last_hubtilt = 6
        self.devicename = ''
        self.wqueue = []
        self.is_subscribe = False

    def start(self):
        self.ble = Bluetooth()
        self.conn = self.ble.connect(self.address)
        while not self.conn.isconnected():
            sleep_ms(100)
        sleep_ms(2000)
        self.svcs = self.conn.services()
        self.chars = self.svcs[2].characteristics()
        self.devicename = self.svcs[1].characteristics()[0].read().decode(
            'utf-8')

    def stop(self):
        if self.conn is not None:
            if self.conn.isconnected():
                self.conn.disconnect()
            self.conn = None

    def is_connected(self):
        if self.conn is not None:
            return self.conn.isconnected()
        return False

    def gat_address(self):
        return self.address

    def get_name(self):
        return self.devicename

    def set_hublight(self, color):
        command = SET_LED_INI
        command += bytes([LED_COLORS.index(color)])
        self._write(command)

    def run_motor_for_time(self, motor, time_ms, dutycycle_pct):
        if motor in MOTORS:
            if dutycycle_pct in range(-100, 101):
                command = MOTOR_TIMED_INI
                command += motor
                command += MOTOR_TIMED_MID
                t = bytes((time_ms & 0xff, (time_ms >> 8) & 0xff))
                command += t
                if dutycycle_pct < 0:
                    dutycycle_pct += 255
                command += bytes([dutycycle_pct])
                command += MOTOR_TIMED_END
                self._write(command)

    def run_motors_for_time(self, motor, time_ms, dutycycle_pct_a,
                            dutycycle_pct_b):
        if motor in MOTOR_PAIRS:
            if (dutycycle_pct_a in range(-100, 101)
                    and dutycycle_pct_b in range(-100, 101)):
                command = MOTORS_TIMED_INI
                command += motor
                command += MOTORS_TIMED_MID
                t = bytes((time_ms & 0xff, (time_ms >> 8) & 0xff))
                command += t
                if dutycycle_pct_a < 0:
                    dutycycle_pct_a += 255
                command += bytes([dutycycle_pct_a])
                if dutycycle_pct_b < 0:
                    dutycycle_pct_b += 255
                command += bytes([dutycycle_pct_b])
                command += MOTORS_TIMED_END
                self._write(command)

    def run_motor_for_angle(self, motor, angle, dutycycle_pct):
        if motor in MOTORS:
            if dutycycle_pct in range(-100, 101):
                command = MOTOR_ANGLE_INI
                command += motor
                command += MOTOR_ANGLE_MID
                ang = bytes((angle & 0xff, (angle >> 8) & 0xff,
                             (angle >> 16) & 0xff, (angle >> 24) & 0xff))
                command += ang
                if dutycycle_pct < 0:
                    dutycycle_pct += 255
                command += bytes([dutycycle_pct])
                command += MOTOR_ANGLE_END
                self._write(command)

    def run_motors_for_angle(self, motor, angle, dutycycle_pct_a,
                             dutycycle_pct_b):
        if motor in MOTORS:
            if (dutycycle_pct_a in range(-100, 101)
                    and dutycycle_pct_b in range(-100, 101)):
                command = MOTORS_ANGLE_INI
                command += motor
                command += MOTORS_ANGLE_MID
                ang = bytes((angle & 0xff, (angle >> 8) & 0xff,
                             (angle >> 16) & 0xff, (angle >> 24) & 0xff))
                command += ang
                if dutycycle_pct_a < 0:
                    dutycycle_pct_a += 255
                command += bytes([dutycycle_pct_a])
                if dutycycle_pct_b < 0:
                    dutycycle_pct_b += 255
                command += bytes([dutycycle_pct_b])
                command += MOTORS_ANGLE_END
                self._write(command)

    @staticmethod
    def parse_notifications(self):
        if len(self.wqueue) > 0:
            command = self.wqueue.pop(0)
            self.chars[0].write(command)
        value = self.chars[0].read()
        if value is None or len(value) < 5:
            return
        #bstr = ''
        #for i in range(len(value)):
        #    bstr += hex(value[i]) + ' '
        #print('value:', bstr)
        if value[0] == 0x08 and value[1] == 0x00 and value[2] == 0x45:
            if value[3] == PORT_A:
                self.last_angle_A = (value[4] + value[5] * 256 +
                                     value[6] * 65536 + value[7] * 16777216)
                if self.last_angle_A > ENCODER_MID:
                    self.last_angle_A = self.last_angle_A - ENCODER_MAX
            elif value[3] == PORT_B:
                self.last_angle_B = (value[4] + value[5] * 256 +
                                     value[6] * 65536 + value[7] * 16777216)
                if self.last_angle_B > ENCODER_MID:
                    self.last_angle_B = self.last_angle_B - ENCODER_MAX
            elif value[3] == PORT_C:
                if self._port_C_is == TYPE_COLORDISTANCE:
                    if value[4] != 0xFF:
                        self.last_color_C = COLOR_SENSOR_COLORS[value[4]]
                        self.last_brightness_C = value[7]
                        self.last_distance_C = ''
                    else:
                        self.last_color_C = ''
                        self.last_brightness_C = 0
                        self.last_distance_C = value[5]
                elif self._port_C_is == TYPE_ENCODERMOTOR:
                    self.last_angle_C = (value[4] + value[5] * 256 +
                                         value[6] * 65536 +
                                         value[7] * 16777216)
                    if self.last_angle_C > ENCODER_MID:
                        self.last_angle_C = (self.last_angle_C - ENCODER_MAX)
            elif value[3] == PORT_D:
                if self._port_D_is == TYPE_COLORDISTANCE:
                    if value[4] != 0xFF:
                        self.last_color_D = COLOR_SENSOR_COLORS[value[4]]
                        self.last_brightness_D = value[7]
                        self.last_distance_D = ''
                    else:
                        self.last_color_D = ''
                        self.last_brightness_D = 0
                        self.last_distance_D = value[5]
                elif self._port_D_is == TYPE_ENCODERMOTOR:
                    self.last_angle_D = (value[4] + value[5] * 256 +
                                         value[6] * 65536 +
                                         value[7] * 16777216)
                    if self.last_angle_D > ENCODER_MID:
                        self.last_angle_D = (self.last_angle_D - ENCODER_MAX)
            elif value[3] == MOTOR_AB:
                pass
        elif (value[0] == 0x06 and value[1] == 0x00 and value[2] == 0x01
              and value[3] == 0x02 and value[4] == 0x06):
            if value[5] == 1:
                self.last_button = BUTTON_PRESSED
            elif value[5] == 0:
                self.last_button = BUTTON_RELEASED
            else:
                self.last_button = ''
        elif (value[0] == 0x05 and value[1] == 0x00 and value[2] == 0x45
              and value[3] == 0x3a):
            if value[4] in range(6):
                self.last_hubtilt = value[4]
            else:
                self.last_hubtilt = 6
                print('Tilt: Unknown value')

    def subscribe_all(self):
        self.chars[0].callback(Bluetooth.CHAR_NOTIFY_EVENT,
                               MoveHub.parse_notifications, self)
        self.is_subscribe = True

    def listen_colordist_sensor(self, port):
        if port in [PORT_C, PORT_D]:
            command = LISTEN_INI
            command += bytes([port])
            command += MODE_COLORDIST_SENSOR
            command += LISTEN_END
            if port == PORT_C:
                self._port_C_is = TYPE_COLORDISTANCE
            else:
                self._port_D_is = TYPE_COLORDISTANCE
            self.chars[0].write(command)

    def listen_angle_sensor(self, port):
        if port in [PORT_A, PORT_B, PORT_C, PORT_D]:
            command = LISTEN_INI
            command += bytes([port])
            command += MODE_ENCODER
            command += LISTEN_END
            if port == PORT_C:
                self._port_C_is = TYPE_ENCODERMOTOR
            elif port == PORT_D:
                self._port_D_is = TYPE_ENCODERMOTOR
            self.chars[0].write(command)

    def listen_button(self):
        self.chars[0].write(LISTEN_BUTTON)

    def listen_hubtilt(self, mode):
        if mode in [MODE_HUBTILT_BASIC, MODE_HUBTILT_FULL]:
            command = LISTEN_INI
            command += bytes([PORT_TILT])
            command += mode
            command += LISTEN_END
            self.chars[0].write(command)

    def _write(self, command):
        if self.is_subscribe:
            self.wqueue.append(command)
        else:
            self.chars[0].write(command)
Beispiel #10
0
import time
bt = Bluetooth()
bt.start_scan(-1)

while True:
    adv = bt.get_adv()
    if adv 
        # try to get the complete name
        print(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL))

        # try to get the manufacturer data (Apple's iBeacon data is sent here)
        print(binascii.hexlify(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA)))

        
        if bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate':
            conn = bt.connect(adv.mac)
            services = conn.services()
            for service in services:
                time.sleep(0.050)
                if type(service.uuid()) == bytes:
                    print('Reading chars from service = {}'.format(service.uuid()))
                else:
                    print('Reading chars from service = %x' % service.uuid())
                chars = service.characteristics()
                for char in chars:
                    if (char.properties() & Bluetooth.PROP_READ):
                        print('char {} value = {}'.format(char.uuid(), char.read()))
            conn.disconnect()
            break
    else:
        time.sleep(0.050)
def BlueToothFun():
    '''
    #Firstly,act as a server
    pycom.heartbeat(False)
    bluetooth = Bluetooth() #create a bluetooth object
    bluetooth.set_advertisement(name='LoPyServer2', service_uuid=b'1234567890123456')
    #id for this device 
    deviceID = 222
    #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:
            print("Client connected")
            pycom.rgbled(0x007f00) # green
        elif events & Bluetooth.CLIENT_DISCONNECTED:
            print("Client disconnected")
            pycom.rgbled(0x7f0000) # red
            
    bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
    #
    bluetooth.advertise(True)

    srv1 = bluetooth.service(uuid=b'1234567890123456', isprimary=True)

    chr1 = srv1.characteristic(uuid=b'ab34567890123456', value=5)

    #char1_read_counter = 0

    def char1_cb_handler(chr):
        #global char1_read_counter
       # char1_read_counter += 1

        events = chr.events()
        if  events & Bluetooth.CHAR_WRITE_EVENT:
            print("Write request with value = {}".format(chr.value()))
        else:
            #modify here to send message to other clients
            return str(deviceID)
    #using the callback to send the data to other clients
    char1_cb = chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler)
'''
    '''srv2 = bluetooth.service(uuid=1234, isprimary=True)

    chr2 = srv2.characteristic(uuid=4567, value=0x1234)
    char2_read_counter = 0xF0
    def char2_cb_handler(chr):
        global char2_read_counter
        char2_read_counter += 1
        if char2_read_counter > 0xF1:
            return char2_read_counter

    char2_cb = chr2.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=char2_cb_handler)'''

    #Secondly, also act as client
    bt = Bluetooth()
    bt.start_scan(-1)
    counter = 0
    while True:
        #Gets an named tuple with the advertisement data received during the scanning.
        #The structure is (mac, addr_type, adv_type, rssi, data)
        adv = bt.get_adv()
        #servermac = ''#save the serer mac
        #use resolve_adv_data to resolve the 31 bytes of the advertisement message
        #Here is problem: when disconnect from server, then adv will always be null...
        if adv and bt.resolve_adv_data(
                adv.data, Bluetooth.ADV_NAME_CMPL) == 'LoPyServer1':
            try:
                #Opens a BLE connection with the device specified by the mac_addr argument
                #This function blocks until the connection succeeds or fails.
                #print(adv.mac)
                #global servermac#change servermac to global
                #servermac = adv.mac
                counter += 1
                conn = bt.connect(adv.mac)
                #print('connected?',conn.isconnected())
                services = conn.services()
                #print('This is service',services)
                #print(services)
                '''
                for service in services:
                    print('This is service uuid',service.uuid())
                    time.sleep(0.050)
                    if type(service.uuid()) == bytes:
                        print('if bytes:Reading chars from service = {}'.format(service.uuid()))
                    else:
                        print('if not bytes:Reading chars from service = %x' % service.uuid())
                    chars = service.characteristics()
                    for char in chars:
                        if (char.properties() & Bluetooth.PROP_READ):
                            print('char {} value = {}'.format(char.uuid(), char.read()))
                '''
                #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:
                            #check if the character properties is PROP_READ
                            if (char.properties() & Bluetooth.PROP_READ):
                                print('char {} value = {}'.format(
                                    char.uuid(), char.read()) + str(counter))
                #Yunwei
                conn.disconnect()
                print('connected?', conn.isconnected())
                #break
                time.sleep(1)
                bt.start_scan(-1)
            except:
                print("Error while connecting or reading from the BLE device")
                #break
                time.sleep(1)
                bt.start_scan(-1)
                print('Scan again')
Beispiel #12
0
import pycom
from network import Bluetooth
import time
import binascii

bt = Bluetooth()
bt.start_scan(10)
conn = bt.connect('08b5d69c1d67')
print(conn)
services = conn.services()
print(services)
for service in services:
    print(service.uuid())
def BLEAndLoRaFun():
    #First, initialize as one LoRa node device
    # initialize LoRa in LORAWAN mode.
    # Please pick the region that matches where you are using the device:
    # Asia = LoRa.AS923
    # Australia = LoRa.AU915
    # Europe = LoRa.EU868
    # United States = LoRa.US915
    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)

    # create an ABP authentication params
    dev_addr = struct.unpack(">l", binascii.unhexlify('260214B3'))[0]
    nwk_swkey = binascii.unhexlify('2C2139EEC68B264BF1F0EDCE183CE33F')
    app_swkey = binascii.unhexlify('C25FB9A263307BF86B659298D86D4A45')

    # remove all the channels
    for channel in range(0, 72):
        lora.remove_channel(channel)

    # set all channels to the same frequency (must be before sending the OTAA join request)
    for channel in range(0, 72):
        lora.add_channel(channel,
                         frequency=config.LORA_FREQUENCY,
                         dr_min=0,
                         dr_max=3)

    # join a network using ABP (Activation By Personalization)
    lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))

    # create a LoRa socket
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)

    # set the LoRaWAN data rate
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)  # last parameter is 3

    # make the socket non-blocking
    s.setblocking(False)

    #Second, act as BLE client
    bt = Bluetooth()
    bt.start_scan(-1)
    counter = 0
    while True:
        #Gets an named tuple with the advertisement data received during the scanning.
        #The structure is (mac, addr_type, adv_type, rssi, data)
        adv = bt.get_adv()
        #servermac = ''#save the serer mac
        #use resolve_adv_data to resolve the 31 bytes of the advertisement message
        #Here is problem: when disconnect from server, then adv will always be null...
        if adv and bt.resolve_adv_data(
                adv.data, Bluetooth.ADV_NAME_CMPL) == 'LoPyServer1':
            try:
                #Opens a BLE connection with the device specified by the mac_addr argument
                #This function blocks until the connection succeeds or fails.
                #print(adv.mac)
                #global servermac#change servermac to global
                #servermac = adv.mac
                counter += 1
                conn = bt.connect(adv.mac)
                #print('connected?',conn.isconnected())
                services = conn.services()
                #print('This is service',services)
                #print(services)
                '''
                for service in services:
                    print('This is service uuid',service.uuid())
                    time.sleep(0.050)
                    if type(service.uuid()) == bytes:
                        print('if bytes:Reading chars from service = {}'.format(service.uuid()))
                    else:
                        print('if not bytes:Reading chars from service = %x' % service.uuid())
                    chars = service.characteristics()
                    for char in chars:
                        if (char.properties() & Bluetooth.PROP_READ):
                            print('char {} value = {}'.format(char.uuid(), char.read()))
                '''
                #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:
                            #check if the character properties is PROP_READ
                            if (char.properties() & Bluetooth.PROP_READ):
                                print('char {} value = {}'.format(
                                    char.uuid(), char.read()) + str(counter))
                                #Use LoRa to send the data out
                                s.send(char.read())
                                time.sleep(4)
                #Yunwei
                conn.disconnect()
                print('connected?', conn.isconnected())
                #break
                time.sleep(6)
                bt.start_scan(-1)
            except:
                print("Error while connecting or reading from the BLE device")
                #break
                time.sleep(1)
                bt.start_scan(-1)
                print('Scan again')
Beispiel #14
0
if server_mac is None:
    print(time.time(), "couldn not find", server_name)
    pycom.rgbled(0x220000)
    time.sleep(5)
    machine.reset()
else:
    #server_adv = Adv[server_mac]
    print(time.time(), "found", server_name, "at",
          binascii.hexlify(server_mac))  # , "with", server_adv.rssi)
    ct = 0
    while True:
        try:
            pycom.rgbled(0x000022)
            print(time.time(), ct, "connect to", server_name)
            conn = bt.connect(server_mac)
            print(time.time(), "connected successful", ct)
            break
        except Exception as e:
            print(time.time(), "failed", e)
            bt.disconnect_client()
            pycom.rgbled(0x220000)
            time.sleep(1)
            if ct >= 10:
                print("reset")
                machine.reset()
        ct += 1
    pycom.rgbled(0x002200)
    print(conn.isconnected())
    print(conn.get_mtu())
    print("Services", len(conn.services()), ":")