From 795fc46849dd3f32a852905792ed387e5d9d71c3 Mon Sep 17 00:00:00 2001 From: rbaron Date: Sun, 2 May 2021 20:20:39 +0200 Subject: [PATCH] Updates docs for data encoding in the BLE advertisement packet --- README.md | 3 +++ code/b-parasite/README.md | 18 +++++++++++++++++- code/b-parasite/src/prst/ble.c | 13 +++++++++++++ code/b-parasite/src/prst/shtc3.c | 2 +- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f7a587c..b74c8a6 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ Another possibility is running [parasite-scanner](https://github.com/rbaron/para This is the quickest way to collect and visualize data from b-parasites, and I personally use it a lot for testing and debugging. +## Protocol and Data Encoding +Sensor data is transmitted via BLE advertisement broadcasts. [Here](./code/b-parasite/README.md) you can find a byte-by-byte description of the data as it is encoded inside the advertisement packet. + # Battery Life **tl;dr:** By taking readings 10 minutes apart, the battery should last for over a year. diff --git a/code/b-parasite/README.md b/code/b-parasite/README.md index 8367bae..06aa32f 100644 --- a/code/b-parasite/README.md +++ b/code/b-parasite/README.md @@ -22,4 +22,20 @@ Calls to `NRF_LOG` will be readable on the console using `JLinkRTTLogger`. This ```bash $ echo "\n\n\n\n0\n/dev/stdout" | JLinkRTTLogger | sed 's/^.*app: //' -``` \ No newline at end of file +``` + +# Bluetooth Low Energy Advertisement Data Encoding +Sensor data is encoded in the BLE advertisement packet as Service Data for the [Environmental Sensing Service profile](https://www.bluetooth.com/specifications/assigned-numbers/environmental-sensing-service-characteristics/) (UUID 0x181a). + +Sensor data is encoded in unsigned 16 bits (2 bytes), and whenever multiple + bytes are used to represent a single value, the encoding is big-endian. + +| Byte index | Description | +|------------|----------------------------------------------------------------| +| 0 | 4 bits for protocol version + 4 reserved bits | +| 1 | 4 reserved bits + 4 bits wrap-around counter for deduplication | +| 2-3 | Battery voltage in millivolts | +| 4-5 | Temperature in millidegrees Celcius | +| 6-7 | Relative air humidity, scaled from 0 (0%) to 0xffff (100%) | +| 8-9 | Soil moisture, scaled from from 0 (0%) to 0xffff (100%) | +| 10-15 | b-parasite's own MAC address, big-endian format | diff --git a/code/b-parasite/src/prst/ble.c b/code/b-parasite/src/prst/ble.c index 8f41d60..ea0e026 100644 --- a/code/b-parasite/src/prst/ble.c +++ b/code/b-parasite/src/prst/ble.c @@ -21,6 +21,19 @@ // Sensor data payload that will go into the advertisement message. // We have a maximum of 20 bytes to play with here. +// Sensor data is encoded in unsigned 16 bits (2 bytes), and whenever multiple +// bytes are used to represent a single value, the encoding is big-endian: +/* +| Byte index | Description | +|------------|----------------------------------------------------------------| +| 0 | 4 bits for protocol version + 4 reserved bits | +| 1 | 4 reserved bits + 4 bits wrap-around counter for deduplication | +| 2-3 | Battery voltage in millivolts | +| 4-5 | Temperature in millidegrees Celcius | +| 6-7 | Relative air humidity, scaled from 0 (0%) to 0xffff (100%) | +| 8-9 | Soil moisture, scaled from from 0 (0%) to 0xffff (100%) | +| 10-15 | b-parasite's own MAC address | +*/ #define SERVICE_DATA_LEN 16 static uint8_t service_data[SERVICE_DATA_LEN]; diff --git a/code/b-parasite/src/prst/shtc3.c b/code/b-parasite/src/prst/shtc3.c index bf5df59..7fa6b0c 100644 --- a/code/b-parasite/src/prst/shtc3.c +++ b/code/b-parasite/src/prst/shtc3.c @@ -64,7 +64,7 @@ prst_shtc3_read_t prst_shtc3_read() { NRF_LOG_INFO("[sht3c] Read temp: " NRF_LOG_FLOAT_MARKER " oC", NRF_LOG_FLOAT((float)ret.temp_millicelcius / 1000.0)); NRF_LOG_INFO("[sht3c] Read humi: " NRF_LOG_FLOAT_MARKER " %%", - NRF_LOG_FLOAT(100.0 * ret.humidity / (1 << 16))); + NRF_LOG_FLOAT(100.0 * ret.humidity / 0xffff)); #endif return ret; } \ No newline at end of file