Baffled by Bluetooth - Help

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Baffled by Bluetooth - Help

Post by dougconran » Sun Jul 11, 2021 6:23 pm

I thought I had at least a basic understanding of how Bluetooth LE works, but it appears not.

I'm trying to get an ESP32 TTGO T-display (acting as a central) reading output from an OBDII reader. The OBDII reader advertises a single characteristic with READ, WRITE and NOTIFY properties and, as far as I can tell, most but not all, output is via WRITE and READ.

I'm using @jimmo's ble_simplecentral.py as my starting point and have added _IRQ_GATTC_READ_RESULT and _IRQ_GATTC_READ_DONE to the _irq method. After initialising the OBDII reader the main loop of my program then iterates around first sending a ble.gattc.write (central.write) to the peripheral and then a ble.gattc_read (central.read) to read (I thought) the output from the reader either through a read callback or notify callback.

However, it is not working as planned. The relevant part of my code is:

Code: Select all

    def on_rec(v):
        print("< rec - ",str(v,"utf-8"))

    def on_rx(v):
#        return
        print("< not - ",str(v,"utf-8"))

    central.on_notify(on_rx)
    
    with_response = False
    while central.is_connected():
        cmds = ["ATSH7E4","220101","ATSH7E4","220105","ATSH7E2","2102"]
        for cmd in cmds:
            try:
                v = cmd+"\n"
                print("> write - ", v)
                central.write(v, with_response)
                time.sleep(2)
                print("< loop - ",str(central.value(),"utf-8"))
            except:
                print("TX failed on - ", cmd)
            time.sleep_ms(2000 if with_response else 2000)
            central.read(callback=on_rec)

    print("Disconnected")
and the responses I'm getting back are:

Code: Select all

> write -  ATSH7E4

< data1 =  2 		<-----  print("< data1 = ",str(char_data,"utf-8")) called immediately after _IRQ_GATTC_READ_RESULT:
< rec -  2			<-----  read callback  (note, this is the first character of the previous write cmd [220101])
< not -  ATSH7E4	<-----  notify callback (this is the current write cmd)

< loop -  ATSH7E4	<-----this is the central.value value from after the write cmd  

> write -  220105

< data1 =  A
< rec -  A
< not -  220105

< loop -  220105
once the 220101/220105/2102 cmd is written/sent I should get back a stream of data of approximately 200 bytes. I am not getting anything back as far as I can see although, on a couple of occasions I may have got the first few bytes of a proper return so this may just be down to a timing issue.

However, I had thought that once I had issued a write cmd (which, in my mind, should cause the peripheral to place the required data in the output buffer ready to be pulled up by the subsequent read or notify cmd) I should get the expected data when the _IRQ_GATTC_READ_RESULT irq is detected.

Why am I getting the previous write cmd (not even the current one) and only the first character of it in the read callback and the current write cmd in the notify callback. It is as if there is some sort of queued data waiting to be pulled and I'm slow (or too fast) trying to read it.

Help, someone!

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

Re: Baffled by Bluetooth - Help

Post by jimmo » Mon Jul 12, 2021 3:40 am

dougconran wrote:
Sun Jul 11, 2021 6:23 pm
The OBDII reader advertises a single characteristic with READ, WRITE and NOTIFY properties and, as far as I can tell, most but not all, output is via WRITE and READ.
Are you able to connect with nRF Connect on your phone and confirm?

The most logical arrangement is that a characteristic would be write+notify (i.e. client->server via write, server->client via notify).

But it sounds like what you're saying is that there's no notify? The server->client happens entirely by (polled) reads?

One possibility is that you need to subscribe to the notifications.

I recently published "aioble", which is the "high level" API for working with ubluetooth. It makes stuff like this much easier!
https://github.com/micropython/micropyt ... oth/aioble

I am working on more examples, but here's one that's roughly equivalent to ble_simplecentral.py -- https://github.com/micropython/micropyt ... _client.py

There's built-in suport for subscribing to notifications -- use "await characteristic.subscribe(notify=True)" (note the README is missing the "await" in the example, I'm fixing that now)

(If you haven't use asyncio before there's a learning curve there but it's really well worth the investment. See https://github.com/peterhinch/micropyth ... /README.md

Feedback welcome -- this is a new library but we've used it in a few projects now and given it quite a workout.

dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Re: Baffled by Bluetooth - Help

Post by dougconran » Mon Jul 12, 2021 12:09 pm

Many thanks for a very full reply some of which I can give straightforward answers to others may be a bit more long-winded.

I have connected to the OBDII reader using nrfConnect (mobile) and it is showing a single characteristic with READ, WRITE and NOTIFY properties, is that what you meant by 'have I used nrfConnect'?

---- EDIT ---- I've just rechecked with nrfConnect and it looks as though I missed a characteristic :( I need to do a lot more checking before I follow up on this.

Secondly, I saw your suggestion to use aioble in a different post but the documentation says that it requires MP v1.15 (at least) whereas, at the moment, I'm using Russ Hughes version of v1.14 because I need to write to a ST7789 display.

Thirdly, I have subscribed to notifications but, based on your comments, I'm beginning to wonder whether I have a fundamental misunderstanding of how BLE works.

As I understand it, the peripheral is a fairly dumb bit of electronics that just dumps values in a buffer or stack and sends an interrupt to the client to say that there is some data there. The client either just reacts to these interrupts and pulls whatever is there or, first, sends a write command to the peripheral to say what data it wants (as in the case of the OBDII device) and then does the pull on receipt of an interrupt. I had assumed that, because the OBDII advertises only a single characteristic, utilised for both read/notify and write commands, that only one channel (buffer/stack) and char_handle are used for data going in both directions. Is that right? Or should there still be 2 handles, one for tx and one for rx, even although there is only a single characteristic? Is that why the write command data is appearing in the notify callback?

I guess that my question boils down to:-

When a peripheral has only a single characteristic which encompasses both read and write properties does it return separate tx and an rx handles in the _IRQ_GATTC_CHARACTERISTIC_RESULT interrupt or does it return just a single txrx handle. (I could, of course, just try it myself but I'm not sure that I could correctly evaluate the returns.)
Last edited by dougconran on Mon Jul 12, 2021 2:06 pm, edited 1 time in total.

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

Re: Baffled by Bluetooth - Help

Post by jimmo » Mon Jul 12, 2021 1:56 pm

dougconran wrote:
Mon Jul 12, 2021 12:09 pm
I have connected to the OBDII reader using nrfConnect (mobile) and it is showing a single characteristic with READ, WRITE and NOTIFY properties, is that what you meant by 'have I used nrfConnect'?
Yep, but I was wondering if you'd tried subscribing and doing a data request (and response) to confirm that it behaves the way you expect.
dougconran wrote:
Mon Jul 12, 2021 12:09 pm
Secondly, I saw your suggestion to use aioble in a different post but the documentation says that it requires MP v1.15 (at least) whereas, at the moment, I'm using Russ Hughes version of v1.14 because I need to write to a ST7789 display.
Ah... If you're doing BLE stuff I do recommend updating to 1.16 because there are a few other fixes. I haven't heard of this version before, but I assume it's https://github.com/russhughes/st7789_mp ... -and-later (in which case it might "just work" if you compile it against 1.16).
dougconran wrote:
Mon Jul 12, 2021 12:09 pm
As I understand it, the peripheral is a fairly dumb bit of electronics that just dumps values in a buffer or stack and sends an interrupt to the client to say that there is some data there.
That's right. Minor clarification that "peripheral" and "gatt server" (i.e. gatts) are actually two orthogonal concepts in BLE, although the peripheral is typically the server.

A characteristic is the buffer owned by the server, and like you say, a client can read from or write to the buffer.

When the server wants to tell the client that the buffer has changed, it can either:
a) Notify with an empty value (then the client should read the latest value)
b) Notify with a value (which can be distinct to the current buffer value)
dougconran wrote:
Mon Jul 12, 2021 12:09 pm
The client either just reacts to these interrupts and pulls whatever is there or, first, sends a write command to the peripheral to say what data it wants (as in the case of the OBDII device) and then does the pull on receipt of an interrupt.
There are kind of two distinct layers here. BLE (GATT) only provides the simple read/write/notify system. The interpretation of this is entirely up to the higher level application.

The two approaches I've seen most commonly:
a) The client writes a command to the characteristic. Then the server clears the characteristic, and responds with the result data entirely in the notification.
b) The client writes a command to the characteristic. Then the server replaces the characteristic value with the result and sends a blank notification.

I've also seen this split over multiple characteristics. For example the Nordic UART Service uses a distinct TX and RX characteristic.
dougconran wrote:
Mon Jul 12, 2021 12:09 pm
I had assumed that, because the OBDII advertises only a single characteristic, utilised for both read/notify and write commands, that only one channel (buffer/stack) and char_handle are used for data going in both directions. Is that right? Or should there still be 2 handles, one for tx and one for rx, even although there is only a single characteristic? Is that why the write command data is appearing in the notify callback?
That is right -- there's one handle per characteristic, regardless of how many operations it supports.

Do you have any reference documentation for the OBDII-over-BLE protocol that I can take a look at.

dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Re: Baffled by Bluetooth - Help

Post by dougconran » Mon Jul 12, 2021 11:17 pm

Wow! That is a very comprehensive reply considering that I'd goofed up and needed to do some more testing. It is late here (UK) and so I will respond properly tomorrow but, many thanks for your input and the time you are taking on this.

dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Re: Baffled by Bluetooth - Help

Post by dougconran » Tue Jul 13, 2021 11:33 am

jimmo wrote:
Mon Jul 12, 2021 1:56 pm
dougconran wrote:
Mon Jul 12, 2021 12:09 pm
I have connected to the OBDII reader using nrfConnect (mobile) and it is showing a single characteristic with READ, WRITE and NOTIFY properties, is that what you meant by 'have I used nrfConnect'?
That, of course was an error on my part. The OBDII reader has 2 characteristics, the second one is READ, WRITE.
jimmo wrote:
Mon Jul 12, 2021 1:56 pm
Ah... If you're doing BLE stuff I do recommend updating to 1.16 because there are a few other fixes. I haven't heard of this version before, but I assume it's https://github.com/russhughes/st7789_mp ... -and-later (in which case it might "just work" if you compile it against 1.16).
That's going to be a whole new learning experience for me! - But this is all about learning :) .
jimmo wrote:
Mon Jul 12, 2021 1:56 pm
The two approaches I've seen most commonly:
a) The client writes a command to the characteristic. Then the server clears the characteristic, and responds with the result data entirely in the notification.
b) The client writes a command to the characteristic. Then the server replaces the characteristic value with the result and sends a blank notification.

I've also seen this split over multiple characteristics. For example the Nordic UART Service uses a distinct TX and RX characteristic.
I'm beginning to understand that there are 2 fundamental parts to this:- One is understanding how the OBDII reader is using BLE to communicate and the other is understanding how to use the code to enable that communication. Like I say, it is all a learning experience!
jimmo wrote:
Mon Jul 12, 2021 1:56 pm
Do you have any reference documentation for the OBDII-over-BLE protocol that I can take a look at.
There is detailed documentation on the ELM327 (the chip that talks to the car) but little to nothing as far as I can find on the use of BLE to communicate outwards. The problem is that, like so many things, the dongle itself is (generally) a Chinese product with no information. As it happens one manufacturer is American who do provide a support email address. I have contacted them but got a simple boiler plate reply. I will, however, contact them again with more specific questions.

I have tried, again, using nrfConnect mobile to connect to the OBDII with little success although that may well be down to my lack of understanding of how to use it. The first command to send to the OBDII is ATZ to initialise it and that returns (or should return) the ELM version no. I have not yet succeeded in getting that initial response although I know that the dongle works because I can conduct a complete dialogue with it using a Bluetooth serial terminal.

So, I think that the first thing for me to do is to get a response using nrfConnect. Only once I've achieved that is it worth trying to get the ESP32 to communicate.

I do, though, have one further question. I have built a simple OBDII emulator to (supposedly!) mimic the real thing as it is a pain having to go out to the car all the time. But, try as I might, I can only get it to transmit up to 20 characters at a time (at least, that is all that are received). It may be that the OBDII will transmit more (it does to the BT serial terminal) but is there a way in MP v1.16 to force a gatts_write/notify to to send more than 20 chars?

As always, many thanks for your help and insights.

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

Re: Baffled by Bluetooth - Help

Post by jimmo » Tue Jul 13, 2021 12:19 pm

dougconran wrote:
Tue Jul 13, 2021 11:33 am
That's going to be a whole new learning experience for me! - But this is all about learning .
OK let us know how you go.
dougconran wrote:
Tue Jul 13, 2021 11:33 am
I have not yet succeeded in getting that initial response although I know that the dongle works because I can conduct a complete dialogue with it using a Bluetooth serial terminal.
OK that's interesting... so this suggests that it's using something like the Nordic Uart Service then... maybe could you send a screenshot of the nRF Connect screen that shows the services and characteristics.

Unfortunately I haven't published example code for the client side of NUS... although I do have a WIP script somewhere from when I was developing the server side for examples/ble_uart_peripheral.py
dougconran wrote:
Tue Jul 13, 2021 11:33 am
So, I think that the first thing for me to do is to get a response using nrfConnect. Only once I've achieved that is it worth trying to get the ESP32 to communicate.
Yeah I think so... even though entering payloads into nRF Connect is a bit painful, it's certainly illuminating.
dougconran wrote:
Tue Jul 13, 2021 11:33 am
I do, though, have one further question. I have built a simple OBDII emulator to (supposedly!) mimic the real thing as it is a pain having to go out to the car all the time. But, try as I might, I can only get it to transmit up to 20 characters at a time (at least, that is all that are received). It may be that the OBDII will transmit more (it does to the BT serial terminal) but is there a way in MP v1.16 to force a gatts_write/notify to to send more than 20 chars?
I'm guessing the simulator is a peripheral/server also written in MicroPython?

There are two things you need to adjust:
a) The default GATT MTU is quite small. You can use ble.config(mtu=N) to set it to a larger value (on both the central/client and peripheral/server before connecting) -- the negotiated MTU will be the minimum of the two device's value.
b) When the server creates a characteristic, the size of the internal buffer is (you guessed it) 20 bytes. When the client writes the value, anything larger than this will be truncated. In your peripheral/server code, use ble.gatts_set_buffer(value_handle, N) to increase it.

dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Re: Baffled by Bluetooth - Help

Post by dougconran » Tue Jul 13, 2021 1:31 pm

jimmo wrote:
Tue Jul 13, 2021 12:19 pm
OK that's interesting... so this suggests that it's using something like the Nordic Uart Service then... maybe could you send a screenshot of the nRF Connect screen that shows the services and characteristics.
Here (I hope ) is a screen scrape of of the nrfConnect screen
jimmo wrote:
Tue Jul 13, 2021 12:19 pm
I'm guessing the simulator is a peripheral/server also written in MicroPython?
Yes
jimmo wrote:
Tue Jul 13, 2021 12:19 pm
There are two things you need to adjust:
a) The default GATT MTU is quite small. You can use ble.config(mtu=N) to set it to a larger value (on both the central/client and peripheral/server before connecting) -- the negotiated MTU will be the minimum of the two device's value.
b) When the server creates a characteristic, the size of the internal buffer is (you guessed it) 20 bytes. When the client writes the value, anything larger than this will be truncated. In your peripheral/server code, use ble.gatts_set_buffer(value_handle, N) to increase it.
I've tried all of those. MTU and RXBUF are configured to 500 and report that length back on both the peripheral and central. I've added ble.gatts_set_buffer to 200 for both the rx & tx handles (picked up from another MP forum thread [probably answered by you!])

Code: Select all

class BLESimplePeripheral:
    def __init__(self, ble, name="BLEOBD"):
        self._ble = ble
        self._ble.active(True)
        self._ble.irq(self._irq)
        ((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
        ble.config(mtu=500)
        ble.config(rxbuf=500)
        self._ble.gatts_set_buffer(self._handle_tx, _MAX_NB_BYTES, False)  #  _MAX_NB_BYTES = 200
        self._ble.gatts_set_buffer(self._handle_rx, _MAX_NB_BYTES, False)
        self._ble.gatts_write(self._handle_tx, bytes(_MAX_NB_BYTES))
        self._ble.gatts_write(self._handle_rx, bytes(_MAX_NB_BYTES))
        self._connections = set()
        self._write_callback = None
        self._payload = advertising_payload(name=name, services=[_UART_UUID])
        self._advertise()
and, still, I'm only getting 20 chars at the central :( When I can communicate with the OBDII reader I will see what I get then but, like I say, the BT serial terminal returns the full set of data (varies but about 150 bytes).

I know this is all about MP and BLE but, for clarity, when sending text using nfrConnect I'm tapping the up arrow of the characteristic (each of them) to send ATZ (text) and then pressing the down arrow to get the result. I can't remember which characteristic gave which return but one gave 3E 0D 0D 3F when I would have expected 'ELM327 v1.5<0D><0D>' and the other gave just the first character of the text that I'd sent. Looking in the log file didn't shed any further light.

One further question, would it make any difference using a 16 bit UUID rather than a 128 bit one? I've tried both and it didn't seem to make a difference.

Oh, I've just realised that the 3E 0D 0D 3F would be a > ? which is, I think, the ELM327 saying that it doesn't understand the command. might that either be tied in with one of the characteristics returning just the first letter of the command or maybe the input command not being terminated by a carriage return (don't know how nrfConnect handles text input).
Attachments
nrfConnect.jpg
nrfConnect.jpg (90.56 KiB) Viewed 3855 times

dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Re: Baffled by Bluetooth - Help

Post by dougconran » Tue Jul 13, 2021 8:49 pm

I've managed to upgrade to MP v1.16 using Russ Hughes separate ST7789py.py library. It does not display as fast as the embedded version but it is good enough for my purposes. So, this would enable me to use aioble but, what would be the advantage of using that given that, between my 2 ESP32s I have BLE working, the area I'm struggling with is getting my central code to communicate with the OBDII reader. (and the fixed write buffer length of 20 chars, of course)

dougconran
Posts: 27
Joined: Sat Jul 03, 2021 5:10 pm

Re: Baffled by Bluetooth - Help

Post by dougconran » Sun Jul 18, 2021 4:07 pm

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?

Post Reply