Seeed xiao bluetooth comunication increasing sampling rate

you are right.

This is the code without the sensors collecting data, I just send a constant string of values:

so this is the peripheral code

#include <Wire.h>
#include "SPI.h"
#include <SparkFun_MS5803_I2C.h>
#include <SparkFun_Bio_Sensor_Hub_Library.h>
#include <bluefruit.h>
#include <Adafruit_LittleFS.h>
#include <InternalFileSystem.h>
#include "LSM6DS3.h"

//#####################################################################################################################
//BLE and data transmission Settings 
#define FAST  
#ifdef FAST
  #define CONN_PARAM  6         // connection interval *1.25mS, min 6
  #define DATA_NUM    244       // max 244
#else
  #define CONN_PARAM  16        // connection interval *1.25mS, default 16
  #define DATA_NUM    20        // default 20
#endif 
union unionData {               // Union for data type conversion
  uint32_t  dataBuff32[DATA_NUM/4];
  uint8_t   dataBuff8[DATA_NUM];
};
union unionData ud;
uint16_t conn;					        // connect handle
bool connectedFlag = false;     // set by connect callback
// Custum Service and Characteristic
// 55c40000-8682-4dd1-be0c-40588193b485 for example
#define customService_UUID(val) (const uint8_t[]) { \
    0x85, 0xB4, 0x93, 0x81, 0x58, 0x40, 0x0C, 0xBE, \
    0xD1, 0x4D, (uint8_t)(val & 0xff), (uint8_t)(val >> 8), 0x00, 0x00, 0xC4, 0x55 }

BLEService        customService        (customService_UUID(0x0000));
BLECharacteristic customCharacteristic   (customService_UUID(0x0030));

BLEDfu  bledfu;
BLEDis  bledis;
BLEUart bleuart;
BLEBas  blebas;
//#####################################################################################################################
float GyroX = 3330.0;
float GyroY = 3330.0;
float GyroZ = 3330.0;
float AccX  = 3330.0;
float AccY  = 3330.0;
float AccZ  = 3330.0;

bool isCollectingData = false; // for keeping track of state (collecting | not collecting);

void setup() {
  delay(2000);
  Serial.begin(115200);
  delay(2000);

  // Pin initialization
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_BLUE, OUTPUT); 

  digitalWrite(LED_RED, HIGH);
  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_BLUE, HIGH);
  
  // BLE 
  setupBLE();

}

void loop(){
  if (connectedFlag) {  // If connected to the central
    sendValues();  
  } else {
    Serial.println("Not connected, waiting for connection.");
  }
}
//#############################################################################################################
// SENSOR FUNCTIONS
void sendValues() {
  float pressure_abs = 400.00;
  int heartRate = 1000;
  int oxygen = 1000;
  int status = 1;

  char dataPacket[80];
  memset(dataPacket, 0, sizeof(dataPacket));
  snprintf(dataPacket, sizeof(dataPacket), "V%.2f,%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f", pressure_abs, heartRate, oxygen, status, GyroX, GyroY, GyroZ, AccX, AccY, AccZ);

  // Write the data to the BLE characteristic
  if (!customCharacteristic.notify((uint8_t*)dataPacket, sizeof(dataPacket) - 1)) {
      Serial.println("Failed to send notification");
  } else {
      Serial.println("Sensors Values Sent");
  }
  bleuart.print("Data Packet: "); // sends data packet to BlueFruit LE app
  bleuart.println(dataPacket);
}

//#############################################################################################################
// BLE FUNCTIONS
void connect_callback(uint16_t conn_handle)
{
  connectedFlag = false;
  
  Serial.print("【connect_callback】 conn_Handle : ");
  Serial.println(conn_handle, HEX);
  conn = conn_handle;

  // Get the reference to current connection
  BLEConnection* connection = Bluefruit.Connection(conn_handle);

  // request to chamge parameters
#ifdef FAST
  connection->requestPHY();                              // PHY 2MHz (2Mbit/sec moduration) 1 --> 2
  delay(1000);                                           // delay a bit for request to complete
  //Serial.println(connection->getPHY());
  connection->requestDataLengthUpdate();                 // data length  27 --> 251
#endif  
  connection->requestMtuExchange(DATA_NUM + 3);          // MTU 23 --> 247
  connection->requestConnectionParameter(CONN_PARAM);    // connection interval (*1.25mS)   
  delay(1000);                                           // delay a bit for request to complete  
  Serial.println();
  Serial.print("PHY ----------> "); Serial.println(connection->getPHY());
  Serial.print("Data length --> "); Serial.println(connection->getDataLength());
  Serial.print("MTU ----------> "); Serial.println(connection->getMtu());
  Serial.print("Interval -----> "); Serial.println(connection->getConnectionInterval());      

  char central_name[32] = { 0 };
  connection->getPeerName(central_name, sizeof(central_name));
  Serial.print("【connect_callback】 Connected to ");
  Serial.println(central_name);

  connectedFlag = true;
}

void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
  (void) conn_handle;
  (void) reason;

  Serial.print("【disconnect_callback】 reason = 0x");
  Serial.println(reason, HEX);
  connectedFlag = false;
  
}

void setupBLE()
{

  Serial.print("Start BLUETOOTH Initialization");
  // Initialization of Bruefruit class
  Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
  Bluefruit.configUuid128Count(15);

  Bluefruit.begin();
  #ifdef FAST  
    Bluefruit.setTxPower(0);    // Central is close, 0dBm
  #else
    Bluefruit.setTxPower(4);    // default +4dBm
  #endif  
  Bluefruit.setConnLedInterval(50);
  Bluefruit.Periph.setConnectCallback(connect_callback);
  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);

  // Custom Service Settings
  customService.begin();
  customCharacteristic.setProperties(CHR_PROPS_NOTIFY);
  customCharacteristic.setFixedLen(DATA_NUM);
  customCharacteristic.begin();

  // Advertisement Settings
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addService(customService);
  Bluefruit.ScanResponse.addName();
  
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setIntervalMS(20, 153);     // fast mode 20mS, slow mode 153mS
  Bluefruit.Advertising.setFastTimeout(30);         // fast mode 30 sec
  Bluefruit.Advertising.start(0);                   // 0 = Don't stop advertising after n seconds

  Serial.println("End of BLUETOOTH initialization");

  // Connecting to Central
  Serial.println("Connecting to Central ................");
  while(!Bluefruit.connected()) {
    Serial.print("."); delay(100);
  }
  Serial.println();
  Serial.println("Connected to Central");
  delay(5000);
}
//#############################################################################################################



while here is the CENTRAL code:

#include <Wire.h>
#include <SPI.h>
#include <bluefruit.h>

//***********************************************************************************************************
#define FAST                    // compiler option : parameters setting for fast transmission
                                // if default setting, comment out
#define MAX_PACKET  200         // maximum number of data packets allowed by FIFO
#define FIFO_SIZE DATA_NUM * MAX_PACKET  // FIFO size, push and pop on a packet-by-packet basis
#ifdef FAST
  #define DATA_NUM  244         // number of bytes in data packet
#else
  #define DATA_NUM  20          // number of bytes in data packet
#endif
//***********************************************************************************************************

union unionData {               // Union for data type conversion
  uint32_t  dataBuff32[DATA_NUM/4];
  uint8_t   dataBuff8[DATA_NUM];
};
union unionData ud; 

uint16_t conn;                  // connect handle
bool notifyFlag = false;        // set by notify callback
bool connectedFlag = false;     // set by connect callback

// Custom Service and Characteristic
// 55c40000-8682-4dd1-be0c-40588193b485 for example
#define customService_UUID(val) (const uint8_t[]) { \
    0x85, 0xB4, 0x93, 0x81, 0x58, 0x40, 0x0C, 0xBE, \
    0xD1, 0x4D, (uint8_t)(val & 0xff), (uint8_t)(val >> 8), 0x00, 0x00, 0xC4, 0x55 }

BLEClientService        customService       (customService_UUID(0x0000));
BLEClientCharacteristic customCharacteristic  (customService_UUID(0x0030));

unsigned long startTime = 0;
unsigned long packetCount = 0;
unsigned long totalDataReceived = 0; // in bytes
const unsigned long interval = 2000; // 10 seconds

void setup() {
    delay(2000);
    Serial.begin(115200);
    delay(2000);

    // LED initialization
    pinMode(LED_RED, OUTPUT);
    pinMode(LED_GREEN, OUTPUT);
    pinMode(LED_BLUE, OUTPUT);

    Serial.println("------ Central Board ------");
    Serial.println("Start Initialization");
    
    // Initialization of Bluefruit
    Bluefruit.configCentralBandwidth(BANDWIDTH_MAX);  
    Bluefruit.begin(0, 1);
    Bluefruit.setName("XIAO BLE Central");

    // Custom Service Settings
    customService.begin();
    customCharacteristic.setNotifyCallback(data_notify_callback);
    customCharacteristic.begin();
    

    // Blue LED blinking interval setting
    Bluefruit.setConnLedInterval(100);

    // Callbacks
    Bluefruit.Central.setDisconnectCallback(disconnect_callback);
    Bluefruit.Central.setConnectCallback(connect_callback);
    
    // Scanner settings
    Bluefruit.Scanner.setRxCallback(scan_callback);
    Bluefruit.Scanner.restartOnDisconnect(true);
    Bluefruit.Scanner.setIntervalMS(100, 50);    
    Bluefruit.Scanner.filterUuid(customService.uuid);
    Bluefruit.Scanner.useActiveScan(false);
    Bluefruit.Scanner.start(0);                  

    Serial.println("End of initialization");
    startTime = millis();
}

void loop() {
    unsigned long currentTime = millis();

    if (currentTime - startTime >= interval) {
        // Calculate the sampling rate (packets per second)
        float samplingRate = (float)packetCount / (interval / 1000.0);

        // Calculate the bit rate (bits per second)
        float bitRate = (totalDataReceived * 8) / (interval / 1000.0);

        Serial.print("Sampling Rate: ");
        Serial.print(samplingRate);
        Serial.println(" packets/second");

        Serial.print("Bit Rate: ");
        Serial.print(bitRate);
        Serial.println(" bits/second");

        // Reset counters and timer
        packetCount = 0;
        totalDataReceived = 0;
        startTime = millis();
    }
}

//*************************************************************************************************************************************************************************************
// THE CONNECTION IS ESTABLISHED 
//*************************************************************************************************************************************************************************************
// FUNCTIONS FOR CONNECTION with the peripheral 
void scan_callback(ble_gap_evt_adv_report_t* report)
{
  Bluefruit.Central.connect(report);
}

void connect_callback(uint16_t conn_handle){
    conn = conn_handle;
    connectedFlag = false;
    if (!customService.discover(conn_handle))
    {
        Serial.println("【connect_callback】 Service not found, disconnecting!");
        Bluefruit.disconnect(conn_handle);
        return;
    }
    if (!customCharacteristic.discover())
    {
        Serial.println("【connect_callback】 Characteristic not found, disconnecting!");
        Bluefruit.disconnect(conn_handle);
        return;
    }

    // After discovering the characteristic, enable notifications
    if (!customCharacteristic.enableNotify()) {
        Serial.println("Failed to enable notifications");
    } else {
        Serial.println("Notifications enabled");
    }

    connectedFlag = true;
    Serial.println("【connect_callback】connected");
}

void disconnect_callback(uint16_t conn_handle, uint8_t reason){
  (void) conn_handle;
  (void) reason;

  Serial.print("【disconnect_callback】 Disconnected, reason = 0x");
  Serial.println(reason, HEX);
  connectedFlag = false;
}
//*************************************************************************************************************************************************************************************
//*************************************************************************************************************************************************************************************

// Callback when new data is available on the characteristic
void data_notify_callback(BLEClientCharacteristic* chr, uint8_t* data, uint16_t len) {
    // Count the packets and accumulate the total data received
    packetCount++;
    totalDataReceived += len;
    
    // Process the received data
    sendDataThroughSerial((char*)data, len);
}

// Function to send data through the serial port
void sendDataThroughSerial(char* data, uint16_t len) {
    Serial.print(data);  // This sends the string up to the null terminator
    Serial.println();
}

the sampling rate is:

00:24:18.378 → Sampling Rate: 533.00 packets/second

00:24:18.378 → Bit Rate: 1040416.00 bits/second

so it is a problem related to data collection not related to ble comunications

1 Like