<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[I don&#x27;t know how to send a lot of data per time by BLE(Bluetooth low energy)]]></title><description><![CDATA[<p dir="auto">Hi,<br />
I'd like to send IMU sensor data which is gotten by one M5Stack to the other. The other M5Stack is in a few meters from one.<br />
To achieve above, now I think use of BLE(Bluetooth Low Energy)(*1).<br />
I'll connect two M5Stacks and send the data as data packet.</p>
<p dir="auto">I know ESP32 which is in M5Stack enables use of Bluetooth 4.2(*2) and we can send 251 bytes(actually 246bytes because of consumption by some protocols) per time by  Bluetooth 4.2(*3).<br />
I tried, but I can't as expected. I don't know why. The problems are below.</p>
<p dir="auto">・In the case of send and receive over 20 bytes, M5Stack receive data which is over 20bytes as zero.<br />
・I defined data type as uint8, so I expected 1byte per one param, but actually 4bytes per one param. Did I do something wrong?</p>
<p dir="auto">Environment<br />
Device: M5Stack GRAY<br />
IDE: Arduino IDE</p>
<p dir="auto">*1 I know also ESP-NOW, but if I can use BLE, I'd like to use BLE considering security.<br />
*2 <a href="https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf" target="_blank" rel="noopener noreferrer nofollow ugc">https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf</a><br />
*3 <a href="https://www.bluetooth.com/" target="_blank" rel="noopener noreferrer nofollow ugc">https://www.bluetooth.com/</a></p>
<p dir="auto">Result<br />
<img src="/assets/uploads/files/1640173036658-result_cliant-resized.png" alt="0_1640173035215_Result_cliant.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">Coder for Server</p>
<pre><code>#define M5STACK_MPU6886
#include &lt;M5Stack.h&gt;
#include &lt;BLEDevice.h&gt;
#include &lt;BLEServer.h&gt;
#include &lt;BLE2902.h&gt;

/* device name */
#define DEVICE_NAME "ESP32"

/* UUID difinition */
#define SERVICE_UUID           "28b0883b-7ec3-4b46-8f64-8559ae036e4e"  // service UUID
#define CHARACTERISTIC_UUID_TX "2049779d-88a9-403a-9c59-c7df79e1dd7c"  // UUID for send 

/* for control connection */
BLECharacteristic *pCharacteristicTX;   // characteristic for send
bool  deviceConnected = false;          // device connection status
bool  bAbnormal  = false;               // to call abnormal

/* connection data */
struct tmpData {
  int   time_get;
  int   accX_send;
  int   accY_send;
  int   accZ_send;
  int   gyroX_send;
  int   gyroY_send;
  int   gyroZ_send;
  int   pitch_send;
  int   roll_send;
  int   yaw_send;
};

struct tmpData  data;

/* IMU 9 params definition */
float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;

float gyroX = 0.0F;
float gyroY = 0.0F;
float gyroZ = 0.0F;

float pitch = 0.0F;
float roll  = 0.0F;
float yaw   = 0.0F;

/* get time */
int time_get;

/* Callback when conncet and break */
class funcServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    }
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

/* make characteristic for Notify */
void doPrepare(BLEService * pService) {
  pCharacteristicTX = pService-&gt;createCharacteristic(
                        CHARACTERISTIC_UUID_TX,
                        BLECharacteristic::PROPERTY_NOTIFY
                      );
  pCharacteristicTX-&gt;addDescriptor(new BLE2902());
}

// Function for send data
void sendData() {
  if (isnan(accX) || isnan(accY) || isnan(accZ)) {
    Serial.println("Failed to read sensor!");
    return;
  }
  // set value to struct and send
  data.time_get = time_get;
  data.accX_send = (int)(accX * 100);
  data.accY_send = (int)(accY * 100);
  data.accZ_send = (int)(accZ * 100);
  data.gyroX_send = (int)(gyroX * 100);
  data.gyroY_send = (int)(gyroY * 100);
  data.gyroZ_send = (int)(gyroZ * 100);
  data.pitch_send = (int)(pitch * 100);
  data.roll_send = (int)(roll * 100);
  data.yaw_send = (int)(yaw * 100);
  pCharacteristicTX-&gt;setValue((uint8_t*)&amp;data, sizeof(tmpData));
  pCharacteristicTX-&gt;notify();
  
  delay(5);
}

void setup() {
  M5.begin(); //Init M5Stack.
  M5.Power.begin(); //Init power.
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextSize(3);

  M5.IMU.Init();
  BLEDevice::init(DEVICE_NAME);

  // make service object and set Callback
  BLEServer *pServer = BLEDevice::createServer();
  pServer-&gt;setCallbacks(new funcServerCallbacks());

  // make service object and prepare(make characteristic for Notify)
  BLEService *pService = pServer-&gt;createService(SERVICE_UUID);
  doPrepare(pService);

  // start service and advertise
  pService-&gt;start();
  BLEAdvertising *pAdvertising = pServer-&gt;getAdvertising();
  pAdvertising-&gt;addServiceUUID(SERVICE_UUID);
  pAdvertising-&gt;start();

}

void loop() {
  M5.IMU.getAccelData(&amp;accX, &amp;accY, &amp;accZ);
  M5.IMU.getGyroData(&amp;gyroX, &amp;gyroY, &amp;gyroZ);
  M5.IMU.getAhrsData(&amp;pitch, &amp;roll, &amp;yaw);
  time_get = millis();

  delay(5);
  // set data and send
  sendData();
  delay(1000);
}
</code></pre>
<p dir="auto">Code for Cliant</p>
<pre><code>#include &lt;M5Stack.h&gt;
#include &lt;BLEDevice.h&gt;
#include &lt;Wire.h&gt;                   // For I2C interface

/* UUID difinition */
BLEUUID serviceUUID("28b0883b-7ec3-4b46-8f64-8559ae036e4e");   // service UUID
BLEUUID CHARA_UUID_RX("2049779d-88a9-403a-9c59-c7df79e1dd7c"); // UUID of RX

/* for control connection */
BLERemoteCharacteristic* pRemoteCharacteristicRX;  // Characteristic for receive
BLEAdvertisedDevice* targetDevice;      // target BLE device
bool  doConnect = false;                // connection cue
bool  doScan = false;                   // scan cue
bool  deviceConnected = false;          // connection status of device
bool  bInAlarm  = false;
bool  enableMeasurement = false;

/* connection data */
struct tmpData {
  int   time_get_rcv;
  int   accX_rcv;
  int   accY_rcv;
  int   accZ_rcv;
  int   gyroX_rcv;
  int   gyroY_rcv;
  int   gyroZ_rcv;
  int   pitch_rcv;
  int   roll_rcv;
  int   yaw_rcv;
};
struct tmpData  data;

char* time_get_rcv;
char* accX_rcv;
char* accY_rcv;
char* accZ_rcv;
char* gyroX_rcv;
char* gyroY_rcv;
char* gyroZ_rcv;
char* pitch_rcv;
char* roll_rcv;
char* yaw_rcv;

/*********************&lt; Callback classes and functions &gt;**********************/
/* Callback when connect and break */
class funcClientCallbacks: public BLEClientCallbacks {
    void onConnect(BLEClient* pClient) {
    };
    void onDisconnect(BLEClient* pClient) {
      deviceConnected = false;
    }
};

/* Callback when receive advertising */
class advertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.print("Advertised Device found: ");
      Serial.println(advertisedDevice.toString().c_str());

      /* stop scan and prepare connect if target BLE device*/
      if (advertisedDevice.haveServiceUUID()) {
        BLEUUID service = advertisedDevice.getServiceUUID();
        Serial.print("Have ServiceUUI: "); Serial.println(service.toString().c_str());
        if (service.equals(serviceUUID)) {
          BLEDevice::getScan()-&gt;stop();
          targetDevice = new BLEAdvertisedDevice(advertisedDevice);
          doConnect = doScan = true;
        }
      }
    }
};

/* Callback Function of Notify */
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
                           uint8_t* pData, size_t length, bool isNotify) {
    M5.Lcd.setCursor(0, 20);
    M5.Lcd.print("Received");

  memcpy(&amp;data, pData, length);
  int tm = data.time_get_rcv;
  float xx = data.accX_rcv / 100.00;
  float yy = data.accY_rcv / 100.00;
  float zz = data.accZ_rcv / 100.00;
  float gx = data.gyroX_rcv / 100.00;
  float gy = data.gyroY_rcv / 100.00;
  float gz = data.gyroZ_rcv / 100.00;
  float pc = data.pitch_rcv / 100.00;
  float rl = data.roll_rcv / 100.00;
  float yw = data.yaw_rcv / 100.00;

  static char time_get_rcv_char[10];
  static char accX_rcv_char[10];
  static char accY_rcv_char[10];
  static char accZ_rcv_char[10];
  static char gyroX_rcv_char[10];
  static char gyroY_rcv_char[10];
  static char gyroZ_rcv_char[10];
  static char pitch_rcv_char[10];
  static char roll_rcv_char[10];
  static char yaw_rcv_char[10];

  sprintf(time_get_rcv_char, "%d", tm);
  sprintf(accX_rcv_char, "%5.2f", xx);
  sprintf(accY_rcv_char, "%5.2f", yy);
  sprintf(accZ_rcv_char, "%5.2f", zz);
  sprintf(gyroX_rcv_char, "%5.2f", gx);
  sprintf(gyroY_rcv_char, "%5.2f", gy);
  sprintf(gyroZ_rcv_char, "%5.2f", gz);
  sprintf(pitch_rcv_char, "%5.2f", pc);
  sprintf(roll_rcv_char, "%5.2f", rl);
  sprintf(yaw_rcv_char, "%5.2f", yw);

  time_get_rcv = (char*)time_get_rcv_char;
  accX_rcv = (char*)accX_rcv_char;
  accY_rcv = (char*)accY_rcv_char;
  accZ_rcv = (char*)accZ_rcv_char;
  gyroX_rcv = (char*)gyroX_rcv_char;
  gyroY_rcv = (char*)gyroY_rcv_char;
  gyroZ_rcv = (char*)gyroZ_rcv_char;
  pitch_rcv = (char*)pitch_rcv_char;
  roll_rcv = (char*)roll_rcv_char;
  yaw_rcv = (char*)yaw_rcv_char;
    
  enableMeasurement = true;
  Serial.print( millis() );
  Serial.print(" ");
  Serial.print("Received data: ");
  Serial.print(time_get_rcv);
  Serial.print(", ");
  Serial.print(accX_rcv);
  Serial.print(", ");
  Serial.print(accY_rcv);
  Serial.print(", ");
  Serial.print(accZ_rcv);
  Serial.print(", ");
  Serial.print(gyroX_rcv);
  Serial.print(", ");
  Serial.print(gyroY_rcv);
  Serial.print(", ");
  Serial.print(gyroZ_rcv);
  Serial.print(", ");
  Serial.print(pitch_rcv);
  Serial.print(", ");
  Serial.print(roll_rcv);
  Serial.print(", ");
  Serial.println(yaw_rcv);
  
  return;
}

/*****************************************************************************
                            Predetermined Sequence
 *****************************************************************************/
void setup() {
  M5.begin();
  M5.Power.begin(); //Init power.
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextSize(3);
  
  BLEDevice::init("");
  Serial.println("Client application start...");

  // get Scan object and set Callback
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan-&gt;setAdvertisedDeviceCallbacks(new advertisedDeviceCallbacks());
  // scan 10 seconds
  pBLEScan-&gt;setActiveScan(true);
  pBLEScan-&gt;start(10);
}

void loop() {
  // Connect Server once when receive Advertising
  if (doConnect == true) {
    if (doPrepare()) {
      Serial.println("Connected to the BLE Server.");
    } else {
      Serial.println("Failed to connect to the BLE server.");
    }
    doConnect = false;
  }
  // If Connecting
  if (deviceConnected) {
    if (enableMeasurement &amp;&amp; !bInAlarm) {
      enableMeasurement = false;
    }
    
  } else if (doScan) {
    BLEDevice::getScan()-&gt;start(0);
  }
}

/*  prepare  */
bool doPrepare() {
  /* make cliant object and set Callback */
  BLEClient* pClient = BLEDevice::createClient();
  pClient-&gt;setClientCallbacks(new funcClientCallbacks());
  Serial.println(" - Created client.");

  /* connect remote BLE server */
  pClient-&gt;connect(targetDevice);
  Serial.println(" - Connected to server.");

  /* get reference to server */
  BLERemoteService* pRemoteService = pClient-&gt;getService(serviceUUID);
  if (pRemoteService == nullptr) {
    Serial.print("Failed to find serviceUUID: ");
    Serial.println(serviceUUID.toString().c_str());
    pClient-&gt;disconnect();
    return false;
  }
  Serial.println(" - Found target service.");

  /* get reference to characteristic */
  pRemoteCharacteristicRX = pRemoteService-&gt;getCharacteristic(CHARA_UUID_RX);
  if (pRemoteCharacteristicRX == nullptr) {
    Serial.print("Failed to find characteristicUUID: ");
    Serial.println(CHARA_UUID_RX.toString().c_str());
    pClient-&gt;disconnect();
    return false;
  }
  Serial.println(" - Found characteristic CHARA_UUID_RX.");

  /* assign callback functon for Notify */
  if (pRemoteCharacteristicRX-&gt;canNotify()) {
    pRemoteCharacteristicRX-&gt;registerForNotify(notifyCallback);
    Serial.println(" - Registered notify callback function.");
  }

  deviceConnected = true;
  return true;
}
</code></pre>
]]></description><link>https://community.m5stack.com/topic/3854/i-don-t-know-how-to-send-a-lot-of-data-per-time-by-ble-bluetooth-low-energy</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 12:15:13 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/3854.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 22 Dec 2021 11:58:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to I don&#x27;t know how to send a lot of data per time by BLE(Bluetooth low energy) on Wed, 22 Dec 2021 16:35:59 GMT]]></title><description><![CDATA[<p dir="auto">Hello <a class="plugin-mentions-user plugin-mentions-a" href="/user/stackyarou" aria-label="Profile: stackyarou">@<bdi>stackyarou</bdi></a></p>
<p dir="auto">it looks like the limiting factor is the MTU which by default is set to 23 bytes. I've tried to set a higher MTU on both sides using <code>BLEDevice::setMTU(40);</code>,  but it did not help. I read somewhere that 23 bytes is the maximum for BLE 4.2 so maybe that is the reason?</p>
<p dir="auto">Thanks<br />
Felix</p>
]]></description><link>https://community.m5stack.com/post/15924</link><guid isPermaLink="true">https://community.m5stack.com/post/15924</guid><dc:creator><![CDATA[felmue]]></dc:creator><pubDate>Wed, 22 Dec 2021 16:35:59 GMT</pubDate></item></channel></rss>