Implements BTHome v1 and v2 encodings for ble sample
This commit is contained in:
parent
4a6e3dcec3
commit
3b104cdf24
9 changed files with 123 additions and 29 deletions
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "prstlib/macros.h"
|
#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.
|
// PWM spec for square wave. Input to the soil sensing circuit.
|
||||||
static const struct pwm_dt_spec soil_pwm_dt =
|
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 lux_sun = 10000.0f;
|
||||||
const float current = out->adc_read.voltage / phototransistor_resistor;
|
const float current = out->adc_read.voltage / phototransistor_resistor;
|
||||||
out->brightness = MAX(0, MIN(lux_sun * current / current_sun, UINT16_MAX));
|
out->brightness = MAX(0, MIN(lux_sun * current / current_sun, UINT16_MAX));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "prstlib/led.h"
|
#include "prstlib/led.h"
|
||||||
#include "prstlib/macros.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 =
|
static struct gpio_dt_spec button =
|
||||||
GPIO_DT_SPEC_GET(DT_NODELABEL(button0), gpios);
|
GPIO_DT_SPEC_GET(DT_NODELABEL(button0), gpios);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "prstlib/macros.h"
|
#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);
|
struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_NODELABEL(led0), gpios);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "prstlib/led.h"
|
#include "prstlib/led.h"
|
||||||
#include "prstlib/macros.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) {
|
int prst_sensors_read_all(prst_sensors_t *sensors) {
|
||||||
RET_IF_ERR(prst_adc_batt_read(&sensors->batt));
|
RET_IF_ERR(prst_adc_batt_read(&sensors->batt));
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "prstlib/macros.h"
|
#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));
|
static const struct i2c_dt_spec shtc3 = I2C_DT_SPEC_GET(DT_NODELABEL(shtc3));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,11 @@ choice PRST_BLE_ENCODING
|
||||||
config PRST_BLE_ENCODING_BPARASITE_V2
|
config PRST_BLE_ENCODING_BPARASITE_V2
|
||||||
bool "Uses the custom b-parasite protocol v2 for encoding advertising packets"
|
bool "Uses the custom b-parasite protocol v2 for encoding advertising packets"
|
||||||
|
|
||||||
config PRST_BLE_ENCODING_BTHOME
|
config PRST_BLE_ENCODING_BTHOME_V1
|
||||||
bool "Uses the BTHome (bthome.io) BLE encoding"
|
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
|
endchoice # PRST_BLE_ENCODING
|
||||||
|
|
||||||
|
|
@ -44,4 +47,5 @@ config PRST_BLE_ENCODING_SERVICE_DATA_LEN
|
||||||
help
|
help
|
||||||
Size of the service data buffer
|
Size of the service data buffer
|
||||||
default 20 if PRST_BLE_ENCODING_BPARASITE_V2
|
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
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# Enabling log has a big impact in power consumption. Only enable it while debugging.
|
# Enabling log has a big impact in power consumption. Only enable it while debugging.
|
||||||
CONFIG_LOG=n
|
CONFIG_LOG=y
|
||||||
CONFIG_PWM=y
|
CONFIG_PWM=y
|
||||||
CONFIG_CBPRINTF_FP_SUPPORT=y
|
CONFIG_CBPRINTF_FP_SUPPORT=y
|
||||||
CONFIG_I2C=y
|
CONFIG_I2C=y
|
||||||
|
|
@ -8,10 +8,7 @@ CONFIG_GPIO=y
|
||||||
|
|
||||||
CONFIG_BT=y
|
CONFIG_BT=y
|
||||||
CONFIG_BT_PERIPHERAL=y
|
CONFIG_BT_PERIPHERAL=y
|
||||||
CONFIG_BT_DEBUG_LOG=n
|
|
||||||
CONFIG_BT_DEVICE_NAME="prst"
|
CONFIG_BT_DEVICE_NAME="prst"
|
||||||
CONFIG_BT_SETTINGS=n
|
|
||||||
CONFIG_SETTINGS=n
|
|
||||||
CONFIG_BT_CTLR_TX_PWR_PLUS_8=y
|
CONFIG_BT_CTLR_TX_PWR_PLUS_8=y
|
||||||
|
|
||||||
CONFIG_SERIAL=n
|
CONFIG_SERIAL=n
|
||||||
|
|
@ -21,8 +18,13 @@ CONFIG_PM_DEVICE=y
|
||||||
CONFIG_USE_SEGGER_RTT=y
|
CONFIG_USE_SEGGER_RTT=y
|
||||||
|
|
||||||
CONFIG_CONSOLE=n
|
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
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include "encoding.h"
|
#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};
|
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),
|
BT_DATA_BYTES(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct bt_data sd[] = {
|
static const struct bt_data sd[] = {};
|
||||||
BT_DATA_BYTES(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME),
|
|
||||||
};
|
static bt_addr_le_t mac_addr;
|
||||||
|
|
||||||
// bt_addr_le_t.a holds the MAC address in big-endian.
|
// bt_addr_le_t.a holds the MAC address in big-endian.
|
||||||
static int get_mac_addr(bt_addr_le_t *out) {
|
static int get_mac_addr(bt_addr_le_t *out) {
|
||||||
struct bt_le_oob oob;
|
struct bt_le_oob oob;
|
||||||
RET_IF_ERR(bt_le_oob_get_local(BT_ID_DEFAULT, &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),
|
const uint8_t *addr = oob.addr.a.val;
|
||||||
"Read address using bt_le_oob_get_local");
|
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;
|
*out = oob.addr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +37,8 @@ int prst_ble_init() {
|
||||||
if (IS_ENABLED(CONFIG_SETTINGS)) {
|
if (IS_ENABLED(CONFIG_SETTINGS)) {
|
||||||
RET_IF_ERR_MSG(settings_load(), "Error in settings_load()");
|
RET_IF_ERR_MSG(settings_load(), "Error in settings_load()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RET_IF_ERR(get_mac_addr(&mac_addr));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,8 +55,6 @@ int prst_ble_adv_stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int prst_ble_adv_set_data(const prst_sensors_t *sensors) {
|
int prst_ble_adv_set_data(const prst_sensors_t *sensors) {
|
||||||
bt_addr_le_t addr;
|
return prst_ble_encode_service_data(sensors, &mac_addr, service_data,
|
||||||
RET_IF_ERR(get_mac_addr(&addr));
|
|
||||||
return prst_ble_encode_service_data(sensors, &addr, service_data,
|
|
||||||
sizeof(service_data));
|
sizeof(service_data));
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
#include <prstlib/macros.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,
|
int prst_ble_encode_service_data(const prst_sensors_t* sensors,
|
||||||
const bt_addr_le_t* bt_addr, uint8_t* out,
|
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);
|
memcpy(out + 12, bt_addr->a.val, BT_ADDR_SIZE);
|
||||||
out[18] = sensors->photo.brightness >> 8;
|
out[18] = sensors->photo.brightness >> 8;
|
||||||
out[19] = sensors->photo.brightness & 0xff;
|
out[19] = sensors->photo.brightness & 0xff;
|
||||||
#elif CONFIG_PRST_BLE_ENCODING_BTHOME
|
|
||||||
// TODO.
|
// https://bthome.io/v1/
|
||||||
memset(out, 0xab, out_len);
|
#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
|
#endif // Enccoding protocols
|
||||||
|
|
||||||
|
LOG_HEXDUMP_DBG(out, out_len, "Encoded BLE adv: ");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue