A battery-powered wireless environmental sensor built around the Nordic nRF52832
and Bosch BME280. The radio link uses the nRF24L01(+)-compatible 2.4 GHz
physical layer — nRF 2 Mbps GFSK, channel 99 (2479 MHz), 5-byte address
0xE7E7E7E7E7, 16-bit CRC and no data whitening. As a result, the transmitted
packets can be received directly by:
- any nRF24L01 / nRF24L01+ module (or compatible clone) configured with the same channel, address and CRC, and
- any other nRF52832 (or nRF52-family) device running the matching RADIO
configuration (
Nrf_2Mbit, channel 99, address0xE7E7E7E7E7, 16-bit CRC).
See Radio Protocol for the exact packet layout.
- Register-level, non-blocking peripheral drivers (TWI, RADIO, SAADC, RTC, TEMP)
- Fully compensated BME280 readings using int64 arithmetic
- SAADC VDD monitoring — 12-bit, 64x oversampling, offset calibration
- nRF52 on-chip die temperature measurement
- 60-second periodic transmission interval (RTC2-driven)
- System ON idle with
__WFE()sleep between cycles; HFCLK gated off - Optional UART debug output (
-DUSE_UART, 9600 baud, P0.06) - Errata workarounds applied: PAN_028 #29, #30, #31
| Component | Detail |
|---|---|
| MCU | Nordic nRF52832 (ARM Cortex-M4F @ 64 MHz) |
| Sensor | Bosch BME280 (I²C address 0x76) |
| Radio | 2 Mbps GFSK, channel 99 (2479 MHz), +4 dBm TX |
| TX Period | 60 seconds (RTC2 CC[0] = 983 040 ticks) |
| Power | 2× AA / Li-Po, measured via SAADC VDD input |
| Signal | Pin | Notes |
|---|---|---|
| SDA | P0.26 | TWI1, 400 kHz |
| SCL | P0.27 | TWI1 |
| UART TX | P0.06 | Optional, 9600 8N1 |
The parameters below are chosen to be wire-compatible with the nRF24L01(+) modules
(no data whitening, standard 16-bit CRC, default address 0xE7E7E7E7E7), so the
same packet can also be received by another nRF52832 configured identically.
Note: this firmware accesses the RADIO peripheral directly and does not require
(or use) a Nordic SoftDevice, so the receiving nRF52 device must likewise run
bare-metal (or without an active SoftDevice) to control RADIO the same way.
10-byte payload transmitted as a single RADIO packet (2Mbit mode, 16-bit CRC):
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 1 | Length | Payload length, fixed to 10 |
| 1 | 1 | Seq ID | Rolling counter, bit 0 always set |
| 2 | 3 | Pressure | Compensated pressure, Pa (24-bit) |
| 5 | 1 | Die Temp | nRF52 junction temperature, °C ÷ 4 |
| 6 | 2 | Temp | BME280 temperature, 0.01 °C |
| 8 | 2 | Humidity | BME280 relative humidity, 0.1 %RH |
| 10 | 2 | Voltage | VDD battery, 3600 / 4095 mV per LSB |
Address field: base 0xE7E7E7E7, prefix 0xE7 (full address 0xE7E7E7E7E7).
+----------+ +----------+ +-----------+ +-----------+ +-----------+
| CLOCK |--->| TWI1 |--->| BME280 |--->|Compensate |--->| RADIO |
| HFXO/LFXO| | SDA/SCL | | 0x76 I2C | | int64_t | | ch.99 2M |
+----------+ +----------+ +-----------+ +-----------+ +-----------+
|
+-----v------+
| SAADC |
| VDD meas |
+------------+
|
+-----v------+
| TEMP |
| die temp |
+------------+
|
+-----v------+
| RTC2 |
| 60 s wake |
+------------+
- ARM GCC toolchain (
arm-none-eabi-gcc) >= 9-2020-q2-update - GNU Make
- (Optional) nRF5x command-line tools for flashing:
nrfjprog
$ make
$ make jflash # nRF52-DK / J-Link
$ make stflash # ST-LINK (ST-LINK_CLI.exe)Define USE_UART at build time to enable formatted output on P0.06 (9600 baud):
$ make CFLAGS="-DUSE_UART"| IDE | Project path |
|---|---|
| SEGGER Embedded Studio | IDE/ses/ |
| IAR EWARM | IDE/EWARM/ |
| Keil MDK-ARM (uVision) | IDE/MDK-ARM/ |
+-- main.c Application entry point and main loop
+-- Makefile GCC build system
+-- .travis.yml CI configuration
+-- LICENSE MIT License
+-- drv/
| +-- inc/ CMSIS-CORE + nRF52 register definitions
| | +-- CMSIS/ core_cm4.h, cmsis_gcc.h, cmsis_iccarm.h
| | +-- nrf.h Master MCU header selector
| | +-- nrf52.h nRF52832 peripheral struct definitions
| | +-- nrf52_bitfields.h Bit-field enumerations (SVD-generated)
| +-- src/
| +-- gcc_startup_nrf52.S Reset vector, data/BSS init
| +-- system_nrf52.c SystemInit, errata workarounds
| +-- iar_startup_nrf52.s IAR startup
+-- IDE/
+-- ses/ SEGGER Embedded Studio project
+-- EWARM/ IAR Embedded Workbench project
+-- GCC/ Linker script + Makefile templates
+-- MDK-ARM/ Keil uVision project
| Anomaly | Description | Workaround |
|---|---|---|
| PAN_028 #29 | TEMP STOP clears register | Read TEMP before TASKS_STOP |
| PAN_028 #30 | TEMP AFE not powered down | Explicit TASKS_STOP after DATARDY |
| PAN_028 #31 | TEMP offset uninitialized | Manual load to 0x4000C504 |
Distributed under the MIT License. See LICENSE for details.