Introduction: Plotting Carbon Dioxide Levels With the Pimoroni Enviro+ FeatherWing and Adafruit SCD-30

The Pimoroni Enviro+ FeatherWing has a wide range of sensors onboard and a connector for the optional Plantower PMS5003 particulate matter sensor. This FeatherWing board uses most of the pins on a Feather board but the i2c bus offers an easy way to add more sensors like the Sensirion SCD-30 for measuring atmospheric carbon dioxide.

In 2020, there was an increased interest in carbon dioxide levels inside buildings and enclosed spaces as it serves as a good indicator of poor ventilation, air-conditioning recirculation and over-crowding. This led to several projects:

This short article shows how to connect the Adafruit SCD-30 to an Adafruit Feather nRF52840 Express and an enhanced Pimoroni plotter program. The setup of the Enviro+ FeatherWing is covered in a previous article.

Many Adafruit boards now have a STEMMA connector or a (smaller) STEMMA QT connector. Unfortunately, the Feather nRF52840 Express board predates these connectors. A breadboard is used in this article to connect to the STEMMA QT connector on the Adafruit SCD-30.

The FeatherS2 board is a great Feather board with a STEMMA QT connector but unfortunately its ESP32-S2 microcontroller has unusual analogue to digital converters which can only measure 0V to 2.6V, rather than the full range of 0 to 3.3V. This makes it a poor choice for the Enviro+ FeatherWing as it cannot read the trio of (analogue) gas sensors properly.

Supplies

Step 1: Adding a Library and Upgrading the Plotter Program

If you are not familiar with CircuitPython then it's worth reading the Welcome to CircuitPython guide first.

If you are setting up the Enviro+ FeatherWing for the first time then follow the instructions in the Installing CircuitPython and Combined Plotter Example step of Instructables: Using the Pimoroni Enviro+ FeatherWing With the Adafruit Feather NRF52840 Express. The additional steps/differences are:

  1. Install this extra library from a bundle from https://circuitpython.org/libraries into the lib directory on the CIRCUITPY drive:
    1. adafruit_scd30.mpy
  2. Download the enhanced combined plotter example program to CIRCUITPY by clicking Save link as... on plotters_combined_with_scd30.py
  3. Rename or delete any existing code.py file on CIRCUITPY, then rename the plotters_combined_with_scd30.py to code.py. This file is run when the CircuitPython interpreter starts or reloads.

The versions used for this guide were:

  • CircuitPython 6.2.0
  • CircuitPython library bundle adafruit-circuitpython-bundle-6.x-mpy-20210413.zip
  • EnviroPlus-FeatherWing library Version 1.0
  • pimoroni_circuitpython_adapter library 9-Dec-2020 f062036

Step 2: Connecting the SCD-30

The connections from the Feather board to the STEMMA QT on the Adafruit SCD-30 are:

  • 3V - VIN (red),
  • Gnd - GND (black),
  • SCL - SCL (yellow),
  • SDA - SDA (blue).

An i2c bus needs pull-up resistors on the SDA and SCL lines. The Adafruit SCD-30 has 10k pull-ups and the Sensirion SCD-30 board has additional internal 45k pull-ups.

The Adafruit SCD-30 board has exposed pins on the underside and should not be placed on conductive surfaces. The Plantower PMS5003 particulate matter sensor without the manufacturer's protective blue plastic has a metal case making it an unwise resting place for the SCD-30.

Step 3: Testing the SCD-30

There are some easy ways to test the SCD-30:

  • Fresh outside air will read just above 400ppm.
  • Breathing over the sensor can easily cause a maximum reading of 40000ppm - the code sets the upper limit of the graph at 3000ppm.
  • A highly carbonated beverage opened and placed near the sensor will be detected, see video above.
  • Leave the sensor running overnight in an occupied bedroom to observe the increase in carbon dioxide due to expiration.

Step 4: Carbon Dioxide, Equivalent CO2 and CO2 Equivalent

There is often confusion over sensors which estimate the concentration of carbon dioxide in the air by sensing other gases as a proxy using one or more metal-oxide sensor(s). Two common, low-cost sensors are:

  • ScioSense (formerly AMS) CCS811 which uses the term equivalent CO2 (eCO2);
  • Sensirion SGP30 and SGP40 which use the term CO2 equivalent signal (CO2eq).

These are not a true measurement of carbon dioxide but are useful as an approximation if the source is from breathing (expiration). They will take into account the background level (around 415ppm in 2021) in their calculations.

Carbon dioxide can be detected and measured using spectroscopy, the characteristic absorption of certain colours of light (wavelengths of electromagnetic radiation). Sensors like the Sensirion SCD-30 use this approach and refer to it as Non-dispersive Infrared (NDIR). In hobbyist circles, these may be referred to as true carbon dioxide sensors to distinguish them from the equivalent/estimated carbon dioxide sensors.

CO2 Equivalent

Another possible source of confusion is the use of the term carbon dioxide equivalent (CO2e or CO 2eq or CO 2-e) to attempt to summarise the Global Warming Potential (GWP) of a set of gases which have different potencies as greenhouse gases and varying lifetimes in the atmosphere. The varying treatment of the lifetime parameter unfortunately means that not all carbon dioxide equivalent values are equivalent!

Carbon Monoxide (CO)

Carbon monoxide is a different, poisonous gas often associated with incomplete combustion in a confined space or broken exhaust systems.

Step 5: Pressure Compensation for the SCD-30 Sensor

The calculation of carbon dioxide in parts-per million (ppm) by the Sensirion SCD-30 involves determining how many other gas molecules are present in the sample in its chamber. This is very similar to air density calculations which involve:

  • pressure,
  • temperature and
  • humidity.

The SCD-30 includes an external Sensirion SHT31-D sensor to measure temperature and relative humidity. The pressure can be passed to the sensor in two different ways:

  • set the ambient pressure at the sensor location (altitude) or alternatively
  • set the altitude.

An accurate pressure value is the superior compensation value. If that is not known then the altitude functions as a good approximation using the assumption of International Standard Atmosphere (ISA) conditions. This will be important if you live at high altitude like Kathmandu or Denver. If you live high up in La Paz in Bolivia you'll be below the sensor's 700-1200mb range and you'll have to resort to the altitude correction!

The Enviro+ FeatherWing's BME280 sensor measures air pressure and can be used to provide pressure values to the SCD-30. The plotters_combined_with_scd30.py program does this.

Weather forecast charts show pressure levels adjusted to 0ft above mean sea level (amsl) which means these values cannot be directly used.

The NOAA Global Monitoring Laboratory presents its ppm data as if the air had 0% relative humidity:

Data are reported as a dry air mole fraction defined as the number of molecules of carbon dioxide divided by the number of all molecules in air, including CO2 itself, after water vapor has been removed.

Step 6: Going Further

There are a number of areas to explore once you've got the SCD-30 sensor working.

  • Monitor a bedroom to see how ventilation affects carbon dioxide levels overnight. The photograph at the top of the page show an overnight graph (interval of 270 seconds) peaking at 1500ppm.
  • Monitor a room which seems stuffy to observe the fluctuation over time in carbon dioxide.
  • Check/calibrate the sensor with fresh air. This is described in Adafruit Learn: Adafruit SCD-30 - Field Calibration

Related projects:

Further reading: