ESP32 : Sending String via Bluetooth

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
MaFr
Posts: 11
Joined: Sun Feb 02, 2020 3:52 pm

ESP32 : Sending String via Bluetooth

Post by MaFr » Sat Feb 08, 2020 1:21 pm

I use the bluetooth to send a string:

Code: Select all

    def send(self, d):
        self._ble.gatts_set_buffer(self._handle, 10000)
        dp = chr(2) + d + chr(3)
        p = str.encode(dp)
        for c in p:
            packet = struct.pack('<h', c)
            self._ble.gatts_write(self._handle, packet)

            for conn_handle in self._connections:
                # Notify connected centrals to issue a read.
                self._ble.gatts_notify(conn_handle, self._handle)
                time.sleep_ms(10)
Actually its working great, but one thing is really a bit annoying as it creates for each packet a print output in the terminal:

Code: Select all

GATT procedure initiated: notify; att_handle=13
GATT procedure initiated: notify; att_handle=13
.....
Is it possible to suppress those print messages or is there a better way of sending strings?
Thank you very much for help.
Last edited by MaFr on Sun Feb 09, 2020 9:19 am, edited 1 time in total.

MaFr
Posts: 11
Joined: Sun Feb 02, 2020 3:52 pm

Re: GATT procedure initiated: notify; att_handle=13

Post by MaFr » Sat Feb 08, 2020 7:22 pm

I updated my send function in the meanwhile as follows:

Code: Select all

    def send(self, d):
        self._ble.gatts_set_buffer(self._handle, 1000)
        p = str.encode(d)
        for conn_handle in self._connections:
            # Notify connected centrals to issue a read.
            self._ble.gatts_notify(conn_handle, self._handle, p)
            time.sleep_ms(10)
With the function it is now possible to send a string. But I noticed it can not be longer than 20 characters - whatever I put as parameter in gatts_set_buffer. I tried with several buffer_length and also with append True and False...
Update: I should mention that I'm working with ESP32..

Any help appreciated....Thank you.

MaFr
Posts: 11
Joined: Sun Feb 02, 2020 3:52 pm

Re: ESP32 : Sending String via Bluetooth

Post by MaFr » Sun Feb 09, 2020 10:49 am

In the documentation I found the following information:
Characteristics and descriptors have a default maximum size of 20 bytes. Anything written to them by a central will be truncated to this length. However, any local write will increase the maximum size, so if you want to allow larger writes from a central to a given characteristic, use gatts_write after registration. e.g. gatts_write(char_handle, bytes(100)).
However, by using ESP32 I couldn't send a string longer than 20 characters/bytes. I tried several alternatives (refer above). Also I tried someting like:

Code: Select all

s = "This is my little test string, which doesn't seem to be transmitted in full length"
p = str.encode(s)
gatts_write(char_handle, p).
For the moment I ended up with the following function.

Code: Select all

    def send(self, d):
        self._ble.gatts_set_buffer(self._handle, 1000)
        dp = chr(2) + d + chr(3)
        p = str.encode(dp)
        for x in range(0, len(p), 20):
            self._ble.gatts_write(self._handle, p[x:x+20])
            
            for conn_handle in self._connections:
                # Notify connected centrals to issue a read.
                self._ble.gatts_notify(conn_handle, self._handle)
                time.sleep_ms(10)
So, actually it splits the string into chunks of 20 bytes and sending them one by one. Also, I add chr(2) and char(3) as an identifier for the host to recognize start and end of the string...This function reduces the number of transactions and also the number of print outputs, which was my original issue :-)
GATT procedure initiated: notify; att_handle=13
However, it would be great to turn them off.....

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

Re: ESP32 : Sending String via Bluetooth

Post by jimmo » Sun Feb 09, 2020 1:23 pm

I don't believe it's possible to send a notify longer than the MTU, so this means the notify payload can't be longer than 20.

However, a write with a larger payload should work. Then the gatt client will read the whole thing (in chunks as necessary, depending on the MTU).

You should just be able to gatts_write the entire length (set_buffer not necessary - that's mostly only required for receiving data, especially if you need to enable append mode), then notify.

i.e.

Code: Select all

p = long payload greater than 20 bytes
gatts_write(char_handle, p)
for c in connections:
  gatts_notify(c, char_handle)
Well, that's the intention at least. I will have to test this out for myself (tomorrow) to investigate. Perhaps we will need to make the MTU configurable from Python.

What sort of device is at the other end (i.e. the gatt client / central)?

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

Re: ESP32 : Sending String via Bluetooth

Post by jimmo » Sun Feb 09, 2020 1:28 pm

The log messages come from the ESP32 IDF.
I think some of these messages can't be turned off due to bugs with the way the IDF log level checking works, but there is some control of this using esp.osdebug

e.g.

Code: Select all

import esp
esp.osdebug(esp.LOG_NONE)
I don't normally use esp32 other than when I was working on BLE support. I remember I found the logging fairly inconsistent. I'll double check when I check the write truncation tomorrow.

MaFr
Posts: 11
Joined: Sun Feb 02, 2020 3:52 pm

Re: ESP32 : Sending String via Bluetooth

Post by MaFr » Tue Feb 11, 2020 4:34 pm

Nope, on my ESP32 the parameter "esp.LOG_NONE" can not hide those messages mentioned. But, thank you for the hint.

Regarding the long payload greater than 20 bytes I can not confirm. I'm working on an application at ESP32, which is reporting to a smartphone. Its a Google Flutter application. Currently I'm testing the Android part of it.

I was trying something like ...

Code: Select all

s = "This is my little test string, which doesn't seem to be transmitted in full length"
p = str.encode(s)
gatts_write(char_handle, p).
for c in connections:
  gatts_notify(c, char_handle)
,,, but this was not working at ESP32. It still cuts the tx to 20 characters. I hope I didnt miss the point here...

Thank you very much again for having a look and helping me out.

Post Reply