Advertising Temperature Data Using XIAO BLE Sense and SHTC3
XIAO BLE Sense is one of the XIAO products by Seeed Studio that uses nRF52840 system on chip, a powerful SoC equipped with Bluetooth 5.0 and ARM Cortex-M4 CPU. It’s only natural that we want to utilize the BLE capability of the SoC.
Background
I wanted to monitor the temperature measurement of different rooms in my house. I prefer using BLE for the data transmission mechanism because I have a few BLE-capable devices, and XIAO BLE Sense is one of them. A dedicated computer is prepared to capture data from every BLE device. That dedicated computer runs data aggregation software and a time-series database.
Having a single computer connected to every BLE device does not feel right. Instead of forming a connection via BLE, the computer scans for all advertisement data from the BLE devices and extracts the temperature data.
For this purpose, I used the SHTC3 temperature and humidity sensor by Sensirion because it is the only sensor available in my arsenal. I used the Adafruit_SHTC3 library by Adafruit along with the ArduinoBLE library for broadcasting the advertisement data.
Implementation
In the early stage of development, I want to broadcast data as often as possible. I chose three seconds as the interval of data acquisition and data transmission.
First, we include the necessary header files.
#include <Arduino.h>
#include <ArduinoBLE.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_SHTC3.h>
Then, we initialize some global variables. One is the object of the Adafruit_SHTC3 class, and the others are the sensors event for both temperature and relative humidity data.
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();sensors_event_t humid, temp;
The program is quite simple, so we are ok with at least three global variables in our code.
Next, we initialize the BLE and SHTC3 objects and check for errors in the setup function. If any error happens during this stage, we print the error message and loop indefinitely.
Serial.begin(115200);if (!BLE.begin())
{
Serial.println("starting BLE failed!");
while (1);
}Serial.println("Starting BLE ok!");
Serial.println("Initializing SHTC3...");if (!shtc3.begin())
{
Serial.println("Couldn't find SHTC3!");
while (1);
}Serial.println("SHTC3 initialization ok!");
Then, we set the local name for the BLE device. Here we set XIAO as the local name.
BLE.setLocalName("XIAO");
Next, in the loop function, we create an object of BLEAdvertisingData class that will hold the temperature data. We also set the BR/EDR not supported flag and general discoverable flag.
BLE.stopAdvertising();
BLEAdvertisingData advData;advData.setFlags(BLEFlagsBREDRNotSupported | BLEFlagsGeneralDiscoverable);
Then, we measure the temperature and humidity and store the data to the global variables humid and temp.
shtc3.getEvent(&humid, &temp);
Next, we must convert the temperature measurement into a signed 16-bit integer and store each byte in an array of unsigned chars. Then we call the setAdvertisedServiceData function to advertise the temperature measurement.
int16_t temperature_i16 = temp.temperature * 100;
unsigned char temperature[2] = {
(unsigned char)(temperature_i16 & 0xFF),
(unsigned char)(temperature_i16 >> 8),
};advData.setAdvertisedServiceData(0x2A6E, temperature, sizeof(temperature));
The array holds the temperature data in a big-endian manner where the high byte comes first. We call the setAdvertisedServiceData function with 0x2A6E as the UUID of temperature data as the first argument, the temperature data array, and the size of temperature data as the second and the third argument.
Then, we broadcast the advertisement data by calling the setAdvertisingData function with the advData object as the only argument and calling advertise function to advertise the data.
BLE.setAdvertisingData(advData);
BLE.advertise();
Next, we put delay function with 3000 milliseconds as the argument to sleep for three seconds. Note that the delay function in XIAO BLE Sense puts the microcontroller to light sleep or even deep sleep if nothing prevents the deep sleep.
delay(3000);
Compile and upload the code to XIAO BLE Sense, then read the advertisement data from an app called nRF Connect (available for iOS and Android).
Here is the entire code:
The above code works with a single service data in the advertisement packet. So, what should we do if we want to put more service data? There is a way, but we need to understand how the advertisement data is formatted.
In short, we need to put the data into an array of bytes and then call the setRawData function of BLEAdvertisingData class with that array as the first argument and the length as the second argument. We will explore more in a future post.
If you have not received your XIAO BLE or XIAO BLE Sense yet, or you have another kind of temperature sensor on your shelf, you can apply the same code. All you need to do is replace the sensor-related code, then make sure that your board is compatible with the ArduinoBLE library.
Thanks for reading, and see you in the next post.