Using "setValue()" to send a string and a float in one packet

I would love to send both string data and a float over BLE using something similar to the “BLE_notify” example provided in Arduino IDE for the XIAO ESP32S3.

I’m able to send float numbers using the nRF data. For example (below) “dist_inch” is a value read from a sonar sensor that the ESP32S3 is connected to:

    if (deviceConnected) {
        pCharacteristic->setValue(dist_inch);
        pCharacteristic->notify();
        value++;
        delay(3);

However, I can’t figure out the right syntax to send both a string and a float at the same time. I tried this (below), but it’s giving me compilation errors. Does anyone have any advice?

if (deviceConnected) {
        pCharacteristic->setValue(std::string "Value is: ",float& dist_inch);
        pCharacteristic->notify();
        value++;
        delay(3); 

Hi there,
I found it easier to just build a string and ADD those floats as such to it.
on the other end I parse for the fields in status. Albeit I’m using ArduinoBLE.

BLE Setup

String statusString;

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

update whenever a write to a characteristic would occur

 }  // if switch write
      if (central) {
      // Send the system status string to the central when the characteristic is read
       if (systemStatusCharacteristic.written()) {
      systemStatusCharacteristic.writeValue(statusString);
    }
    }  //while connected

string builder…

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;
}

imu tempreture, and the Battery level for example.

It’s just mi POV of it and strings for notify are easy. :grin:
HTH
GL :slight_smile: PJ

Hey PJ, thanks for sending over that suggestion! I couldn’t get it to work by making a function as you did. If i recall correctly, I was getting a compilation error. I think this basically came down to formatting. The way I remedied that error is by doing some very specific formatting (see below):

    if (deviceConnected) {
        sensorValue = analogRead(SonarPin);
        delay(50); // give it a sec to read 
        dist_inch = (sensorValue*0.497); // this is a float 
        dtostrf(dist_inch,-5,2,distanceString); // convert the float to a char for readability

        std::string data_send = "Distance is ";
        data_send += distanceString;

        pCharacteristic->setValue(data_send);
        pCharacteristic->notify(); // this initiates the actual sending of data
        delay(3); // prevent Bluetooth congestion with minor delay
    }

For anyone who faces similar issues in the future, here is my full code:


// Bluetooth Stuff:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint32_t value = 0;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};


// Sonar Reading Stuff: 
float dist_inch=0.00;
int SonarPin = D0;
int sensorValue;

// Float to string stuff we use later for sending data
char distanceString[7]; // size of character array I expect from distance reading XXX.XX+1


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

  // Sonar Stuff: 
  pinMode(SonarPin,INPUT);

  // Create the BLE Device, Server, Service, Characteristic, and Descriptor
  BLEDevice::init("ESP32");
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  pCharacteristic->addDescriptor(new BLE2902());

  // Start the service
  pService->start();

  // Start advertising presence of device
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(false);
  pAdvertising->setMinPreferred(0x0);  // set value to 0x00 to not advertise this parameter
  BLEDevice::startAdvertising();
  Serial.println("Waiting a client connection to notify...");
}

void loop() { 
    // notify of changed value
    if (deviceConnected) {
        sensorValue = analogRead(SonarPin);
        delay(50); // give it a sec to read 
        dist_inch = (sensorValue*0.497); // this is a float 
        dtostrf(dist_inch,-5,2,distanceString); // convert the float to a char for readability

        std::string data_send = "Distance is ";
        data_send += distanceString;

        pCharacteristic->setValue(data_send);
        pCharacteristic->notify(); // this initiates the actual sending of data
        delay(3); // prevent Bluetooth congestion with minor delay
    }
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}