Software apps and online services
This is a project to create a remote, LP-WAN (LTE) powered smart alerting and monitoring gas sensor, for CO2 in this case. The more advanced sensor can detect and classify hydrocarbons like propane and natural gas.
The sensor control unit (SCU) in the CXD5602 handles monitoring, filtering and event detection. The system will automatically alert a server via LTE/HTTP POST. In my case, it parses the output into a Prometheus server for further monitoring.
You'll need a SPRESENSE with LTE board and Camera + a microSD card for the TensorFlow models trained via Edge Impulse along with local data storage for the output. If you want to connect to LTE, insert a nano SIM into the LTE board's slot; Truphone has a particularly good dashboard and data plan for $10.
The sensor I use is the Infineon XENSIV PAS CO2 sensor.
I'd recommend going with the sensor2go version as it has every pin broken out and is easy to connect to a Qwiic connector with minimum fuss.
Since this breakout was only recently made available, I made a little breakout with the required 12V step up power supply. The board is in the GitHub repo, and I fabricated it at OSHPark.
The other sensor is the Nevada Nano Flammable Gas Sensor. This is an advanced sensor that communicates over UART, which is awkward on the SPRESENSE since the main board only tolerates 1.8V, but the LTE board does not expose a level-shifted 3.3V UART.
I used a Sparkfun RP2040 board as a quick i2c-UART bridge with MicroPython to translate.Setup:
Make sure your LTE board's power jumper is set to 3.3V! If not, you won't need an ML model to detect CO2 and smoke!
Hooking up the female jumpers to SPRESENSE LTE is a little more complicated. Do this with the power DISCONNECTED!
- Connect the BLACK ground wire to any of the ground pins on the left-hand-side block underneath the micro-USB port.
- Connect the RED 3.3V wire to the 3.3V pin on the left-hand-side block
- Connect the Qwiic YELLOW wire to the pin labeled PWM2/D09/I2C1_SCL
- Connect the Qwiic BLUE wire to the pin labeled PWM2/D03/I2C1_SDA
The XENSIV CO2 breakout I made also has a convenient I2C Qwiic/Grove port, so just hook it up. If you are using the shield2go board, you may need to refer to the schematics to ensure the pins are lined up correctly. Otherwise, just use a Grove to Qwiic cable to attach it to the hub.
Either way, that's all that's needed to get the CO2 sensing working hardware-wise.
Software wise, you will have to enable the SCU, SD card, I2C1 + SCU support (turn off PWM2 and PWM3), LTE, TensorFlow and mbedTLS. See the config in the GitHub repo for details as it's comprehensive and a little complicated.
Copy over the tflite files to the root of the microSD card and insert it into the SPRESENSE LTE slot.Software
Once you've built the image, log into NSH via serial and run:
nsh>lte_sysctl -a iot.truphone.com start
This will start up LTE and the sensor monitor loop in a background task.
To test out the CO2 sensor, breathe on it. Human breath has much more CO2 than the threshold of 1000ppm.
When the SCU alerts the process, it'll take a pic with the camera and then infer whether there's a Fire, Smoke, or "Neutral" condition as well as if there's a person.
After that, it'll rearm and continue to loop in the background using one of the six app cores.
The app will send it along with the alert notification to the server. To run that independently, at the nsh prompt run:
You'll see some output with the classes and the probability in a text file on the root of the sd card. The lte_notify app will upload it to the server for record-keeping and alerting.
For example, I have it send to a Teams channel:
The code is on GitHub along with a trivial python server and the KiCad breakout schematics.
- The code uses the NuttX SDK with the Visual Studio Code SPRESENSE IDE extension
- The SPRESENSE apps are based on versions of the tflmrt, tilt sensor and lte_tls examples
- You may need to alter the SDK and TensorFlow to compile with -Os since SRAM is precious. The SPRESENSE lacks the ability to execute code from the SPI flash (XIP) or demand page via NuttX's mmap hack, so any model must be loaded into SRAM. So, your model and its memory arena must fit into the available SRAM!
- For debugging, change the TensorFlow C runtime context to use a RecordingMicroInterpreter. You'll need to add some timing-related functions as well.
- Use a MicroMutableOpResolver to reduce space even further
- Trained via Edge Impulse
- Uses some tuned topologies for MobileNetV1 to get it to fit and infer at a good accuracy
- Since they live on the SD, they can be dynamically updated. The server I use exposes a version update mechanism. The board downloads the updated model without the need for a firmware update.
Attaching the MPS sensor is more involved (and the driver is a work in progress):
Since the half-height pins on the sensor are awkward to use, there's also a KiCad breakout to link them into standard DuPont headers. Hook them up to UART (the fifth analog pin isn't used) on the RP2040 and install MicroPython.
The SparkFun board has an I2C Qwiic connector, which links to the hub.
The SPRESENSE acts as a master with the RP2040 acting as a slave translator device. The MicroPython code bridges the two in the repo -- it's not at the same level as the CO2 sensor but it can be used in the same way with a SCU driver (in progress).
The RP2040 does some minor formatting to stick the float values into a 16 bit integer. The SCU is limited to handling 16 bit integers and cannot use advanced features if the data aren't in that format.
I wouldn't test out the MPS Flammable Gas sensor unless you know what you're doing with methane, but in principle it works the same. I have mine monitoring a gas range.
There's a lot to do to make this even better. Both gas sensors have secondary temperature and humidity sensors. Setting the SCU to monitor all of them is the next step along with including them in the detection model.
GPS/LTE AGPS for mobile monitoring is in the works.
I don't have a 3D printer for case design unfortunately. I'm working on a PCB based "mount"