This project is the result of multiple years of effort across multiple disciplines; From smart contract development in RFID scanner for blockchain and Telos for IoT projects, website experimentation and development, to the methodical evolution of the Measurement Earth Operating System firmware that powers this device.
I built this because I enjoy the outdoors (cycling, hiking, SUP); Programming and embedded system design and IoT is what I do professionally, and blockchain just has this special allure to it - the idea of a system of perfect order, of irrefutable proof of events - I'm sure many developers out there find it similarly enticing (and no, it's not about the tokens, but tokens do add some spice). So why not bring it all together?
The OverviewThe system is comprised of solar-powered outdoor air quality (AQ) sensors measuring standard parameters such as temperature, pressure and humidity, plus something extra: particulate matter (PM). PM is one of the key metrics to consider when it comes to air quality, as it is these fine particles that have some of the most adverse affects to human health in the air we breath. PM measurements have other uses too, including smoke detection (where there's smoke there's fire).
The sensors take measurements every 15 minutes and produce a signed blockchain transaction. This transaction is delivered over a LoRaWAN network (Helium) to a public blockchain network through a bridge server that encapsulates the transaction with an API request for submission to the blockchain. The key aspect here is that the transaction is made on the device itself and cannot be subsequently modified nor altered due to the nature of blockchain cryptography. The transaction is signed by a secret key that only the device has and is linked to an account on the blockchain that is exclusive to each device. It is this feature that makes the sensors "Trusted" (no-one can pretend to be that device). The blockchain is also the database, storing the measured sensor data in the blocks themselves.
The diagram below shows the relationship between all of the components in the system.
The public blockchain platform is used for two key purposes - to ingest and authenticate the sensor data source. With dozens of access points geographically distributed around the world, regular HTTP requests can be used to access the blockchain to submit data. The blockchain authenticates the data source due to the very nature of blockchain itself - only transactions digitally signed by the data sources (the AQ sensors) can be accepted onto the chain.
The public blockchain I'm using is called Telos, based on EOSIO blockchain technology originally launched in 2018 (recently forked into something called Antelope). I chose this blockchain because of its compatibility with low-power IoT devices: standard cryptography for which small C-based libraries are available and a staking-based blockchain resource allocation model. This means that a small fee is paid once and a device can send data to the blockchain indefinitely. This feature is attractive compared to alternatives like Ethereum that require a fee (gas) per transaction (i.e. sensor measurement). Also, Telos is a proof-of-stake blockchain and therefore better for the environment than energy-intensive proof-of-work types of blockchains.
The functionality of the platform - maintaining a list of registered AQ sensor device accounts, and the collection and authentication of AQ sensor data - is implemented by smart contracts (aka dApps). The dApp I built for the AQ sensor system is registered to the airv11.meas account and hosts several actions (akin to functions) and tables (a mutable database that exists in the blockchain server's RAM state). Of most interest is the submitv1 action that is encoded by each AQ sensor in their signed blockchain transactions. It is through this action that data gets onto the chain. Once on the chain, it is permanently part of the blockchain record. There exists REST APIs that allow user applications, like my Measurement Earth website, to collect the sensor data for presentation. I also run a TestNet website that allows access to most of my active "testbed" sensors. These websites run simple handcrafted HTML and Javascript and were initially deployed to IPFS. However due to IPFS's persistently long load times I recently re-hosted the pages on GitHub pages.
The Communication NetworkUnder the hood, the Helium network differs very little from another LoRaWAN network like The Things Network (TTN). However, Helium has a much smoother onboarding process through their slick Console application, don't impose any "community" limits on data throughput beyond standard regulatory requirements, and has vastly more coverage. It is for these reasons and more that I decided to use Helium. I will make a note here that there are elements to Helium that are also considered "blockchain", however this part of Helium has nothing to do with my blockchain back-end (Telos) and the Measurement Earth platform. I'm only using Helium's radio and packet-forwarding LoRaWAN technology to get the sensor's blockchain transactions to the cloud.
Helium allows access to their network to devices whose associated account has purchased "data credits" (DC). Helium charges 1 DC per 24 bytes of user payload in each uplink (Joins included). A 1 byte payload is charged 1 DC and a 25 byte payload is charged 2 DC. Each DC is 0.00001 USD.
One important thing to note here - the blockchain transactions generated by the AQ devices are relatively large - about 195 bytes including all sensor and metadata plus transaction signature. This fits into only the fastest LoRa mode - spreading factor 7. This means I lose a bit of range, but this is where Helium shines again - with such dense deployment coverage the sensor is always within range of a few gateways (even at SF7) in an urban environment. Helium charges me 9 DC per uplink: 0.00009 USD. Per day ( 0.00864 USD) and per device it costs me not quite 1 cent. Not bad! Honestly, Helium should increase this 10x and distribute more rewards this way to the miners to offset the lower value of HNT.
The BridgeThe last piece of the communications path is to connect the Helium network to the Telos blockchain. Unfortunately there is no built-in way to do this. Even the generic HTTP endpoint integration is not compatible with the Telos blockchain access points. To work around this I partnered with KandaWeather (now AscensionWx) to use their existing MQTT-based Helium to Blockchain binding app server, with some modifications, to complete the "last mile" between the AQ sensors, Helium, and the blockchain itself.
The HardwareThe AQ devices use STM32 MCUs at their core and LoRa radios to communicate with Helium, plus adds the BME280 for pressure (and secondary temp and humidity measurements), SHT35 for high-accuracy temp and humidity, Sensirion SPS30 for PM measurements, LIS3DH accelerometer for device orientation (and possible movement detection) and an AIR530Z for GPS-based location and time. The power management system is comprised of some Adafruit boards: a solar charger and a +5V DC boost for the PM sensor, a 1 W solar panel, and a 1000 mAh LiPo to soak up and release the solar power as needed to the rest of the components. In this configuration, the power management system is able to replace the energy lost overnight in about an hour in early September Canadian prairie sun. A smaller solar panel and battery could work just as well in more southernly climates.
My latest iteration of the AQ sensor device - the V2 devices - uses the SeeedStudio LORA-E5-MINI board (aka WIO-E5-MINI) that features the STM32WLE5 SoC. This is an STM32L4 device that integrates the Semtech SX1262 LoRa radio on the same die while offering more than enough SRAM and flash to host the firmware with Helium and EOSIO transaction generation & signing, along with my STM32 Secure Patching Bootloader to securely manage firmware updates in the field (from the UART port). Firmware update over Helium is theoretically possible thanks to the patching feature of my bootloader and firmware update system, but I have not had occasion to implement the OTA protocol for that.
The firmware running on the blockchain AQ sensor devices is a custom-designed solution I call Measurement Earth OS (or ME-OS). It includes the LoRaMac-node stack from GitHub for the capability to join to and utilize the Helium network. ME-OS features a relatively simple co-operative process event-driven scheduler which I prefer to use over more complex pre-emptive schedulers in OSs like FreeRTOS for two big reasons: shared stack for all processes means greatly reduced SRAM requirement, and shared process context means not having to deal with the complexities and pitfalls of mutual exclusion and data sharing.
With ME-OS, the MCU is asleep (STOP mode) unless there is an event posted to the event queue to process. Most events are timer-related from the RTC. User I/O through the UART is run through DMA with queues so that there is little impact to program execution when printing output (formatted strings are queued internally and drained by the DMA to the UART). Sensors are triggered and polled independently according to sensor driver logic that uses timers to check for results. The SPS30 is a more complex sensor and I poll it once a second for a minimum of 8 seconds and a maximum of 30 seconds or until the returned results stabilize (same across two measurements). This process occurs in parallel with everything else, like polling the BME280, or parsing GPS NMEA messages.
ME-OS also features a linux-like command line interface for configuration and control. It features familiar commands like cd, cat, find, ls, uname, and directory structures like /dev /sys /usr. Sensors can be read on-demand with commands like cat /dev/temp. The LoRaWAN module can be configured with the lorawan command. Configuration is stored persistently in a journaling record-storing system using just 2 sectors on the STM32WLE5 internal flash. All commands have a --help option. There is an extensive logging system and all activities will be accompanied by one or more log messages to the console. In the below example, a LoRaWAN uplink was automatically performed while I was grabbing output for this writeup.
Some examples below from the a11111c.meas AQ sensor device.
/$ ls
d--- bin
d--- data
d--- dev
d--- sys
d--- usr
d--- var
OK
/$ find
./bin
./bin/cat
./bin/cd
./bin/date
./bin/eos
./bin/find
./bin/led
./bin/log
./bin/lorawan
./bin/ls
./bin/nvm
./bin/ps
./bin/reboot
./bin/sense
./bin/stats
./bin/tsp
./bin/uname
./bin/uptime
./bin/wsn
./data
./dev
./dev/adc
./dev/chum
./dev/ctemp
./dev/hum
./dev/loc
./dev/motion
./dev/pm
./dev/pres
./dev/temp
./sys
./sys/clk
./sys/stream
./sys/timer
./usr
./usr/opt
./var
./var/log
OK
/$ uname -a
ME-OS ME-TSP-AIR v1.2.0-rc3-10-gd016d67-dirty GreenField 1.2.10_154288_8b7c54d137a48e4262b2b9815cab7f939e01a1196594b9bfb189aaf1d544e849 STM32WL LORA-E5-DEV 1050304e49317820
OK
/$ date
current time: 1662511145 Wed Sep 7 00:39:05 2022 UTC (LORAWAN)
OK
/$ cd dev
OK
/dev$ cat ctemp
SHT3X temp+hum sensor:
data period ms: 900000
trigger mode : TIMER
sample limit : 0
output mode : RAW
decimation : 0
heater:OFF reset:DETECTED cmd:OK chksum:OK
[07 00:40:01.114] [WARN: SENSE ] packet already acquired
[07 00:40:01.114] [INFO: SENSE ] Polling sensors 0040 @ 1662511201.114
OK
/dev$ [07 00:40:01.138] [INFO: SENSE ] Sensor poll complete: 0040->0040
ctemp: 22.32 C
[07 00:40:05.003] [WARN: EOSLRWAN ] TAPOS timer, resending
[07 00:40:05.003] [INFO: EOSLRWAN ] Sending TAPOS request to port 10
[07 00:40:05.003] [INFO: LORAWAN ] Put tx packet len:1
[07 00:40:05.003] [INFO: EOSLRWAN ] Start timer for : 300000 ms
[07 00:40:05.003] [INFO: LORAWAN ] Tx new packet
[07 00:40:05.008] [INFO: LORAMAC ] TX on freq 904100000 Hz at DR 3 pwr 20 dBm
[07 00:40:05.019] [INFO: LORAWAN ] Tx accepted
[07 00:40:05.066] [INFO: LORAMAC ] MAC txDone
[07 00:40:06.040] [INFO: LORAMAC ] RX_1 on freq 923900000 Hz at DR 13
[07 00:40:06.091] [INFO: RADIO ] IRQ_RX_TX_TIMEOUT
[07 00:40:06.091] [INFO: LORAMAC ] MAC rxTimeOut
[07 00:40:07.056] [INFO: LORAMAC ] RX_2 on freq 923300000 Hz at DR 8
[07 00:40:07.132] [INFO: RADIO ] IRQ_RX_TX_TIMEOUT
[07 00:40:07.132] [INFO: LORAMAC ] MAC rxTimeOut
[07 00:40:07.135] [INFO: LORAWAN ] MCPS-Confirm U/L FRAME: 447 | PORT:10 | DR:3 | PWR:5 UNCONFIRMED
[07 00:40:10.135] [INFO: LORAWAN ] Finish tx status=0 resp=unconfirmed No rx data.
[07 00:40:10.135] [WARN: EOSLRWAN ] Unhandled downlink port 0
[07 00:40:10.135] [INFO: LORAWAN ] Tx released.
lorawan --help
lorawan : Interface with lorawan module
start Start lorawan process
config Get / set lorawan configuration [deveui <hexstr:16>][appeui <hexstr:16>][appkey <hexstr:32>][adr 0..1][dr 0..15][pwr 0..15]
devinfo Show device information
send send binary data: <port 1..255> <conf 0..1> <hexpair><hexpair>... 3 0 A30C
query Query if TX possible for given app payload size : <payload size>
commit Request to commit settings to NVM
stop Stop the lorawan process
OK
/dev$ nvm info
[media base:0803F000 sector:00000800 size:00001000]
types:14 data size:760 smallest:24 largest:64 chunk:00000800 next:0803F6F0 last:0803F6D8
capacity:2048 size on disk:3784 free space:-1736
OK
/dev$ eos ident
a11111c.meas active airv11.meas telos_testnet
OK
Total BOM cost for the AQ sensor device is about $250 USD.
The AssemblyThis project is listed as "Advanced" with 8 hr assembly time. These apply assuming one has all parts (including ME-OS-MINI-TSP: the SeeedStudio Wio-E5-Mini with ME-OS and secure identity pre-loaded) in hand and is re-using the Measurement Earth dApp. With that assumption, it is possible to prepare the enclosure and wire it all up in maybe a day.
Important points:
- A 1" hole is drilled into the bottom of the enclosure for air to enter.
- Components are attached to the enclosure with Adafruit double-sided sticky pads.
- All sensors are wired on same I2C bus; GPS on UART.
- Power is input to the SeeedStudio Wio-E5 "BAT" input and run through the onboard 3.3V LDO. This allows input from LiPo/Charger (at up to ~4.2 V) at full charge and works down to about 3V (LDO follows input below 3.3V) limited by the MCU and sensor operating voltages (around 3V).
- AIR530Z has separate shutdown signal wired up.
- Can add a switch on the LiPo (+) wire to allow for current measurement from the battery.
- Remove the LEDs from the Adafruit Solar Charger and the 5V Boost! These draw lots of current and will cut battery time down significantly.
If anyone has something to add in terms of alternative components or techniques, please share! I'm always on the lookout for ways to get the cost of the AQ sensor down.
Comments