Struggling to stay alert at your desk or feeling groggy despite a good night's sleep? You might not realize it, but poor air quality could be to blame. High levels of CO2 in places like offices, classrooms, and gyms can lead to fatigue, headaches, and difficulty concentrating. In a twist of fate, during the COVID-19 pandemic, scientists uncovered a link between indoor carbon dioxide (CO₂) levels and the risk of virus transmission. It's clear that fresh air isn't just invigorating – it's essential for our well-being!
To address this issue, consider using sensors like the PAS CO2 Shield2Go. These sensors allow accurate monitoring of CO2 levels, providing insights into when to ventilate or open windows. But don't worry, our solution is a quick and simple one that's accessible for everyone.
With this warning light, you will open a window promptly in the future.
How the CO2 Traffic Light WorksThe CO2 Traffic Light device monitors indoor CO2 levels and provides visual feedback. This project relies on the PAS CO2 Shield2Go for accurate CO2 concentration measurement.
The relationship between CO2 concentration and air quality allows us to establish reference thresholds in our case based on The Hygienic guide values for indoor air. Our CO2 monitor interprets these different alert levels using a simple color code. A simple change of color could look like this:
Below we show the correlation between the CO2 level and air quality and the colors used to represent them.
- below 1000 ppm : Recommended for interior spaces in society.
- 1000 ppm to 1800 ppm: Space must be ventilated!
- 1800 ppm to 2800 ppm: High CO2 levels; immediate ventilation required.
- 2800 ppm and above: Red alert! The space is highly polluted. The LED will flash red.
(ppm): Parts per million
How the PAS CO2 Shield2Go worksThe XENSIVTM PAS CO2 sensor utilizes photoacoustic spectroscopy (PAS) to measure CO2 concentration.
Pulses of light from an infrared source pass through an optical filter tuned to the CO2 absorption wavelength (λ = 4.2 µm). CO2 molecules in the measurement chamber absorb the filtered light, generating pressure waves. This CO2 sensor is easy to use and provides highly accurate readings.
You can find more details about PAS CO2 sensor in this article.
Connections and Assembling1) Before we begin connecting the components, let's make a few custom adjustments to our IoT adapter. First, we'll disable the level shifters using a simple jumper. Then, we'll bridge the SDA/SCL connections and the jumper labeled "2." That sounds complicated, but simply solder the bridges together as shown in the pictures below. These quick tweaks ensure that our IoT adapter integrates smoothly into the system and works like a charm. The left side shows the "before, " and the right side shows the "after"!
2) To be able to click together the components, we need to solder the pin headers onto the IoT adapter. Additionally, soldering pin sockets onto the XMC1100 and pin headers onto the PAS CO2 Shield2Go will be necessary. These soldering tasks make it easier afterwards.
3) Solder LED ring connector to pins „5V“ (red), „GND“ (black) and „INT/GPIO3“ (green).
4) Simply stack the CO2 sensor up onto a MY IOT adapter (feel free to check it out here). Use the My IOT adapter on top of XMC1100.
NOTE: when using the MYIOT adapter make sure to use it on a microcontroller with a reference voltage of 5V, since we need it for the operation of our PAS CO2 Sensor.
5) Now 3D print the parts of our housing to complete the build. The CAD files are attached bellow.
Here you can find a short video on how to assemble the all components together. But you can certainly skip the pictures below and assemble your own case according to plan.
If you're not familiar with XMC-for-Arduino and how to set up an XMC Board to work with the Arduino IDE, check out this article !
Make sure that the required libraries for CO2 sensor and the LED's are installed :
- pas-co2-ino.hpp
- Adafruit_NeoPixel.h
Once the libraries are installed and the XMC microcontroller is connected to your laptop you are ready to code!
/* ### CO2 Sensor ### */
/* Set parameters of CO2 sensor (copied from library example) */
#define CO2_I2C_FREQ_HZ 400000
#define CO2_DEMO_MEAS_INTERVAL_IN_SECONDS 10 /* demo-mode value; not recommended for long-term measurements */
#define CO2_STABLE_MEAS_INTERVAL_IN_SECONDS 60L /* specification value for stable operation (uncomment for long-time-measurements) */
#define CO2_SWITCH_OP_MODE_AFTER_SEC 180L
uint32_t co2_meas_interval = CO2_DEMO_MEAS_INTERVAL_IN_SECONDS; /* Start measure interval in demo mode. */
In the beginning you need to set some parameters for the CO2 sensor.
/* Prepare CO2 sensor library */
PASCO2Ino cotwo;
int16_t co2ppm;
Error_t ret;
Next we initialize the CO2 sensor library, creating an instance of the PASCO2Ino class. Additionally, we have to declare a a 16 bit integer to store CO2 concentration readings and create an error type variable to monitor if our sensor is working properly.
/* ### Smart LEDs ### */
/* Set parameters of smart LEDs */
#define LED_PIN 3
#define LED_MAX_BRIGHTNESS 255
#define LED_COUNT 8
/* Prepare smart LED library */
Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
This code snippet above sets the parameters and prepares the smart LED library for controlling the LEDs.
void setup() {
/* Initialize serial interface, so measurement values can be printed to PC when connected. */
Serial.begin(9600);
delay(500);
Serial.println("Serial initialized");
/* Initialize the i2c interface used by the CO2 sensor */
Wire.begin();
Wire.setClock(CO2_I2C_FREQ_HZ);
/* Initialize the CO2 sensor */
ret = cotwo.begin();
/* Error handling (in case of init error). */
if (ret != XENSIV_PASCO2_OK) {
Serial.print("initialization error: ");
Serial.println(ret);
}
/* Initialize the smart LEDs and set to dim white*/
leds.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
leds.setBrightness(LED_MAX_BRIGHTNESS);
setLEDColor(leds.Color(50, 50, 50));
}
In the setup function, the code sets up the I2C interface for the CO2 sensor, initializes the CO2 sensor, handles any initialization errors, and also initializes the smart LEDs, setting them to dim white.
/* Trigger a measurement */
ret = cotwo.startMeasure();
/* Error handling (in case of measurement error). */
if (ret != XENSIV_PASCO2_OK) {
Serial.print("error: ");
Serial.println(ret);
setLEDColor(leds.Color(50, 50, 50));
}
/*
* Wait for the specified delay time.
* This ensures:
* - stable operation (>=60s measure interval during continues operation)
* - readyness of the measurement when we recall it
*/
delay(co2_meas_interval * 1000);
ret = cotwo.getCO2(co2ppm);
/* Error handling (in case of measurement error). */
if (ret != XENSIV_PASCO2_OK) {
Serial.print("error: ");
Serial.println(ret);
setLEDColor(leds.Color(50, 50, 50));
}
/* Print measurement result to serial interface (PC)... */
Serial.print("CO2 measurement: ");
Serial.print(co2ppm);
Serial.println(" ppm");
In the loop, the code initiates a CO2 measurement using the cotwo.startMeasure() method and checks for any measurement errors. It introduces a delay to ensure stable operation and readiness for the subsequent measurement retrieval. Following this delay, the code retrieves the CO2 measurement using cotwo.getCO2(co2ppm) and performs error handling, setting the LED color based on any encountered errors. Finally, the measurement result is printed to the serial interface, displaying the CO2 concentration in parts per million (ppm).
/* Helper function for setting LED ring color */
void setLEDColor(uint32_t color) {
leds.fill(color);
leds.show();
}
To make things easier we define a helper function in the beginning setLEDColor. Which is responsible for setting the color of the LED ring to the specified value and updating the display to reflect the new color.
/* ...and set LED color according to CO2 limit. */
if (co2ppm == 0) {
// 0 ppm / No value: WHITE
setLEDColor(leds.Color(50, 50, 50));
} else if (co2ppm < 1000) {
// Under 1000 ppm: GREEN
setLEDColor(leds.Color(0, 180, 0));
} else if (co2ppm < 1800) {
// 1000-1799 ppm: YELLOW
setLEDColor(leds.Color(200, 200, 0));
} else if (co2ppm < 2800) {
// 1800-2799 ppm: RED
setLEDColor(leds.Color(255, 0, 0));
} else {
// More than 2800 ppm: RED and flashing
for (uint8_t i = 0; i < 10; i++) {
setLEDColor(leds.Color(0, 0, 0));
delay(50);
setLEDColor(leds.Color(255, 0, 0));
delay(50);
}
}
In this code segment, the CO2 concentration is used to determine the appropriate color for the LED ring. Depending on the CO2 concentration level, the setLEDColor function is called to set the corresponding color for the LED ring, reflecting the current CO2 level. For example, if the CO2 concentration is below 1000 ppm, the LEDs will display a green color, while concentrations between 1000 and 1799 ppm will result in a yellow color. Higher concentrations trigger the display of red, with a flashing effect for concentrations exceeding 2800 ppm. This dynamic color adjustment provides a visual indication of the current CO2 level.
/* Switch from demo mode to stable operation mode after certain time */
if (millis() > 1000L * CO2_SWITCH_OP_MODE_AFTER_SEC) {
co2_meas_interval = 60;
}
Last but not least the CO2 sensor is switched from demo mode to stable operation mode after a certain time duration has passed. If the elapsed time exceeds the specified threshold, the CO2 measurement interval is adjusted to 60 seconds.
Comments
Please log in or sign up to comment.