Data received by BLE on the Wio Terminal limited to the number of 3?

Hello,

My final goal is to use the Wio Terminal as a BLE receiver to display data measured on an Arduino nano BLE 33 Sense. I have noticed that if I have more than 3 characteristic I get the message Malloc Failed.

Here is my program on the Arduino nano

/*
 * Device: Arduino Nano 33 BLE Sense
 * Peripheral
 * The values of the integrated temperature sensor and 
 * accelerometer are sent using BLE.
 * created from sketch_nanoBLEsense33_BLE_acc_T_peripheral_v9_MAX30102
 */

#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h> //accelerometer sensor
#include <Arduino_HTS221.h> // temperature sensor
//#include <Wire.h>
//#include "MAX30105.h"

//MAX30105 particleSensor;

int const d_t=0; //number of decimal to keep for the temperature
int const d_ir=0;
int const d_a=2;

//float values read by the sensor
float tSensor=25;
//float irSensor=0;
float xSensor=0;
float ySensor=0;
float zSensor=0;

//integer variables to send via BLE
int tBLE=floor(tSensor*pow(10,d_t)+0.5);
//int irBLE=floor(irSensor*pow(10,d_ir)+0.5);
int xBLE=xSensor*pow(10,d_a);
int yBLE=ySensor*pow(10,d_a);
int zBLE=zSensor*pow(10,d_a);

int compteur=0;

BLEService SensorService("1101");

BLEUnsignedIntCharacteristic XChar("2101", BLERead | BLENotify);
BLEUnsignedIntCharacteristic YChar("2102", BLERead | BLENotify);
BLEUnsignedIntCharacteristic ZChar("2103", BLERead | BLENotify);
BLEUnsignedIntCharacteristic TChar("2104", BLERead | BLENotify);
//BLEUnsignedIntCharacteristic IRChar("2107", BLERead | BLENotify);

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

  //initialisation of the accelerometer
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

// initialisation of the temperature sensor
  HTS.begin();

  while (!Serial);
  
  pinMode(LED_BUILTIN, OUTPUT);

  //initialisation of the BLE
  if (!BLE.begin()) {
    Serial.println("BLE failed to Initiate");
    //delay(500);
    while (1);
    }
  
  BLE.setLocalName("Arduino XYZT (peripheral)");
  BLE.setAdvertisedService(SensorService);
  
  SensorService.addCharacteristic(TChar);
  //SensorService.addCharacteristic(IRChar);
  SensorService.addCharacteristic(XChar);
  SensorService.addCharacteristic(YChar);
  SensorService.addCharacteristic(ZChar);
  BLE.addService(SensorService);

  XChar.writeValue(xBLE);
  YChar.writeValue(yBLE);
  ZChar.writeValue(zBLE);
  TChar.writeValue(tBLE);
//  IRChar.writeValue(irBLE);
  
  BLE.advertise();
  
  Serial.println("Arduino XYZT peripheral device is now active, waiting for connections...");

//  //initialisation from Example4_HeartBeatPlotter
//  Serial.println("Initializing...");
//
//  // Initialize sensor
//  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
//  {
//    Serial.println("MAX30105 was not found. Please check wiring/power. ");
//    while (1);
//  }
//
//  //Setup to sense a nice looking saw tooth on the plotter
//  byte ledBrightness = 0x1F; //Options: 0=Off to 255=50mA
//  byte sampleAverage = 8; //Options: 1, 2, 4, 8, 16, 32
//  byte ledMode = 3; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
//  int sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
//  int pulseWidth = 411; //Options: 69, 118, 215, 411
//  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
//
//  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
//
//  //Arduino plotter auto-scales annoyingly. To get around this, pre-populate
//  //the plotter with 500 of an average reading from the sensor
//
//  //Take an average of IR readings at power up
//  const byte avgAmount = 64;
//  long baseValue = 0;
//  for (byte x = 0 ; x < avgAmount ; x++)
//  {
//    baseValue += particleSensor.getIR(); //Read the IR value
//  }
//  baseValue /= avgAmount;
//
//  //Pre-populate the plotter so that the Y scale is close to IR values
//  for (int x = 0 ; x < 500 ; x++)
//    Serial.println(baseValue);
}


void loop() {
 
  Serial.print("inside the void loop \t");
  compteur++;
  Serial.print("compteur void loop \t");
  Serial.println(compteur);

  tSensor=HTS.readTemperature();
  Serial.print(" tSensor \t");
  Serial.println(tSensor);
//
//  irSensor=particleSensor.getIR();
//  Serial.print(" irSensor \t");
//  Serial.println(irSensor); //Send raw data to plotter

  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(xSensor, ySensor, zSensor);
    Serial.print("xSensor ");
    Serial.print(xSensor);
    Serial.print(" - ySensor ");
    Serial.print(ySensor);
    Serial.print(" - zSensor ");
    Serial.print(zSensor);
  }

  BLEDevice central = BLE.central();  
  BLE.advertise();
  
  if (central) {
    Serial.print("Connected to central: ");
    Serial.print("* Device MAC address: ");
    Serial.println(central.address());
    
    digitalWrite(LED_BUILTIN, HIGH);
    
    if (central.connected()) { // doesn't work if it is a while loop

      // send temperature data
      tBLE=floor(tSensor*pow(10,d_t)+0.5);
      Serial.print(" tBLE \t");
      Serial.println(tBLE);

      TChar.writeValue(tBLE);
      Serial.print(" TChar ");
      Serial.println(TChar.value());
//
//      //send IR data
//      irBLE=floor(irSensor*pow(10,d_ir)+0.5);
//      Serial.print(" irBLE \t");
//      Serial.println(irBLE);
//
//      IRChar.writeValue(irBLE);
//      Serial.print(" IRChar ");
//      Serial.println(IRChar.value());

      //send accelerometer datas
      //xBLE=xSensor*pow(10,d_a);
      yBLE=ySensor*pow(10,d_a);
      zBLE=zSensor*pow(10,d_a);
//
//      Serial.print("xBLE ");
//      Serial.print(xBLE);
      Serial.print(" - yBLE ");
      Serial.print(yBLE);
      Serial.print(" - zBLE ");
      Serial.print(zBLE);

      //XChar.writeValue(xBLE);
      YChar.writeValue(yBLE);
      ZChar.writeValue(zBLE);

//      Serial.print("XChar ");
//      Serial.print(XChar.value());
      Serial.print(" - YChar ");
      Serial.print(YChar.value());
      Serial.print(" - ZChar ");
      Serial.print(ZChar);
      
      }
    }
  Serial.println("");
  digitalWrite(LED_BUILTIN, LOW);
  //Serial.print("Disconnected from central: ");
  //Serial.println(central.address());



  delay(1000);
}

and here the program for the Wio

/**
 * A BLE client example that is rich in capabilities.
 * There is a lot new capabilities implemented.
 * author unknown
 * updated by chegewara
 * created from wio_BLEclient_v5_MAX30102

 */
 
#include "rpcBLEDevice.h"
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include"TFT_eSPI.h"
TFT_eSPI tft;
 
// The remote service we wish to connect to.
//static BLEUUID serviceUUID(0xFEE0);
static BLEUUID serviceUUID(0x1101);
// The characteristic of the remote service we are interested in.
//static BLEUUID    charUUID(0x2A2B);
//static BLEUUID    XcharUUID(0x2101);
static BLEUUID    YcharUUID(0x2102);
static BLEUUID    ZcharUUID(0x2103);
static BLEUUID    TcharUUID(0x2104);
//static BLEUUID    IRcharUUID(0x2107);

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;

static BLERemoteCharacteristic* pTChar;
//static BLERemoteCharacteristic* pXChar;
static BLERemoteCharacteristic* pYChar;
static BLERemoteCharacteristic* pZChar;
//static BLERemoteCharacteristic* pIRChar;
static BLEAdvertisedDevice* myDevice;
//uint8_t bd_addr[6] = {0xD9, 0x91, 0xC0, 0x66, 0xAD, 0xF9};
uint8_t bd_addr[6] = {0x43, 0x89, 0x1A, 0x4E, 0xEA, 0xDC};
BLEAddress BattServer(bd_addr);

//float tmp_T(0),deltaTmp_T(0);
int compteur=0;
int compteur2=0;
int compteur3=0;

//int const d_ir=-2;
 
static void temperatureNotifyCallback(
  BLERemoteCharacteristic* pTChar,
  uint8_t* pTData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for temperature characteristic ");
    Serial.print(pTChar->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println(*(uint8_t *)pTData);

    compteur3++;
    Serial.print("compteur temperatureNotifyCallback \t");
    Serial.println(compteur3);
    //Serial.println(*pTData);
    //Serial.println(pTData[0]);

    tft.fillRect(200, 10, 100, 30, TFT_WHITE);
    tft.drawString(String(*pTData), 200, 10);
}

//static void xNotifyCallback(
//  BLERemoteCharacteristic* pXChar,
//  uint8_t* pXData,
//  size_t length,
//  bool isNotify) {
//    Serial.print("Notify callback for X characteristic ");
//    Serial.print(pXChar->getUUID().toString().c_str());
//    Serial.print(" of data length ");
//    Serial.println(length);
//    Serial.print("data: ");
//    Serial.println(*(uint8_t *)pXData);
//
//    tft.fillRect(200, 40, 100, 30, TFT_WHITE);
//    tft.drawString(String(*pXData), 200, 40);
//}

static void yNotifyCallback(
  BLERemoteCharacteristic* pYChar,
  uint8_t* pYData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for Y characteristic ");
    Serial.print(pYChar->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println(*(uint8_t *)pYData);

    tft.fillRect(200, 70, 100, 30, TFT_WHITE);
    tft.drawString(String(*pYData), 200, 70);
}

static void zNotifyCallback(
  BLERemoteCharacteristic* pZChar,
  uint8_t* pZData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for Z characteristic ");
    Serial.print(pZChar->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println(*(uint8_t *)pZData);

    tft.fillRect(200, 100, 100, 30, TFT_WHITE);
    tft.drawString(String(*pZData), 200, 100);
}

//static void irNotifyCallback(
//  BLERemoteCharacteristic* pIRChar,
//  uint8_t* pIRData,
//  size_t length,
//  bool isNotify) {
//    Serial.print("Notify callback for IR characteristic ");
//    Serial.print(pIRChar->getUUID().toString().c_str());
//    Serial.print(" of data length ");
//    Serial.println(length);
//    Serial.print("data: ");
//    Serial.println(*(uint8_t *)pIRData);
//
//    tft.fillRect(200, 40, 100, 30, TFT_WHITE);
//    tft.drawString(String(*pIRData), 200, 130);
//}

class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }
 
  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};
 
bool connectToServer() {
    Serial.println("Inside bool connectToServer ");
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());
 
    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");
 
    pClient->setClientCallbacks(new MyClientCallback());
  
    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");
 
    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    Serial.println(serviceUUID.toString().c_str());
        
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");
  
    // Obtain a reference to the characteristic in the service of the remote BLE server.
    //pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    pTChar = pRemoteService->getCharacteristic(TcharUUID);
    //pXChar = pRemoteService->getCharacteristic(XcharUUID);
    pYChar = pRemoteService->getCharacteristic(YcharUUID);
    pZChar = pRemoteService->getCharacteristic(ZcharUUID);
    //pIRChar = pRemoteService->getCharacteristic(IRcharUUID);
    
    //if (pTChar == nullptr || pIRChar == nullptr || pXChar == nullptr || pYChar == nullptr || pZChar == nullptr) {
    //if (pXChar == nullptr || pYChar == nullptr || pZChar == nullptr) {
    //if (pTChar == nullptr || pXChar == nullptr || pYChar == nullptr || pZChar == nullptr) {
    if (pTChar == nullptr || pYChar == nullptr || pZChar == nullptr) {

    //if (pTChar == nullptr) {
      Serial.print("Failed to find our characteristic UUID ");
//     Serial.println(TcharUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");
  
    // Read the temperature characteristic value 
    if(pTChar->canRead()) {
      Serial.println(" -  can  read  start");
      std::string value = pTChar->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }
    if(pTChar->canNotify())
      pTChar->registerForNotify(temperatureNotifyCallback);


//    if(pXChar->canRead()) {
//      Serial.println(" -  can  read  start");
//      std::string value = pXChar->readValue();
//      Serial.print("The characteristic value was: ");
//      Serial.println(value.c_str());
//    }
//    if(pXChar->canNotify())
//    pXChar->registerForNotify(xNotifyCallback);

    if(pYChar->canRead()) {
      Serial.println(" -  can  read  start");
      std::string value = pYChar->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }
    if(pYChar->canNotify())
    pYChar->registerForNotify(yNotifyCallback);

    if(pZChar->canRead()) {
      Serial.println(" -  can  read  start");
      std::string value = pZChar->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }
    if(pZChar->canNotify())
    pZChar->registerForNotify(zNotifyCallback);

//    // Read the IR characteristic value 
//    if(pIRChar->canRead()) {
//    Serial.println(" -  can  read  start");
//    std::string value = pIRChar->readValue();
//    Serial.print("The characteristic value was: ");
//    //int irValue=value*pow(10,d_ir);
//    Serial.println(value.c_str());
//    }
//    if(pIRChar->canNotify())
//    pIRChar->registerForNotify(irNotifyCallback);

    compteur2 ++;
    Serial.print("compteur connect to server");
    Serial.println(compteur2);
    connected = true;
    return true;
    Serial.println("End of bool connectToServer ");
    
}// bool connectToServer
/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 * Also in BLEscan example but with a shorter onresult
 */
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { // crée une classe MyAdvertisedDeviceCallbacks qui hérite de la classe BLEAdvertisedDeviceCallbacks
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.println("Inside onResult ");
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());
 
    // We have found a device, let us now see if it contains the service we are looking for.
    //int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 
    //: Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2, 
    //returning zero if they all match or a value different from zero representing which is greater if they do not.
    if (memcmp(advertisedDevice.getAddress().getNative(),BattServer.getNative(), 6) == 0) {
      Serial.print("BATT Device found: ");
      Serial.println(advertisedDevice.toString().c_str());
      BLEDevice::getScan()->stop();
      Serial.println("new BLEAdvertisedDevice");
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      Serial.println("new BLEAdvertisedDevice done");
      doConnect = true;
      doScan = true;    
  } 
 Serial.print("doConnect status");
 Serial.println(doConnect);
  }// onResult
}; // MyAdvertisedDeviceCallbacks
 
 
void setup() {
  //initialisation of the screen
  tft.begin();
  tft.setRotation(3);//
  tft.fillScreen(TFT_WHITE);
  tft.setTextSize(2);                   //sets the size of text
  tft.setTextColor(TFT_BLACK);          //sets the text colour to black
  tft.drawString("Temperature", 0, 10);
  tft.drawString("AccX", 0, 40);
  tft.drawString("AccY", 0, 70);
  tft.drawString("AccZ", 0, 100);
  tft.drawString("IR", 0, 130);
  tft.drawString("SpO2", 0, 160);

  //initialisation of the serial connection
  Serial.begin(115200);
  while(!Serial){};
  //delay(2000);
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");
 } // End of setup.
 
 
// This is the Arduino main loop function.
void loop() {
    Serial.print("inside the void loop \t");
     compteur++;
    Serial.print("compteur void loop \t");
    Serial.println(compteur);

    Serial.print("doConnect status ");
    Serial.println(doConnect);
    
if (doConnect != true) {
    // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  Serial.println("scanning");
  BLEScan* pBLEScan = BLEDevice::getScan(); // get scanner from our client device
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); // behaviour of the scanner each time it find another bluetooth device
  //setAdvertisedDeviceCallbacks, setInterval, setWindow, setActiveScan methods from the librairy BLEscan
  pBLEScan->setInterval(1349); // period between 2 active scans
  pBLEScan->setWindow(449); // active scan time range
  pBLEScan->setActiveScan(true);//beginning of the scan
  pBLEScan->start(5, false);
}
  
    // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
  // connected we set the connected flag to be true.

  if (doConnect == true) {//static boolean initialized as false
    Serial.println("inside the if(doConnect==true) loop");

    if (connectToServer()) {
      Serial.println("inside the ConnectToServer loop");
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    Serial.println("end of if connectToServer");
    //doConnect = false;
    //display time information
  }
  
  delay(1000);
  Serial.println("");
} // End of loop

These programs work well if for instance I comment every thing related to xSensor, xChar…

Anyone would know how to deal with this problem?

Best regards,

Alice