Hi
I am using this code on a BLE Sense.
#include <ArduinoBLE.h> // Bluetooth Library
#include <Arduino_HTS221.h> // Pressure Sensor Library
#include <Arduino_LPS22HB.h> // Temperature Sensor Library
#include <Arduino_LSM9DS1.h> // Magnetometer Sensor Library
// Initalizing global variables for sensor data to pass onto BLE
String p, t, m;
// BLE Service Name
BLEService customService("180C");
// BLE Characteristics
// Syntax: BLE<DATATYPE>Characteristic <NAME>(<UUID>, <PROPERTIES>, <DATA LENGTH>)
BLEStringCharacteristic ble_pressure("2A56", BLERead | BLENotify, 13);
BLEStringCharacteristic ble_temperature("2A57", BLERead | BLENotify, 13);
BLEStringCharacteristic ble_magnetic("2A58", BLERead | BLENotify, 20);
// Function prototype
void readValues();
void setup()
{
// Initalizing all the sensors
HTS.begin();
BARO.begin();
IMU.begin();
Serial.begin(9600);
while (!Serial);
if (!BLE.begin())
{
Serial.println("BLE failed to Initiate");
delay(500);
while (1);
}
// Setting BLE Name
BLE.setLocalName("Arduino Environment Sensor");
// Setting BLE Service Advertisment
BLE.setAdvertisedService(customService);
// Adding characteristics to BLE Service Advertisment
customService.addCharacteristic(ble_pressure);
customService.addCharacteristic(ble_temperature);
customService.addCharacteristic(ble_magnetic);
// Adding the service to the BLE stack
BLE.addService(customService);
// Start advertising
BLE.advertise();
Serial.println("Bluetooth device is now active, waiting for connections...");
}
void loop()
{
// Variable to check if cetral device is connected
BLEDevice central = BLE.central();
if (central)
{
Serial.print("Connected to central: ");
Serial.println(central.address());
while (central.connected())
{
delay(200);
// Read values from sensors
readValues();
// Writing sensor values to the characteristic
ble_pressure.writeValue(p);
ble_temperature.writeValue(t);
ble_magnetic.writeValue(m);
// Displaying the sensor values on the Serial Monitor
Serial.println("Reading Sensors");
Serial.println(p);
Serial.println(t);
Serial.println(m);
Serial.println("\n");
delay(1000);
}
}
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
void readValues()
{
// Reading raw sensor values from three sensors
float x, y, z;
float pressure = BARO.readPressure();
float temperature = HTS.readTemperature();
if (IMU.magneticFieldAvailable()) {
IMU.readMagneticField(x, y, z);
// Saving sensor values into a user presentable way with units
p = String(pressure) + " kPa";
t = String(temperature) + " C";
m = "X:" + String(x) + ", Y:" + String(y);
}
}
It works well on the mobile phone app LightBlue I can connect to the peripheral, open the characteristic, switch the data to be shown in UTF-8. Making the switch leads to it being readable exactly as on the serial output.
To take this to the next level I want to move from phone to a second BLE board. In the forum I found a topic by @Klaus_K where he wrote the following code
/*
This example creates a BLE central that scans for a peripheral with a Environmental Sensing Service (ESS).
If that contains temperature and humidity characteristics the values are displayed.
The circuit:
- Arduino Nano 33 BLE or Arduino Nano 33 IoT board.
This example code is in the public domain.
*/
#include <ArduinoBLE.h>
//----------------------------------------------------------------------------------------------------------------------
// BLE UUIDs
//----------------------------------------------------------------------------------------------------------------------
// https://www.bluetooth.com/specifications/assigned-numbers/environmental-sensing-service-characteristics/
#define BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE "181A"
#define BLE_UUID_TEMPERATURE "2A6E"
#define BLE_UUID_HUMIDITY "2A6F"
void setup()
{
Serial.begin( 9600 );
while ( !Serial );
BLE.begin();
BLE.scanForUuid( BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE );
} // setup
void loop()
{
static long previousMillis = 0;
long interval = 5000;
unsigned long currentMillis = millis();
if ( currentMillis - previousMillis > interval )
{
previousMillis = currentMillis;
BLEDevice peripheral = BLE.available();
if ( peripheral )
{
if ( peripheral.localName() != "Arduino Nano 33 BLE" )
{
return;
}
BLE.stopScan();
explorePeripheral( peripheral );
BLE.scanForUuid( BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE );
}
}
} // loop
bool explorePeripheral( BLEDevice peripheral )
{
if ( !peripheral.connect() )
{
return false;
}
if ( !peripheral.discoverAttributes() )
{
peripheral.disconnect();
return false;
}
BLECharacteristic temperatureCharacterisic = peripheral.characteristic( BLE_UUID_TEMPERATURE );
if ( temperatureCharacterisic )
{
int16_t temperature;
temperatureCharacterisic.readValue( temperature );
Serial.print( "Temperature: " );
Serial.print( temperature / 100.0 );
Serial.println( "°C" );
}
BLECharacteristic humidityCharacterisic = peripheral.characteristic( BLE_UUID_HUMIDITY );
if ( humidityCharacterisic )
{
uint16_t humidity;
humidityCharacterisic.readValue( humidity );
Serial.print( "Humidity: " );
Serial.print( humidity / 100.0 );
Serial.println( "%" );
}
peripheral.disconnect();
return true;
} // explorePeripheral
I can adapt Klause’s code easily but I don’t understand how to work out which type of variable to use. In his central code he uses int16_t and uint16_t. In my initial code that is working on Lightblue the peripheral specifies the data as String.
Please can you help me with:
- What to use to satisfy the first script as it is to allow that to remain the same, how to read UTF-8 like in Lightblue. This is useful to understand because I want to know how to deal with the situation where a system is already set up and can not be changed. In this situation LightBlue proves it is readable and only requires a change to UTF-8.
- How it should be done and whether 1 is correct or incorrect in any way or just a preference. Update I have found that @Klaus_K mentions in another post that Temperature is specified by BLE “as UUID 2A6E Type sint16”
So maybe I now have part of my answer to question 2 but any other follow ups appreciated, especially to question 1, if it is specified as String in the first code and so easily adjusted to UTF-8 in LightBlue is it easy also to just apply the same on a central?
Thanks for your help
