Problem-xiao nrf52840 board bleuart send size over 20 bytes

problem to send 40bytes from xiao nrf52840 to another xiao nrf52840 board.

I’m sending 40 bytes but receiver can’t receive whole packet.
It sends like this
bleuart.write( sensor_packet_tx, 40);

But receiver board receives first 20bytes and last 20 bytes.
uart_svc.available() returns 20 always.

How can I receive 40bytes at one time?

Hi there, mdexdev01

So the maximum size of a single data packet for BLE 4.0 is 23 bytes. This includes 20 bytes of data and a 3-byte protocol wrapper. The maximum allowed length of an attribute value (the ATT payload) is 512 bytes. that being said,
The default MTU size for ArduinoBLE is 32 bytes, but it can be negotiated up to 256 bytes after the connection has been made. The MTU size is usually set during connection establishment with the “MTU Request” command.
Afaik the maximum number of bytes that can be sent in one packet using BLE on the Arduino Nano 33 BLE Sense board is usually 20, unless you enable the extension on both ends.
GL :slight_smile: PJ

here is some of my code snips for a project sending the string over BLE

BLEService systemStatusService("19B1000C-E8F2-537E-4F6C-D104768A1214"); // UUID for the service
BLEStringCharacteristic systemStatusCharacteristic("19B1000B-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite, 200 ); // UUID for the characteristic

if (central) {
      // Send the system status string to the central when the characteristic is read
       if (systemStatusCharacteristic.written()) {

String createStatusString() {  // Function to create the status string
  String statusString = __DATE__ " at " __TIME__ "," + BleId;  //("Test program compiled on " __DATE__ " at "__TIME__);

  if (imuParked) {
    statusString += "Parked,";
  } else {
    statusString += "Not parked,";
  if (droppedFlag) {
    statusString += "DROPPED,";
  } else {
    statusString += "Not dropped,";
  if (motionAlarm) {
    statusString += "Motion alarm ON,";
  } else {
    statusString += "Motion alarm OFF,";
  if (freeFallalarm) {  //enableFallDetection on or off
    statusString += "Drop alarm ON,";
  } else {
    statusString += "Drop alarm OFF,";
  if (tapToOpen) {
    statusString += "Tap to open ON,(" + tapsNumber + ")TAPS," ;
  } else {
    statusString += "Tap to open OFF,";  
  statusString += "Battery level 92%," + imuOrientation + "," + imutemperature + ";";  //+ ",";  // batteryLevel

  return statusString;

Here’s what the Serial OUTput looks like, The Android MIT AI app displays the string sent on the Phone.

System status:
Apr 17 2023 at 17:38:18,Not parked,Not dropped,Motion alarm ON,Drop alarm OFF,Tap to open ON,(2)TAPS,Battery level 92%,SIDEWAYS LEFT,86.96°;

Advertising Bluetooth Device
  as: ABodyGuard F02B

I don’t need to send a string but a binary data.

As I know nrf52840 is based on the BLE 5.3
So it must be no problem that send upto near 500 bytes per one packet.
It was possible by the ESP32 S3 (BLE 5 IC)
Does Seeed provide Arduino api transferring this kind of long binary data curretly?

Hello mdexdev01,
which board and BLE Library are you using on your Seeed Xiao nrf52840?

While the “non-embed” + Bluefruit setup seem to restrict maximal packet size to 20 bytes (and also the different BLE Test Apps seem to adhere to this) i was able to send longer messages from an Seeed Xiao nrf52840 running th mbed board and using the ArduinoBLE to an esp32 using the ArduinoBLE.
If that is a feature or a bug i don´t know as of now.

I didn´t try to setup the server on a Seeed Xiao nrf52840 as well though - but maybe you can give it a shot if you were running on "non-embed + Bluefruit so far.

Hi mdexdev01,
In the Bluefruit sample sketch “throughput.ino”, there is an example of changing the MTU from the default value of 20 to the maximum value of 247. I tried it and it works fine.


Try this. (5.0 KB)

The following link is an example of using this technique. For your reference
XIAO nRF52840, Efficiently Uploads Peripheral On-Board Flash ROM Data to Central

  1. Run PHY at 2 MHz :heart_eyes: