Firmware and tools for the AirGradient PRO kit with some modifications.
The firmware is written in Rust and uses the RTIC framework.
I've modified an AirGradient PRO kit (PCB Version 3.7) mainly so I can have a wired ethernet connection.
Significant differences from stock:
- Replace the Wemos D1 Mini v4 with an stm32f411 "black pill" board
- Add a ENC28J60 Ethernet board
- Custom Rust firmware
- TCP/IP stack, comes with a lightweight broadcast protocol
- CLI with command-line tools and InfluxDB relaying, see the air-gradient-cli README
- Configuration for network and device settings
- OLED display
The build.rs file handles generating build-time configuration values based on the github repository and host environment variables.
The following environment variables can be set:
AIR_GRADIENT_IP_ADDRESS
: The deivce's IP address, default is192.168.1.38
AIR_GRADIENT_MAC_ADDRESS
: The device's MAC address, default is02:00:04:03:07:02
AIR_GRADIENT_DEVICE_ID
: An arbitrary 16-bit identifier, default is0xFFFF
(DeviceId::DEFAULT
)AIR_GRADIENT_BROADCAST_PORT
: The port number to send the broadcast protocol data on, default is32100
AIR_GRADIENT_BROADCAST_ADDRESS
: The IP address to send the broadcast protocol data to, default is255.255.255.255
Flashing the board is currently done via SWD and an st-link.
You can use the Development Artifacts github action to build a custom-configured firmware image in CI (click "Run workflow" and set the configuration fields) or grab the latest release with the default configuration from the Releases page.
- Install probe-rs-cli
cargo install probe-rs-cli
- Flash the target
probe-rs-cli run --chip STM32F411CEUx --protocol swd path/to/air-gradient-pro
- Install cargo-embed and flip-link
cargo install cargo-embed flip-link
- Build the firmware and flash the target
cargo embed --release
Log messages are available on pin PA11 (USART6 Tx), you should see output like the following:
[I] ############################################################
[I] air-gradient-pro-rs 0.1.0 (release)
[I] Build date: Fri, 07 Apr 2023 10:00:13 +0000
[I] rustc 1.68.2 (9eb3afe9e 2023-03-27)
[I] git commit: 709ce69ea2a86585e58f07684f0def66e5f79010
[I] Serial number: 303233313036517042018
[I] Device ID: 0x1 (1)
[I] IP address: 192.168.1.38
[I] MAC address: 02-00-04-03-07-02
[I] Broadcast protocol port: 32100
[I] Broadcast protocol address: 255.255.255.255
[I] ############################################################
[I] Setup: startup delay 5 seconds
[I] Setup: S8 LP
[I] Setup: PMS5003
[I] Setup: I2C2
[I] Setup: SH1106
[I] Setup: SHT31
[I] Setup: SGP41
[I] Setup: ETH
[I] Setup: TCP/IP
[I] Setup: net clock timer
[I] Setup: net poll timer
[I] >>> Initialized <<<
- STM32F411 "black pill"
- ENC28J60 Ethernet board
- AirGradient PRO V3.7 kit
- SH1106 OLED
- Sensirion SHT31 (temperature/humidity sensor)
- Senseair S8 LP (CO2 sensor)
- PMS5003 (particle concentration sensor)
- Sensirion SGP41 (TVOC/NOx sensor)
Pin | Peripheral | Board D1 Mini Header Pin | Description |
---|---|---|---|
PA11 | USART6 Tx | TX | Console/logger/panic-handler output |
PA12 | USART6 Rx | RX | Console input |
PA9 | USART1 Tx | D3 | senseAir S8 Rx |
PA10 | USART1 Rx | D4 | senseAir S8 Tx |
PA2 | USART2 Tx | D6 | PMS5003 Rx |
PA3 | USART2 Rx | D5 | PMS5003 Tx |
PB3 | I2C2 SDA | D1 | Shared I2C SCL : SH1106, SHT31, SGP41 |
PB10 | I2C2 SCL | D2 | Shared I2C SDA : SH1106, SHT31, SGP41 |
PB13 | SPI2 SCK | NC | ENC28J60 Eth SCK |
PB14 | SPI2 MISO | NC | ENC28J60 Eth MISO |
PB15 | SPI2 MOSI | NC | ENC28J60 Eth MOSI |
PB12 | GPIO Output | NC | ENC28J60 Eth CS |
PA8 | GPIO Input | NC | ENC28J60 Eth INT |
PB1 | GPIO Output | NC | ENC28J60 Eth RESET |
PC13 | GPIO Output | NC | On-board LED |