I have a problem getting the coding to run to exchange data between sensors and a PC.
I have a Nano 33 BLE Sense Rev2 and use the onboard IMU, thermometer and two external sensors. I need to send these readings to an app on a PC. To test this, I use a Nano 33 BLE on the receiving end. Communication works fine on byte level (using BLEByteCharacteristic), but I can't seem to get it working with longer strings. I started with the samples on https://docs.arduino.cc/tutorials/nano-33-ble-sense/ble-device-to-device and added some of my own stuff. When I try to change the coding to use BLECharacteristic and try to put a string in, I get all sorts of errors coding errors. Even at the first thing I change on line 26 of the code (see second block of code, where it says 'HERE IT GOES WRONG') I get this:
> N:\Dropbox\Arduino\pc side V05\pc side V05.ino: In function 'void loop()':
> N:\Dropbox\Arduino\pc side V05\pc side V05.ino:66:44: error: invalid conversion from 'const uint8_t {aka const unsigned char*}' to 'int' [-fpermissive]*
> sensor = sensorCharacteristic.value();
> ~~~~~~~~~~~~~~~~~~~~~~~~~~^~
Available documentation is incomprehensible (to me! Maybe an expert understands, but I don't.)
This is what I want to achieve: I read the IMU which gives me 3 floats with values from -8192.00 to 8192.00. I also read the device temperature that returns a float (like 20.21 as centigrade) and two analog ports that give me integers (0-1023). I also need to transmit two fixed strings because of functional requirements.
As a bypass to the problem, I put all this data in a string and send that across byte-by-byte. Works fine, but is very slow: it takes 2.7 seconds for 100 bytes.
I'd really appreciate your help!
This is te coding at the sensor side in a Nano 33 BLE Sense Rev2
#include <ArduinoBLE.h>
#include <Arduino_BMI270_BMM150.h>
#include <Arduino_HS300x.h>
#define BLE_BUFFER_SIZES 100
#define UpperSensorPin A1 // analog port 1: upper stretch sensor
#define LowerSensorPin A0 // analog port 0: lower stretch sensor
long uSensorReading = 0; // sensor value; range 0-1023; calibrated when > 100
long lSensorReading = 0; // sensor value; range 0-1023; calibrated when > 100
String bleBuffer; // this is where the assembled string goes
const unsigned char* bleBufferOut;
const char* deviceServiceUuid = "21c10000-e8f2-537e-4f6c-d104768a1214"; // define a custom service
const char* deviceServiceCharacteristicUuid = "21c10000-e8f2-537e-4f6c-d104768a1214";
String sensorBuildDateTime, sensorUniqueId;
char outputChar;
float sensorTemperature, xAxis, yAxis, zAxis;
int errorCode, i, outputByte;
void setup() {
Serial.begin(9600);
//while (!Serial); // don't check! It would stop processing when not connected to an IDE.
pinMode(LED_BUILTIN, OUTPUT);
// this is for functional reasons
sensorBuildDateTime = "20230101123456";
errorCode = 0;
sensorUniqueId = "12345678";
sensorTemperature = 37.25;
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU! Halted.");
while (1)
;
}
if (!BLE.begin()) {
Serial.println("Failed to start BLE! Halted");
while (1)
;
}
if (!HS300x.begin()) {
Serial.println("Failed to start temperature sensor! Halted");
while (1);
}
BLE.setLocalName("test with sensor v05");
BLE.advertise();
Serial.println("test with sensor v05 (sensor side)");
}
void loop() {
connectToPeripheral();
}
void connectToPeripheral() {
BLEDevice peripheral;
Serial.println("- Discovering peripheral device...");
do {
BLE.scanForUuid(deviceServiceUuid);
peripheral = BLE.available();
} while (!peripheral);
if (peripheral) {
Serial.println("Peripheral device found!");
Serial.print("Device MAC address: ");
Serial.println(peripheral.address());
Serial.print("Device name: ");
Serial.println(peripheral.localName());
Serial.print("Advertised service UUID: ");
Serial.println(peripheral.advertisedServiceUuid());
BLE.stopScan();
controlPeripheral(peripheral);
}
}
void controlPeripheral(BLEDevice peripheral) {
Serial.println("- Connecting to peripheral device...");
if (peripheral.connect()) {
Serial.println("Connected to peripheral device!");
} else {
Serial.println("Connection to peripheral device failed!");
return;
}
Serial.println("- Discovering peripheral device attributes...");
if (peripheral.discoverAttributes()) {
Serial.println("Peripheral device attributes discovered!");
} else {
Serial.println("Peripheral device attributes discovery failed!");
peripheral.disconnect();
return;
}
BLECharacteristic sensorCharacteristic = peripheral.characteristic(deviceServiceCharacteristicUuid);
if (!sensorCharacteristic) {
Serial.println("Peripheral device does not have sensor_type characteristic!");
peripheral.disconnect();
return;
} else if (!sensorCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable sensor_type characteristic!");
peripheral.disconnect();
return;
}
sensorCharacteristic.writeValue((byte)0); // send a 0 to have app reset the buffer
while (peripheral.connected()) {
Serial.println("Get sensors");
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(xAxis, yAxis, zAxis);
}
uSensorReading = analogRead(UpperSensorPin);
lSensorReading = analogRead(LowerSensorPin);
sensorTemperature = HS300x.readTemperature();
Serial.println("Have all");
bleBuffer = String(lSensorReading) + char(9);
bleBuffer = bleBuffer + sensorBuildDateTime + char(9);
bleBuffer = bleBuffer + String(uSensorReading) + char(9);
bleBuffer = bleBuffer + String(errorCode) + char(9);
bleBuffer = bleBuffer + sensorUniqueId + char(9);
bleBuffer = bleBuffer + String(sensorTemperature) + char(9);
bleBuffer = bleBuffer + "v05" + char(9);
bleBuffer = bleBuffer + String(xAxis) + char(9);
bleBuffer = bleBuffer + String(yAxis) + char(9);
bleBuffer = bleBuffer + String(zAxis) + char(0);
// BYPASS: send the buffer character-by-character
for (i = 0; i < BLE_BUFFER_SIZES; i++) {
outputChar = bleBuffer[i];
outputByte = int(outputChar);
if (outputByte != 0) {
sensorCharacteristic.writeValue((byte)outputByte);
Serial.print(outputChar);
}
}
// and terminate with a 0x00
outputByte = 0;
sensorCharacteristic.writeValue((byte)outputByte);
Serial.println("");
Serial.println("Sent");
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
Serial.println("- Peripheral device disconnected!");
}
This is the coding in the Nano 33 BLE that is the interface to the app running on a Windows PC:
#include <ArduinoBLE.h>
#define BLE_BUFFER_SIZES 100
const char* deviceServiceUuid = "21c10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "21c10000-e8f2-537e-4f6c-d104768a1214";
String bleBuffer = "";
int sensor;
const unsigned char* sensorString;
BLEService sensorService(deviceServiceUuid);
// HERE IT GOES WRONG BLECharacteristic sensorCharacteristic(deviceServiceCharacteristicUuid, BLERead | BLEWrite | BLEWriteWithoutResponse, 100);
BLEByteCharacteristic sensorCharacteristic(deviceServiceCharacteristicUuid, BLERead | BLEWrite | BLEWriteWithoutResponse); // this one works !!!!!!
void setup() {
Serial.begin(9600);
while (!Serial)
;
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
Serial.println("Starting Bluetooth® Low Energy module failed!");
while (1)
;
}
BLE.setLocalName("test app PC side v05");
BLE.setAdvertisedService(sensorService);
sensorService.addCharacteristic(sensorCharacteristic);
BLE.addService(sensorService);
BLE.advertise();
Serial.println("test app PC side v05");
Serial.println(" ");
}
void loop() {
BLEDevice central = BLE.central();
Serial.println("- Discovering central device...");
if (central) {
Serial.println("* Connected to central device!");
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("* Device MAC address: ");
Serial.println(central.address());
Serial.println(" ");
while (central.connected()) {
if (sensorCharacteristic.written()) {
sensor = sensorCharacteristic.value();
if (sensor != 0) {
bleBuffer = bleBuffer + char(sensor);
} else {
Serial.println(bleBuffer);
bleBuffer = "";
}
}
}
Serial.println("* Disconnected from central device!");
digitalWrite(LEDB, LOW);
}
}