I am working on a project to develop a room monitoring system with Arduino Nano 33 BLE Sense. My goal is to send temperature from the multiple arduino board acting as the peripheral devices to another board acting as central device.
So far i have been able to connect the peripherals to scan for the local name of the central. Unfortunately, I haven't been able to read the temperature data sent from the peripheral devices to the central device. I'm just getting 0.0;
What I have tried so far:
I have incoropated several solution i found on the Arduino dicussion forum board into my code.
I have incoropated the BateryMonitor example.
My theory
My theory is that I have to convert the temperature data into analog data before sending it but I'm not sure if that possible.
I would seriously appreciate it if anyone could provide any advice or explanation on how to solve this problem I'm having. Thank you.
It is certainly possible to write and read a float characteristic if that's what the sensor on ble sense returns. You can also multiply the value by 100 and use an integer characteristic.
I would suggest that you verify and debug the peripheral sketch using a standard central app like LightBlue or nrf Connect.
Thank you for your suggestion. I have actually tried these solutions before, including verifying and debugging the peripheral sketch using nRf connect. I still couldn't get it working as expected.
If you could give a look at my code, and suggest what I am doing wrong. Thank you!
This is the most successful peripheral sketch I have:
/*
* Device: Arduino Nano 33 BLE Sense
* Peripheral
* The values of the integrated temperature sensor and
* accelerometer are sent using BLE.
*/
#include <ArduinoBLE.h>
#include <Arduino_HS300x.h>
// Service and characteristics 2
const char* peripheralServiceUuid1 = "19b10000-e8f2-537e-4f6c-d104768a1215"; // Service UUID for Peripheral 2
const char* temperatureCharacteristicUuid1 = "19b10001-e8f2-537e-4f6c-d104768a1215"; // Characteristic UUID for Peripheral
const char* humidityCharacteristicUuid1 = "19b10002-e8f2-537e-4f6c-d104768a1215";
BLEService peripheralService1 (peripheralServiceUuid1);
BLEFloatCharacteristic temperatureCharacteristic1(temperatureCharacteristicUuid1, BLERead | BLENotify);
BLEFloatCharacteristic humidityCharacteristic1(humidityCharacteristicUuid1, BLERead | BLENotify);
float temperatureValue1 = 0.0;
float humidityValue1 = 0.0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial);
if (!BLE.begin()) {
Serial.println("* Starting Bluetooth® Low Energy module failed!");
while (1);
}
if (!HS300x.begin()) {
Serial.println("Failed to initialize humidity temperature sensor!");
while (1);
}
BLE.setLocalName("Peripheral Device 1");
BLE.setAdvertisedService(peripheralService1);
peripheralService1.addCharacteristic(temperatureCharacteristic1);
peripheralService1.addCharacteristic(humidityCharacteristic1);
BLE.addService(peripheralService1);
temperatureCharacteristic1.writeValue(temperatureValue1);
humidityCharacteristic1.writeValue(humidityValue1);
BLE.advertise();
Serial.println("Arduino Nano 33 BLE Sense (Peripheral Device)");
Serial.println(" ");
}
void loop() {
// put your main code here, to run repeatedly:
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
Serial.print("* Device name: ");
Serial.println(central.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(central.advertisedServiceUuid());
Serial.print("RSSI: ");
Serial.println(central.rssi());
Serial.println(" ");
BLE.stopScan();
while (central.connected()) {
updateTemperatureValue();
delay(500);
}
Serial.print("Disconnected from central: ");
}
}
void updateTemperatureValue() {
float temp1, humi1;
temp1 = HS300x.readTemperature();
humi1 = HS300x.readHumidity();
Serial.print("---------------------------------");
Serial.print(temp1);
if (temp1 != temperatureValue1 && humi1 != humidityValue1) {
temperatureCharacteristic1.writeValue(temp1 * 100);
humidityCharacteristic1.writeValue(humi1 * 100);
temperatureValue1 = temp1;
humidityValue1 = humi1;
}
Serial.print("Temp = ");
Serial.print(temp1);
Serial.println("°C");
Serial.print("Humidity = ");
Serial.print(humi1);
Serial.println("%");
delay(1000);
}
This is central device sketch:
/*
* Device: Arduino Nano 33 BLE Sense
* Central
* The values of the integrated temperature sensor and
* accelerometer are recieved using BLE.
*/
#include <ArduinoBLE.h>
// Define service and characteristic UUIDs for each peripheral device
const char* peripheralServiceUuid1 = "19b10000-e8f2-537e-4f6c-d104768a1215";
const char* temperatureCharacteristicUuid1 = "19b10001-e8f2-537e-4f6c-d104768a1215";
const char* humidityCharacteristicUuid1 = "19b10002-e8f2-537e-4f6c-d104768a1215";
BLEService peripheralService1(peripheralServiceUuid1);
BLEFloatCharacteristic temperatureCharacteristic1(temperatureCharacteristicUuid1, BLERead | BLENotify);
BLEFloatCharacteristic humidityCharacteristic1(humidityCharacteristicUuid1, BLERead | BLENotify);
float temperature1 = 0.0;
float humidity1= 0.0;
void setup() {
Serial.begin(9600);
while (!Serial);
if (!BLE.begin()) {
Serial.println("Starting BLE failed!");
while (1);
}
BLE.setLocalName("Central Device");
BLE.advertise();
Serial.println(" ");
}
void loop() {
connectToPeripheral1();
}
void connectToPeripheral1() {
BLEDevice peripheral1;
Serial.println("- Discovering BLE Device....");
delay(500);
do {
BLE.scanForUuid(peripheralServiceUuid1);
peripheral1 = BLE.available();
} while (!peripheral1);
if (peripheral1) {
Serial.print("Connected to central device with MAC address: ");
Serial.println(peripheral1.address());
Serial.print(" Device Name: ");
Serial.println(peripheral1.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(peripheral1.advertisedServiceUuid());
Serial.println(" ");
BLE.stopScan();
controlPeripheral(peripheral1);
}
}
void controlPeripheral(BLEDevice peripheral1) {
Serial.println(" Connecting to peripheral 1 device...");
if (peripheral1.connect()) {
Serial.println("Connected peripheral 1 device!");
Serial.println(" ");
} else {
Serial.println("Connection to peripheral 1 device failed!");
Serial.println(" ");
return;
}
Serial.println(" Discovering peripheral 1 device attribute...");
if (peripheral1.connect()) {
Serial.println(" peripheral 1 device! attribute discovered");
Serial.println(" ");
} else {
Serial.println("peripheral 1 device attribute discovery failed!");
Serial.println(" ");
return;
}
while (peripheral1.connected()) {
temperatureCharacteristic1.readValue(&temperature1, 2);
Serial.println(temperature1 );
humidityCharacteristic1.readValue(&humidity1, 2);
Serial.println(humidity1 / 100.0);
}
}
Apologies for the late response, the peripheral sketch work on my phone. I can read the Temperature and Humidity on my phone. which mean the code in the peripheral sketch works fine so the problem is definitely in the central sketch.
I am now set up to test, and have a central reading a version of your peripheral which I modified for values not sent by the sensors. I only have a Nano33 BLE and not the sense version.
This central should read your peripheral. It does not subscribe to the notifications, but for simplicity just reads periodically with a delay. It demonstrates how to read the value of a characteristic into a variable.
#include <ArduinoBLE.h>
const char* peripheralServiceUuid1 = "19b10000-e8f2-537e-4f6c-d104768a1215"; // Service UUID
const char* temperatureCharacteristicUuid1 = "19b10001-e8f2-537e-4f6c-d104768a1215"; // Characteristic UUID for Peripheral
const char* humidityCharacteristicUuid1 = "19b10002-e8f2-537e-4f6c-d104768a1215";
BLEDevice peripheral; //make this global
void setup() {
Serial.begin(9600);
while (!Serial);
if (!BLE.begin()) {
Serial.println("* Starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("Nano 33 BLE (Central)");
Serial.println("- Discovering peripheral device...");
do
{
BLE.scanForUuid(peripheralServiceUuid1);
peripheral = BLE.available(); // Name gefundenes BLE ist hier "peripheral" ?
} 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()); Serial.println(" ");
BLE.stopScan();
}
Serial.println("- Connecting to peripheral device...");
if (peripheral.connect()) {
Serial.println("* Connected to peripheral device!"); Serial.println(" ");
} else {
Serial.println("* Connection to peripheral device failed!"); Serial.println(" ");
return;
}
Serial.println("- Discovering peripheral device attributes..."); // "BLE.discoverAttributes" ist in der Referenz nicht zu finden, was macht das wirklich, welchen Zweck haben die Attribute und wie passen sie in die Struktur? Brauche ich den Befehl überhaupt?
if (peripheral.discoverAttributes()) {
Serial.println("* Peripheral device attributes discovered!"); Serial.println(" ");
} else {
Serial.println("* Peripheral device attributes discovery failed!"); Serial.println(" ");
peripheral.disconnect();
return;
}
}
void loop() {
BLECharacteristic temperatureCharacteristic = peripheral.characteristic(temperatureCharacteristicUuid1);
BLECharacteristic humidityCharacteristic = peripheral.characteristic(humidityCharacteristicUuid1);
uint16_t statusTemperature = 0;
uint16_t statusHumidity = 0;
temperatureCharacteristic.readValue(&statusTemperature, 2); //reads 2 bytes into variable
humidityCharacteristic.readValue(&statusHumidity, 2);
Serial.println("Temperature: "); Serial.println((float) statusTemperature / 100.0);
Serial.println("Humidity: "); Serial.println((float) statusHumidity / 100.0);
Serial.println();
delay(1000);
}
You can certainly go back to using FloatCharacteristic which will send 4 bytes. You would then read 4 bytes into the receiving variables.
The problem is that floating point characteristics are not very well handled by LightBlue or nrfConnect and the peripheral code is harder to debug by phone.
Now that you have a working model for the central, going back to floats should be simple.