I'm still struggling on this. To recap, I'm trying to use an ESP32 TTGO T-Display to connect to an OBDII device to get engine stats. The OBDII acts as a peripheral and has the following service/characteristic UUIDs:
Code: Select all
Name - OBDBLE
Service - 0xffe0 ("0000ffe0-0000-1000-8000-00805f9b34fb")
Characteristic - 0xffe1 ("0000ffe1-0000-1000-8000-00805f9b34fb") INDICATE, READ, WRITE
Characteristic - 0xffee ("0000ffee-0000-1000-8000-00805f9b34fb") READ, WRITE
I'm using a derivative of @jimmo's (thank you Jimmo!) ble_simple_central.py.
I can connect to the reader using nrfConnect Mobile, send it all the necessary commands and get a series of notifications back containing the engine stats. However, I can't connect and get stats using the app. I can only connect to the reader by using it's name, using either the 16 bit or 128 bit UUID fails. If I connect using the name I get both an rx handle and tx handle returned with the correct characteristic UUIDs and properties but, when using those handles I get no notifications returned and suspect that the reader is not receiving my commands.
the UUIDs I'm using are:
Code: Select all
#_UART_SERVICE_UUID = bluetooth.UUID("0000ffe0-0000-1000-8000-00805f9b34fb")
#_UART_TX_CHAR_UUID = bluetooth.UUID("0000ffe1-0000-1000-8000-00805f9b34fb")
#_UART_RX_CHAR_UUID = bluetooth.UUID("0000ffee-0000-1000-8000-00805f9b34fb")
_UART_SERVICE_UUID = bluetooth.UUID(0xffe0)
_UART_TX_CHAR_UUID = bluetooth.UUID(0xffe1)
_UART_RX_CHAR_UUID = bluetooth.UUID(0xffee)
I have set up a simple emulator using a derivative of ble_simple_peripheral.py on an ESP32 and can connect quite happily to that (using the 16 bit UUIDs, I get an advertising payload error when using the 128 bit alternatives).
I suspect that the problem lies with correctly interpreting the UUIDs, even although I have the relevant handles but don't understand why it is going wrong.
The output from nrfConnect Mobile is:
Code: Select all
- PnP ID [R] (0x2A50)
Unknown Service (0000ffe0-0000-1000-8000-00805f9b34fb)
- Unknown Characteristic [N R W] (0000ffe1-0000-1000-8000-00805f9b34fb)
Client Characteristic Configuration (0x2902)
Characteristic User Description (0x2901)
- Unknown Characteristic [R W] (0000ffee-0000-1000-8000-00805f9b34fb)
Characteristic User Description (0x2901)
Unknown Descriptor (fe3cf737-79ed-f667-fdff-bfd4eeb3b7ff)
Unknown Descriptor (fe3cf737-79ed-f667-fdff-bfd4eeb3b7ff)
Unknown Descriptor (fe3cf737-79ed-f667-fdff-bfd4eeb3b7ff)
Unknown Descriptor (fe3cf737-79ed-f667-fdff-bfd4eeb3b7ff)
Unknown Descriptor (fe3cf737-79ed-f667-fdff-bfd4eeb3b7ff)
...
...
V 17:40:45.250 Writing request to characteristic 0000ffe1-0000-1000-8000-00805f9b34fb
D 17:40:45.250 gatt.writeCharacteristic(0000ffe1-0000-1000-8000-00805f9b34fb, value=0x3232303130310D)
I 17:40:45.309 Data written to 0000ffe1-0000-1000-8000-00805f9b34fb, value: (0x) 32-32-30-31-30-31-0D
A 17:40:45.309 "(0x) 32-32-30-31-30-31-0D" sent
I 17:40:45.323 Notification received from 0000ffe1-0000-1000-8000-00805f9b34fb, value: (0x) 30-33-45-0D-30-3A-36-32-30-31-30-31-46-46-46-37-45-37-0D
A 17:40:45.323 "(0x) 30-33-45-0D-30-3A-36-32-30-31-30-31-46-46-46-37-45-37-0D" received
I 17:40:45.324 Notification received from 0000ffe1-0000-1000-8000-00805f9b34fb, value: (0x) 31-3A-46-46-35-31-34-32-36-38-34-32-36-38-30-33-0D
A 17:40:45.324 "(0x) 31-3A-46-46-35-31-34-32-36-38-34-32-36-38-30-33-0D" received
I 17:40:45.355 Notification received from 0000ffe1-0000-1000-8000-00805f9b34fb, value: (0x) 32-3A-30-30-31-32-30-44-45-43-31-37-31-35-31-36-0D-33-3A-31
A 17:40:45.355 "(0x) 32-3A-30-30-31-32-30-44-45-43-31-37-31-35-31-36-0D-33-3A-31" received
I 17:40:45.357 Notification received from 0000ffe1-0000-1000-8000-00805f9b34fb, value: (0x) 36-31-35-31-36-30-30-30-30-31-39-42, "61516000019B"
A 17:40:45.357 "(0x) 36-31-35-31-36-30-30-30-30-31-39-42, "61516000019B"" received
I 17:40:45.358 Notification received from 0000ffe1-0000-1000-8000-00805f9b34fb, value: (0x) 35-0D-34-3A-30-32-42-35-31-46-30-30-30-30-38-43-30-30-0D
...
The relevant (I think) part of the BLECentral Class is:
Code: Select all
if event == _IRQ_SCAN_RESULT:
addr_type, addr, adv_type, rssi, adv_data = data
if decode_name(adv_data) == 'OBDBLE': <----------- Only this 'works'
# if adv_type in (_ADV_IND, _ADV_DIRECT_IND) and _UART_SERVICE_UUID in decode_services(adv_data):
# if _UART_SERVICE_UUID in decode_services(adv_data):
print("uuid - ",decode_services(adv_data))
# Found a potential device, remember it and stop scanning.
self._addr_type = addr_type
self._addr = bytes(
addr
) # Note: addr buffer is owned by caller so need to copy it.
print("Device - ",decode_name(adv_data))
self._name = decode_name(adv_data) or "?"
self._ble.gap_scan(None)
elif event == _IRQ_SCAN_DONE:
if self._scan_callback:
if self._addr:
# Found a device during the scan (and the scan was explicitly stopped).
self._scan_callback(self._addr_type, self._addr, self._name)
self._scan_callback = None
else:
# Scan timed out.
self._scan_callback(None, None, None)
elif event == _IRQ_PERIPHERAL_CONNECT:
# Connect successful.
conn_handle, addr_type, addr = data
if addr_type == self._addr_type and addr == self._addr:
self._conn_handle = conn_handle
self._ble.gattc_discover_services(self._conn_handle)
elif event == _IRQ_PERIPHERAL_DISCONNECT:
# Disconnect (either initiated by us or the remote end).
conn_handle, _, _ = data
if conn_handle == self._conn_handle:
# If it was initiated by us, it'll already be reset.
self._reset()
elif event == _IRQ_GATTC_SERVICE_RESULT:
# Connected device returned a service.
conn_handle, start_handle, end_handle, uuid = data
print("service", bluetooth.UUID(uuid))
if conn_handle == self._conn_handle and uuid == _UART_SERVICE_UUID:
self._start_handle, self._end_handle = start_handle, end_handle
elif event == _IRQ_GATTC_SERVICE_DONE:
# Service query complete.
print("Service done : ",self._start_handle)
if self._start_handle and self._end_handle:
self._ble.gattc_discover_characteristics(
self._conn_handle, self._start_handle, self._end_handle
)
else:
print("Failed to find uart service.")
elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
# Connected device returned a characteristic.
conn_handle, def_handle, value_handle, properties, uuid = data
print("characteristic",uuid)
# printText(str(uuid))
if conn_handle == self._conn_handle and uuid == _UART_RX_CHAR_UUID:
print("rx handle : ",value_handle," - props : ",properties)
self._rx_handle = value_handle
if conn_handle == self._conn_handle and uuid == _UART_TX_CHAR_UUID:
print("tx handle : ",value_handle," - props : ",properties)
self._tx_handle = value_handle
elif event == _IRQ_GATTC_CHARACTERISTIC_DONE:
# Characteristic query complete.
if self._tx_handle is not None and self._rx_handle is not None:
# We've finished connecting and discovering device, fire the connect callback.
if self._conn_callback:
self._conn_callback()
else:
print("Failed to find uart rx characteristic.")
and what I'm getting returned in the REPL is:
Code: Select all
Device - OBDBLE
Found peripheral: 0 b'\xd09r\xa4\xd7\xf6' OBDBLE
service UUID(0x1800)
service UUID(0x1801)
service UUID(0x180a)
service UUID(0xffe0)
Service done : 35
characteristic UUID(0xffe1)
tx handle : 37 - props : 26
characteristic UUID(0xffee)
rx handle : 41 - props : 10
Connected
Why can nrfConnect Mobile connect using the UUIDs and my app can't and yet can connect to my ESP32 using the same UUIDs?