Implements BLE protocol v2

The only change from v1 is how the temperature is encoded. In v2, two
bytes at offset 4 and 5  represent a 16-bit signed int (in big-endian).
It contains the temperature in degrees Celsius *  100.

Fixes #29
This commit is contained in:
rbaron 2022-03-14 18:20:45 +01:00
parent 77f398757a
commit 8fd4d7222a
7 changed files with 29 additions and 23 deletions

View file

@ -35,7 +35,7 @@ Sensor data is encoded in unsigned 16 bits (2 bytes), and whenever multiple
| 0 | Protocol version (4 bits) + reserved (3 bits) + `has_lux`* (1 bit)|
| 1 | Reserved (4 bits) + increasing, wrap-around counter (4 bits) |
| 2-3 | Battery voltage in millivolts |
| 4-5 | Temperature in millidegrees Celcius |
| 4-5 | Temp in 1000 * Celsius (protocol v1) or 100 * Celsius (v2) |
| 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 |

View file

@ -27,8 +27,8 @@
// BLE.
// Prints out BLE debug info, such as the final encoded advertisement packet.
#define PRST_BLE_DEBUG 0
#define PRST_BLE_PROTOCOL_VERSION 1
#define PRST_BLE_DEBUG 1
#define PRST_BLE_PROTOCOL_VERSION 2
// There are two options for configuring the MAC address of b-parasites:
// 1. Comment out the PRST_BLE_MAC_ADDR to use a random static MAC address that
@ -60,7 +60,7 @@
#endif
// SHT3C temp/humidity sensor.
#define PRST_SHT3C_DEBUG 0
#define PRST_SHT3C_DEBUG 1
// Version-specific configuration.
#if defined(PRST_VERSION_1_1_X)

View file

@ -77,7 +77,7 @@ static void rtc_callback() {
nrf_gpio_pin_clear(PRST_PHOTO_V_PIN);
#endif
prst_ble_update_adv_data(batt_read.millivolts, temp_humi.temp_millicelcius,
prst_ble_update_adv_data(batt_read.millivolts, temp_humi.temp_celsius,
temp_humi.humidity, soil_read.relative, lux,
run_counter);
prst_adv_start();

View file

@ -29,7 +29,7 @@
| 0 | Protocol version (4 bits) + reserved (3 bits) + has_lux* (1 bit)|
| 1 | Reserved (4 bits) + increasing, wrap-around counter (4 bits) |
| 2-3 | Battery voltage in millivolts |
| 4-5 | Temperature in millidegrees Celcius |
| 4-5 | Temp in 1000 * Celsius (protocol v1) or 100 * Celsius (v2) |
| 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 |
@ -159,10 +159,9 @@ void prst_ble_init() {
init_advertisement_data();
}
void prst_ble_update_adv_data(uint16_t batt_millivolts,
uint16_t temp_millicelcius, uint16_t humidity,
uint16_t soil_moisture, uint16_t brightness,
uint8_t run_counter) {
void prst_ble_update_adv_data(uint16_t batt_millivolts, float temp_celsius,
uint16_t humidity, uint16_t soil_moisture,
uint16_t brightness, uint8_t run_counter) {
// 4 bits for a small wrap-around counter for deduplicating messages on the
// receiver.
service_data[1] = run_counter & 0x0f;
@ -170,8 +169,17 @@ void prst_ble_update_adv_data(uint16_t batt_millivolts,
service_data[2] = batt_millivolts >> 8;
service_data[3] = batt_millivolts & 0xff;
service_data[4] = temp_millicelcius >> 8;
service_data[5] = temp_millicelcius & 0xff;
#if PRST_BLE_PROTOCOL_VERSION == 1
uint16_t temp_millicelsius = temp_celsius * 1000;
service_data[4] = temp_millicelsius >> 8;
service_data[5] = temp_millicelsius & 0xff;
#elif PRST_BLE_PROTOCOL_VERSION == 2
int16_t temp_centicelsius = temp_celsius * 100;
service_data[4] = temp_centicelsius >> 8;
service_data[5] = temp_centicelsius & 0xff;
#else
#error "[ble] Unsupported BLE protocol version"
#endif // PRST_BLE_PROTOCOL_VERSION
service_data[6] = humidity >> 8;
service_data[7] = humidity & 0xff;

View file

@ -11,9 +11,8 @@ void prst_adv_start();
void prst_adv_stop();
void prst_ble_update_adv_data(uint16_t batt_millivolts,
uint16_t temp_millicelcius, uint16_t humidity,
uint16_t soil_moisture, uint16_t brightness,
uint8_t run_counter);
void prst_ble_update_adv_data(uint16_t batt_millivolts, float temp_celsius,
uint16_t humidity, uint16_t soil_moisture,
uint16_t brightness, uint8_t run_counter);
#endif // _PRST_BLE_H_

View file

@ -55,14 +55,14 @@ prst_shtc3_read_t prst_shtc3_read() {
// TODO(rbaron): verify the CRC of the measurements. The function is described
// in the datasheet.
double temp_c = -45 + 175 * ((double)((buff[0] << 8) | buff[1])) / (1 << 16);
float temp_c = -45 + 175 * ((float)((buff[0] << 8) | buff[1])) / (1 << 16);
uint16_t humi = (buff[3] << 8) | buff[4];
prst_shtc3_read_t ret = {.temp_millicelcius = temp_c * 1000,
.humidity = humi};
prst_shtc3_read_t ret = {.temp_celsius = temp_c, .humidity = humi};
#if PRST_SHT3C_DEBUG
NRF_LOG_INFO("[sht3c] Read temp: " NRF_LOG_FLOAT_MARKER " oC",
NRF_LOG_FLOAT((float)ret.temp_millicelcius / 1000.0));
NRF_LOG_FLOAT((float)ret.temp_celsius));
NRF_LOG_INFO("[sht3c] Read humi: " NRF_LOG_FLOAT_MARKER " %%",
NRF_LOG_FLOAT(100.0 * ret.humidity / 0xffff));
#endif

View file

@ -14,9 +14,8 @@
#define PRST_SHTC3_CMD_MEASURE_TFIRST_NORMAL 0x7866
typedef struct prst_shtc3_values {
// Temperature in millicelcius. To get the temp in Celcius, divide this by
// 1000.0.
int16_t temp_millicelcius;
// Temperature in degrees Celsius.
float temp_celsius;
// Relative humidity, from 0 to 2^16.
uint16_t humidity;
} prst_shtc3_read_t;