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.
HTH
GL 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;
}
}