Uses service data instead of manufacturer specific data for advertising sensor values
This commit is contained in:
parent
02e2f3d074
commit
df97f89bd9
2 changed files with 37 additions and 14 deletions
|
|
@ -13,17 +13,26 @@ constexpr int kSensAnalogPin = 4; // AIN2
|
||||||
constexpr int kDischargeEnablePin = 16;
|
constexpr int kDischargeEnablePin = 16;
|
||||||
constexpr double kPWMFrequency = 500000;
|
constexpr double kPWMFrequency = 500000;
|
||||||
|
|
||||||
char manufacturer_data[] = {
|
|
||||||
0x01,
|
|
||||||
0x02,
|
|
||||||
0x03,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr int kManufacturerDataLen = 3;
|
constexpr int kManufacturerDataLen = 3;
|
||||||
|
|
||||||
|
// We can have at most 31 bytes here.
|
||||||
|
uint8_t advertisement_data[] = {
|
||||||
|
9, // Length of name.
|
||||||
|
BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME,
|
||||||
|
'P', 'a', 'r', 'a', 's', 'i', 't', 'e',
|
||||||
|
7, // Length of the service data.
|
||||||
|
BLE_GAP_AD_TYPE_SERVICE_DATA,
|
||||||
|
0x1a, 0x18, // Environment sensor service UUID.
|
||||||
|
0x00, 0x00, // Raw soil humidity.
|
||||||
|
0x00, 0x00, // Percentage soil humidity.
|
||||||
|
};
|
||||||
|
constexpr size_t kRawSoilMoistureOffset = 14;
|
||||||
|
constexpr size_t kPercentSoilMoistureOffset = kRawSoilMoistureOffset + 2;
|
||||||
|
constexpr size_t kTemperatureOfsset = kRawSoilMoistureOffset + 4;
|
||||||
|
|
||||||
ble_gap_addr_t kGAPAddr{
|
ble_gap_addr_t kGAPAddr{
|
||||||
1,
|
1,
|
||||||
BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
|
BLE_GAP_ADDR_TYPE_PUBLIC,
|
||||||
// This is the "reverse" order in comparison that the colon-separated
|
// This is the "reverse" order in comparison that the colon-separated
|
||||||
// human-readable MAC addresses.
|
// human-readable MAC addresses.
|
||||||
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
|
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
|
||||||
|
|
@ -36,13 +45,16 @@ void setupAdvertising() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateAdvertisingData(int moisture_level) {
|
void updateAdvertisingData(int moisture_level) {
|
||||||
manufacturer_data[2] = moisture_level & 0xff;
|
uint16_t packed_raw_moisture = moisture_level;
|
||||||
manufacturer_data[1] = 0xff;
|
advertisement_data[kRawSoilMoistureOffset] = packed_raw_moisture >> 1;
|
||||||
|
advertisement_data[kRawSoilMoistureOffset + 1] = packed_raw_moisture & 0xff;
|
||||||
|
// manufacturer_data[1] = 0xff;
|
||||||
Bluefruit.Advertising.stop();
|
Bluefruit.Advertising.stop();
|
||||||
Bluefruit.Advertising.clearData();
|
Bluefruit.Advertising.clearData();
|
||||||
Bluefruit.Advertising.addName();
|
// Bluefruit.Advertising.addName();
|
||||||
Bluefruit.Advertising.addManufacturerData(manufacturer_data,
|
// Bluefruit.Advertising.addManufacturerData(manufacturer_data,
|
||||||
kManufacturerDataLen);
|
// kManufacturerDataLen);
|
||||||
|
Bluefruit.Advertising.setData(advertisement_data, sizeof(advertisement_data));
|
||||||
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
|
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
|
||||||
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
|
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
|
||||||
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
|
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
|
||||||
|
|
@ -58,6 +70,12 @@ void setup() {
|
||||||
analogReference(AR_VDD4);
|
analogReference(AR_VDD4);
|
||||||
|
|
||||||
setupAdvertising();
|
setupAdvertising();
|
||||||
|
|
||||||
|
Serial.println("Will advertise with MAC:");
|
||||||
|
for (const auto byte : kGAPAddr.addr) {
|
||||||
|
Serial.printf("0x%02x ", byte);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,11 @@ I'm getting ~680 when in the air; ~65 while holding the sensor. The default reso
|
||||||
* [main_loop](https://github.com/atc1441/ATC_MiThermometer/blob/916cef7db24977ec187e68ab6e718b7b7a4988e6/ATC_Thermometer/app.c#L76)
|
* [main_loop](https://github.com/atc1441/ATC_MiThermometer/blob/916cef7db24977ec187e68ab6e718b7b7a4988e6/ATC_Thermometer/app.c#L76)
|
||||||
* [advertisement_data](https://github.com/atc1441/ATC_MiThermometer/blob/master/ATC_Thermometer/ble.c#L39) definition
|
* [advertisement_data](https://github.com/atc1441/ATC_MiThermometer/blob/master/ATC_Thermometer/ble.c#L39) definition
|
||||||
* [set_adv_data](https://github.com/atc1441/ATC_MiThermometer/blob/master/ATC_Thermometer/ble.c#L178) - where the temp, humidity and batt levels are encoded into the advertisement data
|
* [set_adv_data](https://github.com/atc1441/ATC_MiThermometer/blob/master/ATC_Thermometer/ble.c#L178) - where the temp, humidity and batt levels are encoded into the advertisement data
|
||||||
|
* They don't use manufacturer data. They use a custom UUID service (0x181a).
|
||||||
|
* Using the manufacturer data requires a SIG membership for getting the manufacturer ID (first two bytes in the manufacturer data)
|
||||||
|
* Using the service data also requires applying for a 16-bit (2 byte) ID from SIG ([link](https://www.bluetooth.com/specifications/assigned-numbers/))
|
||||||
|
* Aha! I think we can use the 0x181a service UUID (the same one the alternative xiaomi firmware uses). This service is reserved for "Environmental Sensors". Check out the offical assigned numbers list [here](https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf).
|
||||||
|
* We can use the SERVICE_DATA (int 16) in the BLE advertisement packet to pack service data for the UUID 0x181a.
|
||||||
* How the xiaomi BLE temp sensor works in ESPHome: [link](https://github.com/esphome/esphome/blob/5c86f332b269fd3e4bffcbdf3359a021419effdd/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp)
|
* How the xiaomi BLE temp sensor works in ESPHome: [link](https://github.com/esphome/esphome/blob/5c86f332b269fd3e4bffcbdf3359a021419effdd/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp)
|
||||||
* [How advertisement works YouTube video](https://www.youtube.com/watch?v=CJcLabp42b4) by nordic
|
* [How advertisement works YouTube video](https://www.youtube.com/watch?v=CJcLabp42b4) by nordic
|
||||||
* In your case:
|
* In your case:
|
||||||
|
|
@ -176,8 +181,8 @@ I'm getting ~680 when in the air; ~65 while holding the sensor. The default reso
|
||||||
* Can we update the manufaturer advertising data dynamically?
|
* Can we update the manufaturer advertising data dynamically?
|
||||||
* [Hint on devzone.nordicsemi.com](https://devzone.nordicsemi.com/f/nordic-q-a/11217/adc-values-in-advertising-data-dynamically-changing)
|
* [Hint on devzone.nordicsemi.com](https://devzone.nordicsemi.com/f/nordic-q-a/11217/adc-values-in-advertising-data-dynamically-changing)
|
||||||
* What MAC address to use?
|
* What MAC address to use?
|
||||||
* Public
|
* Public - might have some security implications, since BLE can be used for tracking
|
||||||
* Random
|
* Random - safer, since its random, but it "breaks" our MAC-addr based Hub config
|
||||||
|
|
||||||
## Packing values into the advertising packet
|
## Packing values into the advertising packet
|
||||||
### Soil humidity
|
### Soil humidity
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue