About BLE.gap_connect(esp32-based ubluetooth)

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
User avatar
net0040
Posts: 26
Joined: Fri Nov 08, 2019 4:33 am

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by net0040 » Mon Nov 11, 2019 12:24 am

thanks,I will try it.

User avatar
net0040
Posts: 26
Joined: Fri Nov 08, 2019 4:33 am

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by net0040 » Mon Nov 11, 2019 3:37 am

jimmo wrote:
Sun Nov 10, 2019 11:48 pm
You can't discover services until you're connected to the peripheral. i.e. you have to wait until you get the _IRQ_PERIPHERAL_CONNECT event.

If you want a "synchronous" connect, you might find this thread viewtopic.php?f=20&t=7199 and followup in this thread viewtopic.php?f=2&t=7205 useful.

Code: Select all

bt.gap_connect(0, b'\xf4^\xab\x91k\x97', 2000)

Code: Select all

  elif event == _IRQ_PERIPHERAL_CONNECT:
    # A successful gap_connect().
    conn_handle, addr_type, addr = data
    print('conn_handle','addr_type','addr')
    print(conn_handle,addr_type,addr)
    print('conn complete')
I thought that once the PERIPHERAL_CONNECT succeeded, it returned to 'conn_handle', 'addr_type', 'addr' and would be considered connected to the the PERIPHERAL device.

Code: Select all

>>> conn_handle addr_type addr
0 0 b'\xf4^\xab\x91k\x97'
conn complete
Now it may not seem so simple. I'll take a closer look at your suggested posts.

thanks

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

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by jimmo » Mon Nov 11, 2019 4:23 am

I'm not quite sure I follow sorry.

The important thing to know is that the events (i.e. the irq function) happen asynchronously.

i.e. calling gap_connect() returns immediately, then at some point in the future, the event will be invoked with the conn_handle, etc.

So you must only call gattc_discover_services() after you've received the conn_handle in the event.

User avatar
net0040
Posts: 26
Joined: Fri Nov 08, 2019 4:33 am

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by net0040 » Mon Nov 11, 2019 5:34 am

After my code runs:

Code: Select all

>>> conn_handle addr_type addr
0 0 b'\xf4^\xab\x91k\x97'
conn complete
I think When _IRQ_PERIPHERAL_CONNECT happened, It will return:

Code: Select all

conn_handle=0
addr_type=0
addr= b'\xf4^\xab\x91k\x97'
Looks like I don't know enough.I'm not familiar with the ble mechanism. :D
I'm learning about the two posts you mentioned.

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

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by jimmo » Mon Nov 11, 2019 6:13 am

In your code you posted earlier, you had:

Code: Select all

bt.gap_connect(0, b'\xf4^\xab\x91k\x97', 2000)
bt.gattc_discover_services(0)
you can't do the second line until you've received the _IRQ_PERIPHERAL_CONNECT from the first line. (And you need the conn_handle from that event, rather than always using `0`).

So one easy option is to call gattc_discover_services() from within the connect event handler.

User avatar
net0040
Posts: 26
Joined: Fri Nov 08, 2019 4:33 am

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by net0040 » Tue Nov 19, 2019 3:59 pm

My code:

Code: Select all

from ubluetooth import BLE, UUID, FLAG_NOTIFY, FLAG_READ, FLAG_WRITE
from micropython import const
import utime

_IRQ_CENTRAL_CONNECT                 = const(1 << 0)
_IRQ_CENTRAL_DISCONNECT              = const(1 << 1)
_IRQ_GATTS_WRITE                     = const(1 << 2)
_IRQ_GATTS_READ_REQUEST              = const(1 << 3)
_IRQ_SCAN_RESULT                     = const(1 << 4)
_IRQ_SCAN_COMPLETE                   = const(1 << 5)
_IRQ_PERIPHERAL_CONNECT              = const(1 << 6)
_IRQ_PERIPHERAL_DISCONNECT           = const(1 << 7)
_IRQ_GATTC_SERVICE_RESULT            = const(1 << 8)
_IRQ_GATTC_CHARACTERISTIC_RESULT     = const(1 << 9)
_IRQ_GATTC_DESCRIPTOR_RESULT         = const(1 << 10)
_IRQ_GATTC_READ_RESULT               = const(1 << 11)
_IRQ_GATTC_WRITE_STATUS              = const(1 << 12)
_IRQ_GATTC_NOTIFY                    = const(1 << 13)
_IRQ_GATTC_INDICATE                  = const(1 << 14)

def adv_decode(adv_type, data):
    i = 0
    while i + 1 < len(data):
        if data[i + 1] == adv_type:
            return data[i + 2:i + data[i] + 1]
        i += 1 + data[i]
    return None

def adv_decode_name(data):
    n = adv_decode(0x09, data)
    if n:
        return n.decode('utf-8')
    return data

def bt_irq(event, data):
  if event == _IRQ_SCAN_RESULT:
    # A single scan result.
    addr_type, addr, connectable, rssi, adv_data = data
    print(addr_type, addr, adv_decode_name(adv_data))
  elif event == _IRQ_SCAN_COMPLETE:
    # Scan duration finished or manually stopped.
    print('scan complete')
  elif event == _IRQ_PERIPHERAL_CONNECT:
    # A successful gap_connect().
    conn_handle, addr_type, addr = data
    utime.sleep(5)
    print(conn_handle, addr_type,addr)
    bt.gattc_discover_services(conn_handle)
    utime.sleep(5)
    print('connect complete...')
  elif event == _IRQ_PERIPHERAL_DISCONNECT:
    # Connected peripheral has disconnected.
    conn_handle, addr_type, addr = data
  elif event == _IRQ_GATTC_SERVICE_RESULT:
    # Called for each service found by gattc_discover_services().
    conn_handle, start_handle, end_handle, uuid = data
    print(conn_handle, start_handle, end_handle, uuid)
    bt.gattc_discover_characteristics(conn_handle, start_handle, end_handle)
    #bt.gattc_discover_descriptors(conn_handle,start_handle,end_handle)
    print('discover service...')
  elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
    # Called for each characteristic found by gattc_discover_services().
    conn_handle, def_handle, value_handle, properties, uuid = data
    print(conn_handle, def_handle, value_handle, properties, uuid)
    print('discover char ...')
  elif event == _IRQ_GATTC_DESCRIPTOR_RESULT:
    # Called for each descriptor found by gattc_discover_descriptors().
    conn_handle, dsc_handle, uuid = data
    print(conn_handle, dsc_handle, uuid)
    print('discover descript  ...')
  elif event == _IRQ_GATTC_READ_RESULT:
    # A gattc_read() has completed.
    conn_handle, value_handle, char_data = data
  elif event == _IRQ_GATTC_WRITE_STATUS:
    # A gattc_write() has completed.
    conn_handle, value_handle, status = data
  elif event == _IRQ_GATTC_NOTIFY:
    # A peripheral has sent a notify request.
    conn_handle, value_handle, notify_data = data
  elif event == _IRQ_GATTC_INDICATE:
    # A peripheral has sent an indicate request.
    conn_handle, value_handle, notify_data = data

# Scan for 10s (at 100% duty cycle)
bt = BLE()
bt.active(True)
bt.irq(handler=bt_irq)
# Scan for 10s (at 100% duty cycle)
#bt.gap_scan(10000, 30000, 30000)
bt.gap_connect(0,b'\xf4^\xab\x91k\x97',2000)



result:

Code: Select all

>>> %Run -c $EDITOR_CONTENT
>>> 0 0 b'\xf4^\xab\x91k\x97'
connect complete...
0 1 11 UUID16(0x0000)
discover service...
0 12 15 UUID16(0x0001)
discover service...
0 16 23 UUID16(0x000d)
discover service...
0 24 65535 UUID16(0x000a)
discover service...
0 2 3 2 UUID16(0x0000)
discover char ...
0 13 14 32 UUID16(0x0005)
discover char ...
0 17 18 16 UUID16(0x0037)
discover char ...
0 22 23 8 UUID16(0x0039)
discover char ...
I want to be able to connect the heart rate band to esp312 and read the data. But now I can't find the heart rate service I need.
UUID 018D

Thanks

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

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by jimmo » Wed Nov 20, 2019 12:11 am

Sorry! this was a bug in the Nimble bindings extracting the UUIDs... I just fixed last week and sent the PR this morning. https://github.com/micropython/micropython/pull/5343

In the meantime though, the HR service is 0x180D (not 0x018D) and the bug is that the high byte is missing, so for now the one you're seeing as 0x000d is the correct one.

User avatar
net0040
Posts: 26
Joined: Fri Nov 08, 2019 4:33 am

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by net0040 » Wed Nov 20, 2019 2:59 am

jimmo wrote:
Wed Nov 20, 2019 12:11 am
Sorry! this was a bug in the Nimble bindings extracting the UUIDs... I just fixed last week and sent the PR this morning. https://github.com/micropython/micropython/pull/5343

In the meantime though, the HR service is 0x180D (not 0x018D) and the bug is that the high byte is missing, so for now the one you're seeing as 0x000d is the correct one.
yes,it is 0x180D。 :D
1. After scan, I got addr_type and addr, but after trying to connect,
conn_handle always return 0, I have also seen the posts of other players in the forum, should be a non-0 integer.

Code: Select all

>>> conn_handle addr_type addr
0 0 b'\xf4^\xab\x91k\x97'
2, Will the PR you sent be integrated into the firmware. I'm brush v.1120 firmware tonight and try again, thank you.

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

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by jimmo » Wed Nov 20, 2019 4:14 am

net0040 wrote:
Wed Nov 20, 2019 2:59 am
conn_handle always return 0, I have also seen the posts of other players in the forum, should be a non-0 integer.
It depends on which port and the BLE implementation. On ESP32, the conn_handle will typically be around 0, on STM32 it starts at 64.
net0040 wrote:
Wed Nov 20, 2019 2:59 am
2, Will the PR you sent be integrated into the firmware. I'm brush v.1120 firmware tonight and try again, thank you.
I hope so, but not sure how quickly. You can always build using my branch instead though if you want to try out the fix. https://github.com/jimmo/micropython/tr ... er-example

User avatar
net0040
Posts: 26
Joined: Fri Nov 08, 2019 4:33 am

Re: About BLE.gap_connect(esp32-based ubluetooth)

Post by net0040 » Wed Nov 20, 2019 4:36 am

jimmo wrote:
Wed Nov 20, 2019 4:14 am
net0040 wrote:
Wed Nov 20, 2019 2:59 am
conn_handle always return 0, I have also seen the posts of other players in the forum, should be a non-0 integer.
It depends on which port and the BLE implementation. On ESP32, the conn_handle will typically be around 0, on STM32 it starts at 64.
net0040 wrote:
Wed Nov 20, 2019 2:59 am
2, Will the PR you sent be integrated into the firmware. I'm brush v.1120 firmware tonight and try again, thank you.
I hope so, but not sure how quickly. You can always build using my branch instead though if you want to try out the fix. https://github.com/jimmo/micropython/tr ... er-example
ble-scanner-example/examples/bluetooth/ble_temperature_central.py
I will try it,thanks. :D

Post Reply