Implements BTHome v1 and v2 encodings for ble sample

This commit is contained in:
rbaron 2022-11-29 20:05:41 +01:00
parent 4a6e3dcec3
commit 3b104cdf24
9 changed files with 123 additions and 29 deletions

View file

@ -8,7 +8,7 @@
#include "prstlib/macros.h"
LOG_MODULE_REGISTER(adc, LOG_LEVEL_DBG);
LOG_MODULE_REGISTER(adc, LOG_LEVEL_WRN);
// PWM spec for square wave. Input to the soil sensing circuit.
static const struct pwm_dt_spec soil_pwm_dt =
@ -115,6 +115,5 @@ int prst_adc_photo_read(float battery_voltage, prst_adc_photo_sensor_t* out) {
const float lux_sun = 10000.0f;
const float current = out->adc_read.voltage / phototransistor_resistor;
out->brightness = MAX(0, MIN(lux_sun * current / current_sun, UINT16_MAX));
return 0;
}

View file

@ -6,7 +6,7 @@
#include "prstlib/led.h"
#include "prstlib/macros.h"
LOG_MODULE_REGISTER(button, LOG_LEVEL_DBG);
LOG_MODULE_REGISTER(button, LOG_LEVEL_WRN);
static struct gpio_dt_spec button =
GPIO_DT_SPEC_GET(DT_NODELABEL(button0), gpios);

View file

@ -4,7 +4,7 @@
#include "prstlib/macros.h"
LOG_MODULE_REGISTER(led, LOG_LEVEL_DBG);
LOG_MODULE_REGISTER(led, LOG_LEVEL_WRN);
struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_NODELABEL(led0), gpios);

View file

@ -6,7 +6,7 @@
#include "prstlib/led.h"
#include "prstlib/macros.h"
LOG_MODULE_REGISTER(sensors, LOG_LEVEL_DBG);
LOG_MODULE_REGISTER(sensors, LOG_LEVEL_WRN);
int prst_sensors_read_all(prst_sensors_t *sensors) {
RET_IF_ERR(prst_adc_batt_read(&sensors->batt));

View file

@ -6,7 +6,7 @@
#include "prstlib/macros.h"
LOG_MODULE_REGISTER(shtc3, LOG_LEVEL_INF);
LOG_MODULE_REGISTER(shtc3, LOG_LEVEL_WRN);
static const struct i2c_dt_spec shtc3 = I2C_DT_SPEC_GET(DT_NODELABEL(shtc3));

View file

@ -34,8 +34,11 @@ choice PRST_BLE_ENCODING
config PRST_BLE_ENCODING_BPARASITE_V2
bool "Uses the custom b-parasite protocol v2 for encoding advertising packets"
config PRST_BLE_ENCODING_BTHOME
bool "Uses the BTHome (bthome.io) BLE encoding"
config PRST_BLE_ENCODING_BTHOME_V1
bool "Uses the BTHome (bthome.io) BLE encoding (v1)"
config PRST_BLE_ENCODING_BTHOME_V2
bool "Uses the BTHome (bthome.io) BLE encoding (v2)"
endchoice # PRST_BLE_ENCODING
@ -44,4 +47,5 @@ config PRST_BLE_ENCODING_SERVICE_DATA_LEN
help
Size of the service data buffer
default 20 if PRST_BLE_ENCODING_BPARASITE_V2
default 18 if PRST_BLE_ENCODING_BTHOME
default 18 if PRST_BLE_ENCODING_BTHOME_V1
default 19 if PRST_BLE_ENCODING_BTHOME_V2

View file

@ -1,5 +1,5 @@
# Enabling log has a big impact in power consumption. Only enable it while debugging.
CONFIG_LOG=n
CONFIG_LOG=y
CONFIG_PWM=y
CONFIG_CBPRINTF_FP_SUPPORT=y
CONFIG_I2C=y
@ -8,10 +8,7 @@ CONFIG_GPIO=y
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEBUG_LOG=n
CONFIG_BT_DEVICE_NAME="prst"
CONFIG_BT_SETTINGS=n
CONFIG_SETTINGS=n
CONFIG_BT_CTLR_TX_PWR_PLUS_8=y
CONFIG_SERIAL=n
@ -21,8 +18,13 @@ CONFIG_PM_DEVICE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_CONSOLE=n
CONFIG_RTT_CONSOLE=n
CONFIG_PINCTRL=y
# Otherwise a weird float multiplication error?
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_PRST_SLEEP_DURATION_SEC=600
# Application config.
# See all options in Kconfig.
# CONFIG_PRST_SLEEP_DURATION_SEC=600
# CONFIG_PRST_BLE_ENCODING_BTHOME_V2=y

View file

@ -7,7 +7,7 @@
#include "encoding.h"
LOG_MODULE_REGISTER(ble, LOG_LEVEL_DBG);
LOG_MODULE_REGISTER(ble, LOG_LEVEL_INF);
static uint8_t service_data[CONFIG_PRST_BLE_ENCODING_SERVICE_DATA_LEN] = {0};
@ -17,16 +17,17 @@ static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME),
};
static const struct bt_data sd[] = {
BT_DATA_BYTES(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME),
};
static const struct bt_data sd[] = {};
static bt_addr_le_t mac_addr;
// bt_addr_le_t.a holds the MAC address in big-endian.
static int get_mac_addr(bt_addr_le_t *out) {
struct bt_le_oob oob;
RET_IF_ERR(bt_le_oob_get_local(BT_ID_DEFAULT, &oob));
LOG_HEXDUMP_DBG(oob.addr.a.val, ARRAY_SIZE(oob.addr.a.val),
"Read address using bt_le_oob_get_local");
const uint8_t *addr = oob.addr.a.val;
LOG_INF("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
*out = oob.addr;
return 0;
}
@ -36,6 +37,8 @@ int prst_ble_init() {
if (IS_ENABLED(CONFIG_SETTINGS)) {
RET_IF_ERR_MSG(settings_load(), "Error in settings_load()");
}
RET_IF_ERR(get_mac_addr(&mac_addr));
return 0;
}
@ -52,8 +55,6 @@ int prst_ble_adv_stop() {
}
int prst_ble_adv_set_data(const prst_sensors_t *sensors) {
bt_addr_le_t addr;
RET_IF_ERR(get_mac_addr(&addr));
return prst_ble_encode_service_data(sensors, &addr, service_data,
return prst_ble_encode_service_data(sensors, &mac_addr, service_data,
sizeof(service_data));
}

View file

@ -3,7 +3,7 @@
#include <logging/log.h>
#include <prstlib/macros.h>
LOG_MODULE_DECLARE(ble, LOG_LEVEL_DBG);
LOG_MODULE_DECLARE(ble, LOG_LEVEL_INF);
int prst_ble_encode_service_data(const prst_sensors_t* sensors,
const bt_addr_le_t* bt_addr, uint8_t* out,
@ -38,10 +38,98 @@ int prst_ble_encode_service_data(const prst_sensors_t* sensors,
memcpy(out + 12, bt_addr->a.val, BT_ADDR_SIZE);
out[18] = sensors->photo.brightness >> 8;
out[19] = sensors->photo.brightness & 0xff;
#elif CONFIG_PRST_BLE_ENCODING_BTHOME
// TODO.
memset(out, 0xab, out_len);
// https://bthome.io/v1/
#elif CONFIG_PRST_BLE_ENCODING_BTHOME_V1
out[0] = 0x1c;
out[1] = 0x18;
// 1. Soil moisture.
// uint16_t.
out[2] = (0b000 << 5) | 3;
// Type of measurement - Moisture.
out[3] = 0x14;
// Value. Factor of 0.01, so we need to multiply our the value in 100% by
// 1/0.01 = 100.
uint16_t soil_val = 10000 * sensors->soil.percentage;
out[4] = soil_val & 0xff;
out[5] = soil_val >> 8;
// 2. Temp.
// int16_t.
out[6] = (0b001 << 5) | 3;
// Type of measurement - temperature.
out[7] = 0x02;
// Value. Factor 0.01.
int16_t temp_val = 100 * sensors->shtc3.temp_c;
out[8] = temp_val & 0xff;
out[9] = temp_val >> 8;
// 3. Humidity
// uint16_t.
out[10] = (0b000 << 5) | 3;
// Type - humidity.
out[11] = 0x03;
// Value. Factor 0.01, over 100%.
uint16_t humi_val = 10000 * sensors->shtc3.rel_humi;
out[12] = humi_val & 0xff;
out[13] = humi_val >> 8;
// 4. Battery voltage.
// uint16_t.
out[14] = (0b000 << 5) | 3;
// Type - voltage.
out[15] = 0x0c;
// Value. Factor of 0.001.
uint16_t batt_val = sensors->batt.millivolts;
out[16] = batt_val & 0xff;
out[17] = batt_val >> 8;
// https://bthome.io/format/
#elif CONFIG_PRST_BLE_ENCODING_BTHOME_V2
// 0xfcd2 - bthome.io service UUID.
out[0] = 0xd2;
out[1] = 0xfc;
// Service header - no encryption, bt home v2.
out[2] = 0x40;
// Soil moisture.
out[3] = 0x14;
// Factor of 0.01, so we need to multiply our the value in 100% by 1/0.01 = 100.
uint16_t soil_val = 10000 * sensors->soil.percentage;
out[4] = soil_val & 0xff;
out[5] = soil_val >> 8;
// Temperature.
out[6] = 0x02;
int16_t temp_val = 100 * sensors->shtc3.temp_c;
out[7] = temp_val & 0xff;
out[8] = temp_val >> 8;
// Humidity.
out[9] = 0x03;
// Value. Factor 0.01, over 100%.
uint16_t humi_val = 10000 * sensors->shtc3.rel_humi;
out[10] = humi_val & 0xff;
out[11] = humi_val >> 8;
// Battery voltage.
out[12] = 0x0c;
// Value. Factor of 0.001.
uint16_t batt_val = sensors->batt.millivolts;
out[13] = batt_val & 0xff;
out[14] = batt_val >> 8;
// Illuminance.
out[15] = 0x05;
out[16] = sensors->photo.brightness >> 16;
out[17] = (sensors->photo.brightness >> 8) & 0xff;
out[18] = sensors->photo.brightness & 0xff;
#endif // Enccoding protocols
LOG_HEXDUMP_DBG(out, out_len, "Encoded BLE adv: ");
return 0;
}