Blog Custom IoT solution using nRF52840 and Raspberry Pi
After years of thinking about it, I have finally started to actually delve into the world of BLE. As often with communication technologies, especially with wireless, with BLE a big part of the development is actually reading specifications and standards and implementing your code accordingly. With BLE communication the focus is on concepts such as GAP and GATT, which define the nature of the service a certain device offers. Everything is distinguished using universally unique identifiers, UUIDs.
In my project, SlumSense, I use nRF52840 on Thingy91 as a sensor platform. It has an onboard environmental sensor, Bosch BME680, which I am using to record temperature, humidity and air pressure. At some point I could also implement full air quality index measurement which is possible using BME's gas resistance sensor combined with the other readings. While not in sleep, the sensor platform advertises itself, allowing any BLE client to bond with it. After connected, the client will send a message to enable notifications on the sensor. That will trigger the sensor's measurement timer, which will sample BME periodically and notify the client of new data. The data is read using TWI. The client, which is actually a Raspberry Pi 3b+, after receiving the measurements from the sensor, packages and sends them to my server using a REST API. The client, which I call Gateway or SlumWay, has an API key saved on board that allows storing data to the server. The server can set configurations for the Gateway, which will periodically read its configs from the server using the said REST API.
I'm planning on writing more detailed report of the project at some point but we will see if that will ever actually happen.
Here is the current implementation of main
, demonstrating the structure of the program.
/**@brief Function for application main entry.
*/
int main(void)
{
// Initialize.
log_init();
timers_init();
power_management_init();
NRF_LOG_INFO("Initializing services...");
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
NRF_LOG_INFO("Initializing sensors...");
sensors_init();
sensors_configure();
NRF_LOG_INFO("Initialized. Starting...");
application_timers_start();
// start BLE advertising
advertising_start();
// enter main loop
for (;;)
{
idle_state_handle();
}
}
Topology
This figure illustrates the high-level topology of the system: