Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Build your own portable, graphing CO₂ sensor



CO₂ levels measured indoors can be used as an indicator of air quality.

Outdoor air has a CO₂ ppm level of 400 ppm. Humans exhale air with 40000 ppm. You can calculate the percentage of exhaust air you are breathing by dividing measured CO₂ level above outdoor by the human exhaust level. Used air might contain aerosols which might contain the corona virus.

High indoor CO₂ levels also have an impact on the cognitive performance of humans.

Smoca AG decided to build this easy to reproduce CO₂ measuring device to help slow the spread of the corona virus in offices. It supports its users in deciding when ventilating the room begin monitored is advisable. It also raises awareness for the correlation between CO₂ level and air quality.


The following hardware is needed:

description cost link
Sensirion SCD30 54 USD
M5 Stack Core2 39.9 USD
M5 Stack Proto Board 2.95 USD
M5 Stack PLC Base 9.95 USD
M5 Stack Battery (optional) 7.95 USD

Note: The optional battery increases the battery operation time from 6 to 10 hours.


Description Image
1. Power the Core2 module. A factory test application should be loaded. Test the device.
2. Remove the bottom of the Core2 module. Keep the battery there or replace it with the optional bigger one. Front
3. Remove the PCB from the proto module.
4. Connect the SCD30 module to the proto module. We used pin headers. solder
5. Connect VDD with 3V3, GND with GND, TX/SCL with pin 5 and RX/SDA with pin 2. The other pins don't need to be connected to the proto module. scd30
5. Screw the proto module to the PLC Base
6. Screw the PLC Base to the Core2 module together
7. HW Done, load the software


To initialise the device do the following:

  1. Install Platformio IDE or PlatformIO Core to use another IDE
  2. Open the co2-sensor project folder
  3. Flash the main.cpp script to your M5 Stack Core2 with pio run -t upload --upload-port {your_device}. You can see a list of your devices with pio device list. Dependencies are installed automatically.



The SCD30 can be calibrated manually or automatically. For manual calibration, the device must be placed outdoors for at least five minutes. Then the calibration can be adjusted. Fresh air has a CO₂ concentration of about 400 ppm. To use automatic calibration, the device must have access to fresh air for at least one hour a day.


To use MQTT, synchronization and update functionality the device must have internet connection. To add WiFi credentials the device opens an access point with a web interface (Default IP is

Data sharing via MQTT

MQTT can be used to send the sensors data to a custom MQTT broker. Server, Port, Topic, Device name, Username and Password can also be configured in the web interface. Each minute the device sends its data in the following format: {TOPIC}/{CATEGORY} {VALUE}. Here an example: sensor/co2 650.
Topics are able to have subtopics: office2/meeting_room1/co2 1100.
The following categories are provided by the device: /co2, /humidity, /temperature.

Time synchronization

To keep time up to date the device synchronizes with a time server each night between two and three o'clock.

Firmware updates

Is a new firmware available, it can manually be updated via WiFi.


Using SNMP you are able to read the values of the co2, temperature and humidity sensors and also check the battery status of the device:

  1. First you have to make sure you have net-snmp installed on your system. You can do this using your package manager or by downloading it from
  2. Second you have to find out where your mib files are stored using the command net-snmp-config --default-mibdirs.
  3. Then you have to copy the mib file from /snmp-mib/sensorhub.mib into one of the listed directories. e.g. cp snmp-mib/sensorhub.mib ~/.snmp/mibs
  4. Done that, you can now use snmptable to list the sensors: snmptable -m +SENSORHUB-MIB -c public {IP-Address} shSensorTable
    Which should output the following:
    SNMP table: SENSORHUB-MIB::shSensorTable
    or to list the measurement values: snmptable -m +SENSORHUB-MIB -c public {IP-Address} shMeasurementTable
    Which should output something like this:
    SNMP table: SENSORHUB-MIB::shMeasurementTable
    shMeasurementType shMeasurementValue
                co2                  617
        temperature                  207
           humidity                  433
            voltage                  3
    electricCurrent                  276


Disclaimer This is not a safety device. Always follow the local regulations regarding corona safety. No warranty is provided Device


  • The graphs alway show the last six hours. Every line on the graph represents the measurement of one minute. The last value measured in the given minute is used for the graph.
  • To switch between different graphs (temperature / humidity / battery / co2) touch the corresponding value in the display


If a microsd card formated with fat is present, a csv file, data.txt will be written every 2 seconds with the timestamp, the co2 level, the humidity, the temperature and the current battery charge.


level color description
< 600 ppm blue outdoor air
600 - 800 ppm green fresh indoor air
800 - 1000 ppm yellow indoor air, ventilate the room if possible, small possibility of virus transmission
1000 - 1400 ppm orange used indoor air, ventilate the room, cognition is impacted, possibility of virus transmission
> 1400 ppm red heavy used indoor air, heavy cognition impact, high possiblity of virus transmission, ventilation needed.

Extended uses (no code provided)

  • We use it at our office to control a couple of exhaust / inlet pwm computer fans to keep the CO₂ level below 800 ppm.
  • We log the measurement results to a influxdb with a grafana dashboard. The grafana instance sends alerts to telegram for CO₂ levels above 800 ppm.


If you have any suggestions for the project feel free to file an issue. If you want to build the device on a bigger scale / have any other development / prototyping needs, feel free to contact us:


Copyright (c) 2020 David Gunzinger / smoca AG
Code: GPL v3
Text / Graphics / Photographs: CC BY-SA