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"
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue