How to get BLE beacons

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
john7
Posts: 10
Joined: Mon Mar 16, 2020 11:09 am

How to get BLE beacons

Post by john7 » Tue Mar 17, 2020 9:26 am

One ESP32 board is advertising BLE beacons. I want to scan thees beacons on another ESP32 board. How can I do it?

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to get BLE beacons

Post by jimmo » Tue Mar 17, 2020 9:48 am

A BLE beacon just includes its data in the advertising payload. So you'll see this when you scan for devices (i.e. ble.gap_scan() ).

See the temperature central example that includes code that scans for devices and looks at the advertising data https://github.com/micropython/micropyt ... ral.py#L83

john7
Posts: 10
Joined: Mon Mar 16, 2020 11:09 am

Re: How to get BLE beacons

Post by john7 » Tue Mar 17, 2020 10:01 am

jimmo wrote:
Tue Mar 17, 2020 9:48 am
A BLE beacon just includes its data in the advertising payload. So you'll see this when you scan for devices (i.e. ble.gap_scan() ).

See the temperature central example that includes code that scans for devices and looks at the advertising data https://github.com/micropython/micropyt ... ral.py#L83
Thank you.

I get
ImportError: no module named 'ble_advertising'
on line
from ble_advertising import decode_services, decode_name

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to get BLE beacons

Post by jimmo » Tue Mar 17, 2020 12:04 pm

john7 wrote:
Tue Mar 17, 2020 10:01 am
ImportError: no module named 'ble_advertising'
You need to copy ble_advertising.py to your device (it's in the same directory).

john7
Posts: 10
Joined: Mon Mar 16, 2020 11:09 am

Re: How to get BLE beacons

Post by john7 » Tue Mar 17, 2020 1:23 pm

I don't understand the logic. In C routines run in main

Code: Select all

void main(void)
{
    Init();
    while (1)
    {
        DoSomeStuff();
    }
}
here I see

Code: Select all

def demo():
    ble = bluetooth.BLE()
    central = BLETemperatureCentral(ble)
    
    and so on....
    
 if __name__ == "__main__":
    demo()   
demo() doesn't run constantly, does it?

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to get BLE beacons

Post by jimmo » Fri Mar 20, 2020 3:10 am

john7 wrote:
Tue Mar 17, 2020 1:23 pm
demo() doesn't run constantly, does it?
Yes, exactly like your C example -- it has a while loop:

Code: Select all

    while central.is_connected():
        central.read(callback=print)
        time.sleep_ms(2000)
(Although the program will terminate back to the REPL once the peripheral disconnects)

john7
Posts: 10
Joined: Mon Mar 16, 2020 11:09 am

Re: How to get BLE beacons

Post by john7 » Sun Mar 22, 2020 6:50 am

That's the problem - if it get disconnected. Isn't it better to create an endless loop? And organize some state machine - in case it's disconnected - try to connect, in case it's connected - scan for beacons.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to get BLE beacons

Post by jimmo » Sun Mar 22, 2020 9:27 am

Yes, if this were a real program, definitely.

john7
Posts: 10
Joined: Mon Mar 16, 2020 11:09 am

Re: How to get BLE beacons

Post by john7 » Sun Mar 22, 2020 2:12 pm

Thank you.

aofek54
Posts: 1
Joined: Sat Jul 31, 2021 4:30 am

Re: How to get BLE beacons

Post by aofek54 » Sat Jul 31, 2021 5:09 am

Hi Jimmo, John7
Just followed your conversation today
Got to alternate Advertise and Scan every 5 seconds, getting Name and rssi from whoever is found
Adv works fine
The scanning gives all kind of problems like ble.gap_scan() doesn't work
Could you please inspect this code?
Thank you
Avi


code:

Code: Select all

# Advertise wait 5 second, scan wait 5 seconds, if found another BLE
# save time, name and rssi
ble = bluetooth.BLE()
name_found=' '
name_foundl=' '
rssi=' '
rssil=' '

_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)

_ADV_IND = const(0x00)
_ADV_DIRECT_IND = const(0x01)
_ADV_SCAN_IND = const(0x02)
_ADV_NONCONN_IND = const(0x03)

#-------------------------------------------

class BLEA():            # Advertise
    def __init__(self, name):   
        self.name = name
        self.ble = ubluetooth.BLE()
        self.ble.active(True)      
        self.advertiser()

    def advertiser(self):
        name = bytes(self.name, 'UTF-8')
        self.ble.gap_advertise(100, bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name)


class BLEF:
    
    def __init__(self, ble):
        self._ble = ble
        self._ble.active(True)
        self._ble.irq(self._irq)
        self._reset()

    def _reset(self):
        # Cached name and address from a successful scan.
        self._name_found = None
        self._addr_type = None
        self._addr = None
        self.rssi = None
        

    def _irq(self, event, data):
        if event == _IRQ_SCAN_RESULT:
            addr_type, addr, adv_type, rssi, adv_data = data
            return data
 
    # Find a device advertising the environmental sensor service.
    def scan(self, callback=None):
       
        self._addr_type = None
        self._addr = None
        self._scan_callback = callback
        self._ble.gap_scan(2000, 5000, 5000)      

#-----------------------------------------------
if __name__ == '__main__':
    while True:
        print('advertise')
        BLEA('ahp01')
        time.sleep_ms(5000)
        print('find')
        BLEF(ble)
        print('results',name_found,rssi)
        time.sleep_ms(5000)
Last edited by jimmo on Wed Aug 04, 2021 4:53 am, edited 1 time in total.
Reason: Add [code] formatting

Post Reply