About BLE.gap_connect(esp32-based ubluetooth)

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

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

Post by jimmo » Fri Dec 06, 2019 3:45 am

Sorry that's a bit much to ask.

I'd like to help, but I still don't understand what you're even trying to do. Can you answer my question (is it (a) or (b) or something else) and post snippets that show what you're doing and what you expect to happen.

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

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

Post by net0040 » Fri Dec 06, 2019 6:27 am

jimmo wrote:
Fri Dec 06, 2019 3:45 am
Can you answer my question (is it (a) or (b) or something else) and post snippets that show what you're doing and what you expect to happen.
So sorry, My question is (a). I have a real heart rate band, and can connect to from:
ESP32 (arduino)
Arduino 101
Android Phones
Old MicroPython (2017-08)

But I can't connect to it from new MicroPython.

In _IRQ_SCAN_RESULT

I can get adv_data ,but decode_services(adv_data)=[],it return null.


My code comes entirely from your ble thermometer central role
Just two changes:
1 180D---181A
2 2A37---2A6E

Code: Select all

>>> %Run -c $EDITOR_CONTENT
>>> 0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
0 b'\xf4^\xab\x91k\x97' b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'
No sensor found.
addr_type= 0
addr = b'\xf4^\xab\x91k\x97'
adv_data=b'\x02\x01\x06\x05\x02\r\x18\x0f\x18'

Thanks.

Heba_Mostafa
Posts: 1
Joined: Wed Mar 04, 2020 4:34 pm

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

Post by Heba_Mostafa » Wed Mar 04, 2020 4:47 pm

net0040 wrote:
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
How can i get the actual data value ?
when i call (bt.gattc_read(conn_handle,value_handle))in char event & the event(_IRQ_GATTC_READ_RESULT)occurs,i start print(char_data) but the value printed is like(b'\x12\x0e') or string like(Device name). how can i get the integer value of heart rate ?

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

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

Post by jimmo » Thu Mar 05, 2020 12:03 am

Heba_Mostafa wrote:
Wed Mar 04, 2020 4:47 pm
when i call (bt.gattc_read(conn_handle,value_handle))in char event & the event(_IRQ_GATTC_READ_RESULT)occurs,i start print(char_data) but the value printed is like(b'\x12\x0e') or string like(Device name). how can i get the integer value of heart rate ?
The values returned from reads are just the underlying bytes that were transmitted by the peripheral.

It's up to the individual services and characteristics to define how those bytes should be interpreted. See for example in " def _update_value(self, data):" in https://github.com/micropython/micropyt ... al.py#L186 where the temperature value is a signed 16-bit int.

In most cases, Python's struct.unpack is quite helpful for decoding these payloads.

You can look up the characteristics at https://www.bluetooth.com/specification ... teristics/ There used to be a nice viewer, but now there's just the XML files.

In your case, org.bluetooth.characteristic.heart_rate_measurement (i.e. 0x2A37) is https://www.bluetooth.com/wp-content/up ... rement.xml

So this one is a bit tricky -- the first byte tells you a few things, including whether this is an 8 or 16-bit value (and other information about whether the sensor is currently making contact). Then the remaining bytes are the actual value in BPM.

User avatar
Walkline
Posts: 14
Joined: Wed Feb 19, 2020 4:44 pm

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

Post by Walkline » Fri Jun 05, 2020 7:40 am

net0040 wrote:
Fri Dec 06, 2019 6:27 am
In _IRQ_SCAN_RESULT

I can get adv_data ,but decode_services(adv_data)=[],it return null.
_IRQ_SCAN_RESULT is a callback used for gap_scan(), in this callback you will got addr_type and addr, use gap_connect() with these params to start connect the scanned device, _IRQ_PERIPHERAL_CONNECT will triggered and you can get conn_handle, and then use gattc_discover_services() with conn_handle param to start discovery services, you will meet your UUID in _IRQ_GATTC_SERVICE_RESULT callback....

About the decode_services(), it's used to decode services UUID from broadcasting payload, generally it's only include basic services, eg. General Access

Post Reply