Zero Axis Technologies
Both sides of the cellular gas sensor's two populated circuit boards, showing the cellular module and SIM card slot, antenna, and a LiPo battery with its IMEI label

Building a cellular air-quality sensor that provisions and encrypts itself

Challenge

A team needed firmware for a standalone, battery-powered air-quality sensor that connects directly over cellular - no Wi-Fi, no gateway, no phone pairing - and streams live sensor data to AWS IoT at fleet scale, meaning every unit had to onboard itself with its own unique cloud credentials straight off the factory line. The sensor payload itself also needed to stay private end to end, not just protected by the transport connection, since the data crosses a cloud account the device team doesn't fully control downstream.

Solution

We built the firmware in C++ on Nordic's nRF9160/nRF9161 cellular SiP (LTE-M/NB-IoT) on Zephyr and the nRF Connect SDK, reading a CO2 sensor (Sensirion SCD41), a VOC/NOx gas sensor (SGP41, processed through Sensirion's VOC Index algorithm), and precision temperature (TMP117) and humidity (SHT41) sensors over I2C, with a TI BQ25180 nano-power charger managing the battery and the modem's own cell-tower operator ID and signal strength read out for coarse connectivity diagnostics without needing a GPS chip. Every unit ships with only a shared "claim" certificate restricted to a single provisioning topic; on first boot it publishes its unique hardware ID and waits, and a Lambda function on the backend issues that unit its own permanent X.509 certificate and private key through AWS IoT fleet provisioning - split across two separate sub-2KB MQTT messages specifically because the nRF9160 modem's internal TLS buffer can't handle AWS's full certificate-creation response in one frame. The device writes its new permanent credentials to internal flash behind a magic-word verification check, reboots, and reconnects under its own identity from then on, with a runtime IoT policy scoped only to that device's own topics. On top of that already-TLS-secured connection, we added a second, independent encryption layer for the sensor data itself: on first connection, the device and a dashboard backend perform an X25519 elliptic-curve key exchange over MQTT, derive a shared key, and from then on every telemetry payload is ChaCha20-Poly1305 ciphertext - so the sensor readings stay unreadable to anything sitting between the device and the one dashboard holding the matching private key, not just protected in transit. Telemetry publishes every 8 seconds with a 2-minute heartbeat carrying the running firmware version, every reading is also appended to a local SD card CSV log as an offline backup, and separate RTOS threads handle sensor sampling, modem/MQTT connection management, SD logging, and status LEDs independently, so a stalled cellular reconnect never blocks sensor sampling or local logging.

Results

The result is a gas-sensor fleet that provisions itself: a factory-flashed claim identity is all a unit needs to receive its own permanent, uniquely scoped AWS IoT certificate the first time it powers on and gets signal, with no manual credential flashing per device. Sensor data is protected twice over - once by the MQTT connection's TLS, and again by an application-layer ChaCha20-Poly1305 payload that only the paired dashboard can decrypt - and the local SD card log means a dead cellular connection or a cloud outage never costs the unit its data.

Contact Us

Kick-start your project

Get in touch with our team to discuss your business needs and see how we can help with a project like this one.