CO₂ Sensor¶

Written by Grace Lo & Rachel Yan

A previous version describing the python implementation of the sensor can be found here.

The CO₂ recording procedure was developed and tested on the Sensirion SCD30 CO₂ Sensor Module for measuring carbon dioxide (CO₂) concentration, temperature, and humidity. It is a digital sensor communicating over I²C and is pre-calibrated under controlled environmental conditions. The basic CO₂ sensor functionality, intialization and reading data is borrowed from the Sensirion embedded-i2c-scd30 library. The data is provided in standard units (eg. ppm for CO₂, °C for temperature, and %RH for humidity) with specifications provided below.

Sensor Range Accuracy
CO₂ 0 - 40,000 ppm ±30 ppm + 3 %MV
Temperature 0 - 100 %RH ±3 %RH
Humidity -40 - 70 °C ±(0.4°C + 0.023 × (T [°C] – 25°C))

Pin Connections¶

Breadboarding best practices should be followed.

Pin Connections

Pin connections from the CO₂ sensor → Pico are as follows:

  • VIN → 3V3(OUT) (pin 36)
  • GND → GND
  • SCL → I2C0_SCL (pin 17)
  • SDA → I2C0_SDA (pin 16)
  • SEL → floating for selecting I2C

Code¶

All code is in the CornellFluxChamber Github repository. The code for interfacing with the CO₂ sensor is incorporated into flux_chamber.c.

Includes¶

The first lines of code in the C source file include header files. Don't forget to link these in the CMakeLists.txt file!

The following files are required to interface with the CO₂ sensor and are provided by the Sensirion embedded-i2c-scd30 library (refer to the parent library for a description about each header file).

#include <stdio.h>
#include "scd30_i2c.h"
#include "sensirion_common.h"
#include "sensirion_i2c_hal.h"

Initializations¶

The C source file initializes the CO₂ sensor's I²C Hardware Abstraction Layer (HAL) and configures the driver with the I²C address of the sensor, which sets up the communication interface between the sensor and the Pico.

int16_t error = NO_ERROR;
sensirion_i2c_hal_init();
init_driver(SCD30_I2C_ADDR_61);

Then it ensures the sensor starts in a clear and ready state by terminating all previous reading loops, sending a reset signal, and verifying the communication responsiveness of the sensor one last time, before setting up the sensor with the periodic measurement.

scd30_stop_periodic_measurement();
scd30_soft_reset();
sensirion_i2c_hal_sleep_usec(2000000);

uint8_t major = 0;
uint8_t minor = 0;
error = scd30_read_firmware_version(&major, &minor);
if (error != NO_ERROR) {
    printf("error executing read_firmware_version(): %i\n", error);
    return error;
}
printf("firmware version major: %u minor: %u\n", major, minor);

error = scd30_start_periodic_measurement(0);
if (error != NO_ERROR) {
    printf("error executing start_periodic_measurement(): %i\n", error);
    return error;
}

Read¶

The CO₂ sensor module is read using scd30_blocking_read_measurement_data(&co2,&temp, &hum) and directly written to the file.

An example of the data logging to a CSV file is provided below:

CSV File

Sensor Testing¶

The CO₂ sensor was tested by manipulating CO₂ concentrations, temperature, and humidity through a series of covering the sensor with a hand and blowing on it. Current lab testing has shown CO₂ readings ranging from approximately 300 ppm to over 6000 ppm, temperature ranging from 24-28 °C, and 45-70% relative humidity.

The example provided below shows a series of data measurements, 5 seconds apart, while altering the sensor's immediate environmental conditions.

Sensor Testing