Skip to content

Commit

Permalink
Merge pull request #76 from rbaron/nrf-connect
Browse files Browse the repository at this point in the history
Migrate code to the nRF Connect SDK
  • Loading branch information
rbaron committed Dec 7, 2022
2 parents 427f927 + 3bf9045 commit fdf4157
Show file tree
Hide file tree
Showing 100 changed files with 6,234 additions and 13,820 deletions.
13 changes: 13 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "nrf-connect:v2.1",
"image": "nordicplayground/nrfconnect-sdk:v2.1-branch",
"features": {
},
"customizations": {
"vscode": {
"extensions": [
"nordic-semiconductor.nrf-connect"
]
}
}
}
10 changes: 1 addition & 9 deletions .github/actions/build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
FROM debian:bullseye-slim

RUN apt-get update && \
apt-get -y install wget tar unzip make clang-format gcc-arm-none-eabi

RUN cd /opt && \
wget https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5/Binaries/nRF5SDK1702d674dde.zip -O nRF5_SDK.zip && \
unzip nRF5_SDK.zip && \
mv nRF5_SDK_17.0.2_d674dde nRF5_SDK
FROM nordicplayground/nrfconnect-sdk:v2.1-branch

COPY build.sh /build.sh

Expand Down
24 changes: 23 additions & 1 deletion .github/actions/build/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
name: 'Build'
description: 'Builds b-parasite firmware'
description: 'Builds a nrf-connect sample for b-parasite'
inputs:
sample-dir:
description: 'Sample directory to build'
required: true
board:
description: 'Board definition to use'
default: bparasite_nrf52840
revision:
description: 'Board revision use'
default: '1.2.0'
cmake-extra:
description: 'Extra CMake arguments'
default: ''
output-bin:
description: 'Name of the .hex output'
required: true
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.sample-dir }}
- ${{ inputs.board }}
- ${{ inputs.revision }}
- ${{ inputs.cmake-extra }}
- ${{ inputs.output-bin }}
16 changes: 10 additions & 6 deletions .github/actions/build/build.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#!/bin/bash
set -eux -o pipefail

export SDK_ROOT=/opt/nRF5_SDK
export GNU_INSTALL_ROOT=/usr/bin/
SAMPLE_DIR=$1
BOARD=$2
REVISION=$3
CMAKE_EXTRA=$4
OUTPUT_BIN=$5

cd "$GITHUB_WORKSPACE/code/b-parasite"
make clean
make lint
make
cd "${GITHUB_WORKSPACE}/${SAMPLE_DIR}"

west build --build-dir ./build --pristine --board "${BOARD}@${REVISION}" -- $CMAKE_EXTRA

mv build/zephyr/zephyr.hex build/zephyr/"${OUTPUT_BIN}"
33 changes: 33 additions & 0 deletions .github/actions/build_and_upload/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Build and upload artifact'
description: 'Builds a nrf-connect sample for b-parasite'
inputs:
sample-dir:
description: 'Sample directory to build'
required: true
board:
description: 'Board definition to use'
required: true
revision:
description: 'Board revision use'
default: '1.2.0'
cmake-extra:
description: 'Extra CMake arguments'
default: ''
output-bin:
description: 'Name of the .hex output'
required: true

runs:
using: "composite"
steps:
- uses: ./.github/actions/build
with:
sample-dir: ${{ inputs.sample-dir }}
board: ${{ inputs.board }}
revision: ${{ inputs.revision }}
cmake-extra: ${{ inputs.cmake-extra }}
output-bin: ${{ inputs.output-bin }}
- uses: actions/upload-artifact@v3
with:
name: sample-binaries
path: code/nrf-connect/samples/ble/build/zephyr/${{ inputs.output-bin }}
63 changes: 60 additions & 3 deletions .github/workflows/b-parasite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,66 @@ on:
jobs:
build:
runs-on: ubuntu-latest
name: Checks format & builds b-parasite's firmware
name: Check format & build samples
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Build
uses: actions/checkout@v3
- name: Check clang-format
uses: jidicula/clang-format-action@v4.9.0
with:
check-path: 'code/nrf-connect'
- name: Build blinky
uses: ./.github/actions/build
with:
sample-dir: code/nrf-connect/samples/blinky
board: bparasite_nrf52840
output-bin: blinky_nrf52840.hex
- name: Build soil_read_loop
uses: ./.github/actions/build
with:
sample-dir: code/nrf-connect/samples/soil_read_loop
board: bparasite_nrf52840
output-bin: soil_read_loop_nrf52840.hex
- name: Build ble_nrf52840_1_2_0_default.hex
uses: ./.github/actions/build_and_upload
with:
sample-dir: code/nrf-connect/samples/ble
board: bparasite_nrf52840
revision: '1.2.0'
output-bin: ble_nrf52840_1_2_0_default.hex
- name: Build ble_nrf52840_1_1_0_default.hex
uses: ./.github/actions/build_and_upload
with:
sample-dir: code/nrf-connect/samples/ble
board: bparasite_nrf52840
revision: '1.1.0'
output-bin: ble_nrf52840_1_1_0_default.hex
- name: Build ble_nrf52840_1_0_0_default.hex
uses: ./.github/actions/build_and_upload
with:
sample-dir: code/nrf-connect/samples/ble
board: bparasite_nrf52840
revision: '1.0.0'
output-bin: ble_nrf52840_1_0_0_default.hex
- name: Build ble_test_nrf52840_bthomev1_1s.hex
uses: ./.github/actions/build_and_upload
with:
sample-dir: code/nrf-connect/samples/ble
board: bparasite_nrf52840
revision: '1.2.0'
cmake-extra: -DCONFIG_PRST_BLE_ENCODING_BTHOME_V1=y -DCONFIG_PRST_SLEEP_DURATION_SEC=1
output-bin: ble_test_nrf52840_bthomev1_1s.hex
- name: Build ble_test_nrf52840_bthomev2_1s.hex
uses: ./.github/actions/build_and_upload
with:
sample-dir: code/nrf-connect/samples/ble
board: bparasite_nrf52840
revision: '1.2.0'
cmake-extra: -DCONFIG_PRST_BLE_ENCODING_BTHOME_V2=y -DCONFIG_PRST_SLEEP_DURATION_SEC=1
output-bin: ble_test_nrf52840_bthomev2_1s.hex
- name: Build ble_nrf52833_default.hex
uses: ./.github/actions/build_and_upload
with:
sample-dir: code/nrf-connect/samples/ble
board: bparasite_nrf52833
output-bin: ble_nrf52833_default.hex
60 changes: 16 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,35 @@
<img src="img/resized/img1.jpg" width="512px" border="0" alt="PCB front and back photo" />
</p>

b-parasite is an open source Bluetooth Low Energy (BLE) soil moisture and ambient temperature/humidity/light sensor.
b-parasite is an open source soil moisture and ambient temperature/humidity/light sensor.

# Features
* Soil moisture sensor. I wrote about how capacitive soil moisture sensors works on [this Twitter thread](https://twitter.com/rbaron_/status/1367182806368071685), based on [this great post](https://wemakethings.net/2012/09/26/capacitance_measurement/) on wemakethings.net
* Capacitive Soil moisture sensor - see [this blog post](https://rbaron.net/blog/2021/04/05/How-capacitive-soil-moisture-sensors-work.html), [this Twitter thread](https://twitter.com/rbaron_/status/1367182806368071685), and [this post](https://wemakethings.net/2012/09/26/capacitance_measurement/) for nice resources on how they work
* Air temperature and humidity sensor using a [Sensirion's SHTC3](https://www.sensirion.com/en/environmental-sensors/humidity-sensors/digital-humidity-sensor-shtc3-our-new-standard-for-consumer-electronics/)
* Light sensor using an [ALS-PT19](https://everlighteurope.com/ambient-light-sensors/7/ALSPT19315CL177TR8.html) phototransistor
* Powered by a common CR2032 coin cell, with a battery life of possibly over a year - see "Battery Life" below
* Powered by a common CR2032 coin cell, potentially for over two years
* Support for [nRF52840](https://www.nordicsemi.com/products/nrf52840) and [nRF52833](https://www.nordicsemi.com/products/nrf52833) modules
* Open hardware and open source design

# Wiki Pages
* [Hardware Versions](https://github.com/rbaron/b-parasite/wiki/Hardware-Versions)
* [How to order: PCB fabrication and SMT assembly](https://github.com/rbaron/b-parasite/wiki/How-to-order:-PCB-fabrication-and-SMT-assembly)
* [How to Program](https://github.com/rbaron/b-parasite/wiki/How-to-Program)
# Software
This repository also hosts a few different firmware samples for b-parasite.

|Sample|Description|Extra Documentation|
|---|---|---|
|[samples/ble](./code/nrf-connect/ble)|This is the most battle-tested and useful firmware. It periodically reads all sensors and broadcast them via Bluetooth Low Energy (BLE). It works with [Home Assistant](https://www.home-assistant.io/) out of the box. |[Docs](./code/nrf-connect/ble/../../../README.md)|
|[samples/blinky](./code/nrf-connect/blinky)| The classic "Hello, world" |-|
|[samples/soil_read_loop](./code/nrf-connect/samples/soil_read_loop)| Read the soil moisture sensor on a loop. Useful for experimenting and calibrating the sensor. |-|

# Documentation
Information about how to order, assemble, build the samples, protect the sensor and flash the firmware is on [the Wiki](https://github.com/rbaron/b-parasite/wiki/How-to-Program).

# Repository Organization
* [code/b-parasite/](./code/b-parasite/) - firmware code based on the [nRF5 SDK](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fstruct_sdk%2Fstruct%2Fsdk_nrf5_latest.html&cp=7_1)
* [code/nrf-connect/](./code/nrf-connect/) - Common library and samples, built with Nordic's [nRF Connect SDK](https://www.nordicsemi.com/Products/Development-software/nrf-connect-sdk).
* [kicad/](./kicad/) - KiCad schematic, layout and fabrication files for the printed circuit board (PCB)
* [data/](data/) - data for testing and sensor calibration
* [bridge/](bridge/) - an [ESPHome](https://github.com/esphome/esphome)-based BLE-MQTT bridge
* [case/](case/) - a 3D printable case

# How It Works
<p align="center">
<img src="img/excalidraw/diagram.png" border="0" alt="Diagram containing two b-parasites, a bridge & an MQTT broker" />
</p>

b-parasite works by periodically measuring the soil moisture, air temperature/humidity and broadcasting those values via Bluetooth Low Energy (BLE) advertisement packets. After doing so, the board goes into a sleep mode until it's time for another measurement. The sleep interval is configurable - I often use 10 minutes between readings, which is a good compromise between fresh data and saving battery.

At this point, b-parasite's job is done. We have many possibilities of how to capture its BLE advertisement packet and what to do with the data. A common pattern is having a BLE-MQTT bridge that listens for these BLE broadcasts, decodes them and ships the sensor values through MQTT messages. The MQTT broker is then responsible for relaying the sensor data to interested parties. This is the topology shown in the diagram above.

## Integrations
### ESPHome
A popular choice for a BLE-MQTT bridge is the [ESPHome](https://github.com/esphome/esphome) project, which runs on our beloved [ESP32](https://www.espressif.com/en/products/socs/esp32) boards. b-parasite is officially supported and documentation for using it can be found in [the b-parasite ESPHome docs](https://esphome.io/components/sensor/b_parasite.html). An example of using this platform is also available in this repo, under [bridge/](bridge/) (check out [README.md](bridge/README.md) there for more info).

ESPHome is a battle-tested project with a vibrant community, and is currently the most mature b-parasite bridge. ESP32 are also cheap, so you can sprinkle a few of them around the house to cover a wide range, and even share the same ESP32 with other sensors.

### Home Assistant
b-parasite is supported by the [ble_monitor](https://github.com/custom-components/ble_monitor) Home Assistant custom component - please refer to the [docs](https://custom-components.github.io/ble_monitor/by_brand#rbaron). This custom component gets Home Assistant to automatically discover nearby b-parasites based on their advertisement data.

### Linux/Raspberry Pi & macOS
Another possibility is running [parasite-scanner](https://github.com/rbaron/parasite-scanner). It is a purpose-built bridge for b-parasites, and runs on Linux and macOS.

This is the quickest way to collect and visualize data from b-parasites, and I personally use it a lot for testing and debugging.

## Protocol and Data Encoding
Sensor data is transmitted via BLE advertisement broadcasts. [Here](./code/b-parasite/README.md) you can find a byte-by-byte description of the data as it is encoded inside the advertisement packet.

# Battery Life
**tl;dr:** By taking readings 10 minutes apart, the battery should last for over a couple of years.

The main parameters involved in estimating the battery life are:
* Current consumption (both in operation and during sleep)
* Duty cycle (how much time it spends in operation vs. sleeping)
* Battery capacity - this is roughly 200 mAh for CR2032 cells

Details and power comsumption measurements in the #48. [This spreadsheet](https://docs.google.com/spreadsheets/d/157JQiX20bGkTrlbvWbWRrs_WViL3MgVZffSCWRR7uAI/edit#gid=0) can be used to estimate battery life for different parameters.

<p align="center">
<img src="img/resized/img2.jpg" border="0" alt="b-parasite stuck into a small plant vase" />
</p>
Expand Down
4 changes: 4 additions & 0 deletions code/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---

BasedOnStyle: Google
ColumnLimit: 0
1 change: 0 additions & 1 deletion code/b-parasite/.gitignore

This file was deleted.

Loading

0 comments on commit fdf4157

Please sign in to comment.