Hello everyone here I hope you are doing amazing.
I am developing a program where I can send the temperature readings from a BLE SENSE 33 REV2 to an ESP32. I have already successfully made the connection using the libraries: ArduinoBLE and ESP32 BLE Arduino. I am currently using a modified version of the battery monitor from the ArduinoBLE library which has allowed me to take the reading from the built-in sensor "HS300x" I've checked already with my phone and other devices and it is successfully sending the information so any terminal can nRF terminal can read.
I am also using the ESP32 client example to read the values from the BLE SENSE but even when I am having a good connection between the 2 devices, the results print look like this:
Notify callback for characteristic 00002a19-0000-1000-8000-00805f9b34fb of data length 1
data: ?��?
As I said before I am Using the Battery monitor example and I am also using the same UUIDs that probably do not allow to me get the readings. I am new to this topic and also this example is kind of new to me. I am happy I could make the connection between those 2 devices. I would highly appreciate any advice or example or explanation anything would be super welcome.
Here are my two sketches
/*
Temperature Monitor
This example creates a Bluetooth® Low Energy peripheral with the standard battery service and
level characteristic. The A0 pin is used to calculate the battery level.
The circuit:
- Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT,
Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board.
You can use a generic Bluetooth® Low Energy central app, like LightBlue (iOS and Android) or
nRF Connect (Android), to interact with the services and characteristics
created in this sketch.
This example code is in the public domain.
*/
#include <ArduinoBLE.h>
#include <Arduino_HS300x.h>
// Bluetooth® Low Energy Battery Service
BLEService temperatureService("180F");
// Bluetooth® Low Energy Battery Level Characteristic
BLEUnsignedCharCharacteristic temperatureLevelChar("2A19", // standard 16-bit characteristic UUID
BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
float old_temp = 0;
float old_hum = 0;
// last battery level reading from analog input
long previousMillis = 0; // last battery level reading from analog input
// last time the battery level was checked, in ms
void setup() {
Serial.begin(9600); // initialize serial communication
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
if (!HS300x.begin()) {
Serial.println("Failed to initialize humidity temperature sensor!");
while (1);
}
// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
/* Set a local name for the Bluetooth® Low Energy device
This name will appear in advertising packets
and can be used by remote devices to identify this Bluetooth® Low Energy device
The name can be changed but maybe be truncated based on space left in advertisement packet
*/
BLE.setLocalName("TemperatureMonitor");
BLE.setAdvertisedService(temperatureService); // add the service UUID
temperatureService.addCharacteristic(temperatureLevelChar); // add the battery level characteristic
BLE.addService(temperatureService); // Add the battery service
temperatureLevelChar.writeValue(old_temp); // set initial value for this characteristic
/* Start advertising Bluetooth® Low Energy. It will start continuously transmitting Bluetooth® Low Energy
advertising packets and will be visible to remote Bluetooth® Low Energy central devices
until it receives a new connection */
// start advertising
BLE.advertise();
Serial.println("Bluetooth® device active, waiting for connections...");
}
void loop() {
// wait for a Bluetooth® Low Energy central
BLEDevice central = BLE.central();
// if a central is connected to the peripheral:
if (central) {
Serial.print("Connected to central: ");
// print the central's BT address:
Serial.println(central.address());
// turn on the LED to indicate the connection:
digitalWrite(LED_BUILTIN, HIGH);
// check the battery level every 200ms
// while the central is connected:
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 200) {
previousMillis = currentMillis;
updatetemperatureLevel();
}
}
// when the central disconnects, turn off the LED:
digitalWrite(LED_BUILTIN, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
void updatetemperatureLevel() {
/* Read the current voltage level on the A0 analog input pin.
This is used here to simulate the charge level of a battery.
*/
float temperature = HS300x.readTemperature();
// print each of the sensor values
Serial.print("Temperature = ");
Serial.print(temperature);
Serial.println(" °C");
temperatureLevelChar.writeValue(temperature); // and update the battery level characteristic
old_temp = temperature;
delay(1000);
}
ESP32
/**
* A BLE client example that is rich in capabilities.
* There is a lot new capabilities implemented.
* author unknown
* updated by chegewara
*/
#include "BLEDevice.h"
//#include "BLEScan.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("180F");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("2A19");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
Serial.print("Notify callback for characteristic ");
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
Serial.println((char*)pData);
}
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer() {
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic");
// Read the value of the characteristic.
if(pRemoteCharacteristic->canRead()) {
std::string value = pRemoteCharacteristic->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if(pRemoteCharacteristic->canNotify())
pRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 5 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
} // End of setup.
// This is the Arduino main loop function.
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer()) {
Serial.println("We are now connected to the BLE Server.");
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
doConnect = false;
}
// If we are connected to a peer BLE Server, update the characteristic each time we are reached
// with the current time since boot.
if (connected) {
String newValue = "Time since boot: " + String(millis()/1000);
Serial.println("Setting new characteristic value to \"" + newValue + "\"");
// Set the characteristic's value to be the array of bytes that is actually a string.
pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
}else if(doScan){
BLEDevice::getScan()->start(0); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino
}
delay(5000); // Delay a second between loops.
} // End of loop