BLE : gattc_write cannot write more than 20 bytes ?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Posts: 3
Joined: Mon Mar 15, 2021 5:51 pm

BLE : gattc_write cannot write more than 20 bytes ?

Post by Yannick » Thu May 06, 2021 9:53 am


I am currently working on an adaptation of the BLE UART code given here ...

But I am facing what seems to me a bug in features of ... tooth.html.
I can't manage to lift the limit of 20 char payload in a characteristic.

Followin explantions given in the lib description :
Characteristics and descriptors have a default maximum size of 20 bytes. Anything written to them by a client 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 client to a given characteristic, use gatts_write after registration. e.g. gatts_write(char_handle, bytes(100)).
BLE.gatts_set_buffer(value_handle, len, append=False, /)
Sets the internal buffer size for a value in bytes. This will limit the largest possible write that can be received. The default is 20.
Setting append to True will make all remote writes append to, rather than replace, the current value. At most len bytes can be buffered in this way. When you use gatts_read, the value will be cleared after reading. This feature is useful when implementing something like the Nordic UART Service.

I added these bold lines to my code :

Code: Select all

	def __init__(self, ble, name="mpy-uart"):
		self._ble = ble

		((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
		[b]self._ble.gatts_set_buffer(self._handle_tx, _MAX_NB_BYTES, False)[/b]
		[b]self._ble.gatts_set_buffer(self._handle_rx, _MAX_NB_BYTES, False)[/b]
		[b]self._ble.gatts_write(self._handle_tx, bytes(_MAX_NB_BYTES))[/b]
		[b]self._ble.gatts_write(self._handle_rx, bytes(_MAX_NB_BYTES))[/b]

		self._connections = set()
		self._write_callback = None
		self._payload = advertising_payload(name=name, services=[_UART_UUID])

But it doesn't work !
No error reported, script is running, but reads into Rx from peripheral side are still truncated to 20 char ...
Can you help please ?
Last edited by Yannick on Fri May 07, 2021 8:00 pm, edited 6 times in total.

User avatar
Posts: 64
Joined: Thu Oct 03, 2019 2:26 am

Re: How to go betyond 20 char payload in a characteristic ?

Post by russ_h » Thu May 06, 2021 4:11 pm

The 'MTU' (max transmission unit) defaults to 20. Have you tried changing it using BLE.config as described ... tooth.html?

Posts: 3
Joined: Mon Mar 15, 2021 5:51 pm

BLE : gattc_write cannot write more than 20 bytes ?

Post by Yannick » Thu May 06, 2021 5:40 pm

Thanks !

Unfortunately, this feature doesn't seem to be implemented yet on my hardware (STM32 NUCLEO-WB55 board).
I tried several synthaxes ...

for ex :

Code: Select all

... but none worked, all thrown a "unknown config param message." :cry:

In the meantime I progressed. I added this code in peripheral py script :

Code: Select all

self._ble.gatts_set_buffer(self._handle_rx, _MAX_NB_BYTES, True)
I then connected the peripheral with a (smartphone + NRF Connect) as a central, and this worked ; from NRF Connect, I managed to write more than 20 char in the RX CHAR of the peripheral by setting _MAX_NB_BYTES = 100 for example.

So, the problem seems to be on the central side inside ... , when I install it in my second NUCLEO-WB55 board to make it the central instead of (smartphone + NRF Connect).

More specifically, it seems that the problem is coming from this row :

Code: Select all

self._ble.gattc_write(self._conn_handle, self._rx_handle, v, 1 if response else 0)
Whatever I do,

Code: Select all

only writes 20 bytes inside v ...

Post Reply