diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..945388b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.swp +.vscode diff --git a/code/parasite/platformio.ini b/code/parasite/platformio.ini index 04dbfa3..690f5b8 100644 --- a/code/parasite/platformio.ini +++ b/code/parasite/platformio.ini @@ -13,6 +13,8 @@ platform = nordicnrf52 board = adafruit_feather_nrf52832 framework = arduino +upload_port = /dev/cu.usbserial-14330 +monitor_port = /dev/cu.usbserial-14330 ; build_flags = -DNRF52 -DS132 -DNRF51_S132 -DNRF5 ; Let's keep it simple for now and just use adafruit_feather_nrf52832. diff --git a/code/parasite/src/main.cpp b/code/parasite/src/main.cpp index 901c87e..baea4b1 100644 --- a/code/parasite/src/main.cpp +++ b/code/parasite/src/main.cpp @@ -1,10 +1,11 @@ #include - -#include "parasite/pwm.h" -#include "parasite/ble.h" - #include +#include + +#include "parasite/ble.h" +#include "parasite/pwm.h" + constexpr int kLED1Pin = 17; constexpr int kLED2Pin = 18; constexpr int kPWMPin = 19; @@ -13,16 +14,25 @@ constexpr int kDischargeEnablePin = 16; constexpr double kPWMFrequency = 500000; char manufacturer_data[] = { - 0x01, - 0x02, - 0x03, + 0x01, + 0x02, + 0x03, }; constexpr int kManufacturerDataLen = 3; +ble_gap_addr_t kGAPAddr{ + 1, + BLE_GAP_ADDR_TYPE_RANDOM_STATIC, + // This is the "reverse" order in comparison that the colon-separated + // human-readable MAC addresses. + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, +}; + void setupAdvertising() { Bluefruit.begin(1, 1); Bluefruit.setName("Parasite"); + Bluefruit.setAddr(&kGAPAddr); } void updateAdvertisingData(int moisture_level) { @@ -31,7 +41,8 @@ void updateAdvertisingData(int moisture_level) { Bluefruit.Advertising.stop(); Bluefruit.Advertising.clearData(); Bluefruit.Advertising.addName(); - Bluefruit.Advertising.addManufacturerData(manufacturer_data, kManufacturerDataLen); + Bluefruit.Advertising.addManufacturerData(manufacturer_data, + kManufacturerDataLen); Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds @@ -47,10 +58,6 @@ void setup() { analogReference(AR_VDD4); setupAdvertising(); - // Bluefruit.Advertising.start(); - - // ble.setConnectable(false); - // ble.addLocalAttribute(); } void loop() { diff --git a/hub/.esphome/parahub.yaml.json b/hub/.esphome/parahub.yaml.json new file mode 100644 index 0000000..3128bc4 --- /dev/null +++ b/hub/.esphome/parahub.yaml.json @@ -0,0 +1,22 @@ +{ + "storage_version": 1, + "name": "parahub", + "comment": null, + "esphome_version": "1.17.0-dev", + "src_version": 1, + "arduino_version": "espressif32@1.12.4", + "address": null, + "esp_platform": "ESP32", + "board": "lolin32", + "build_path": "parahub", + "firmware_bin_path": "parahub/.pioenvs/parahub/firmware.bin", + "loaded_integrations": [ + "esp32_ble_tracker", + "esphome", + "logger", + "parasite", + "ruuvi_ble", + "sensor", + "xiaomi_ble" + ] +} diff --git a/hub/.gitignore b/hub/.gitignore new file mode 100644 index 0000000..883f22c --- /dev/null +++ b/hub/.gitignore @@ -0,0 +1,3 @@ +secrets.yaml +# The platformio project that ESPHome produces. +parahub diff --git a/hub/README.md b/hub/README.md new file mode 100644 index 0000000..c531c24 --- /dev/null +++ b/hub/README.md @@ -0,0 +1,2 @@ +The hub is an [ESPHome fork](https://github.com/rbaron/esphome/). +This is the central device that listens to parasite BLE broadcasts and pipe them to MQTT. diff --git a/hub/parahub.yaml b/hub/parahub.yaml new file mode 100644 index 0000000..7fc35eb --- /dev/null +++ b/hub/parahub.yaml @@ -0,0 +1,39 @@ +esphome: + name: parahub + platform: ESP32 + board: lolin32 + + #mqtt: + # broker: raspberrypi + # username: mqttuser + # password: !secret mqtt_password + +esp32_ble_tracker: + + #switch: + # - platform: gpio + # name: "Builtin LED" + # pin: + # number: 5 + # inverted: yes + +sensor: + - platform: parasite + #mac_address: "01:02:03:04:05:06" + mac_address: "06:05:04:03:02:01" + # Doesn't matter. + humidity: + name: "Parasite humidity" + + #wifi: + # ssid: !secret wifi_ssid + # password: !secret wifi_password + + #captive_portal: + +# Enable logging +logger: + #level: VERY_VERBOSE + + #ota: + # password: !secret ota_password diff --git a/resources.md b/resources.md index e506a34..efa51d8 100644 --- a/resources.md +++ b/resources.md @@ -175,8 +175,18 @@ I'm getting ~680 when in the air; ~65 while holding the sensor. The default reso * [BLEAdvertising.h](https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/libraries/Bluefruit52Lib/src/BLEAdvertising.h#L87) * 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) +* What MAC address to use? + * Public + * Random -# Central BLE +## Packing values into the advertising packet +### Soil humidity +If there's room, I'd like to pack the raw analog-to-digital value and a percentage. +* Values for the ADC are 10 bit (0-1023). So we could use 10 bits for this. For simplicity, I'll keep this byte-aligned and use 16 bits (2 bytes) for this. It means + I'll have to scale [0, 2^10) to [0-2^16) (and back in the hub). +* Percentage values are floating points, but we don't have nearly as much precision for justifying 32/64 bits. Even using integers in [0-100] would be fine. I'll splurge and use two bytes here as well. It means I'll have to scale [0, 1.0] to [0, 2^16) and back in the hub. + +# Central BLE (hub) The "central" BLE will be responsible for listening to parasite's BLE broadcasts and parsing its manufacturer's data. One idea is to use ESPHome for this, for example like the xiaomi sensor does: * [Xiaomi component's parse_device](https://github.com/esphome/esphome/blob/dev/esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp#L19)