How to monitor air quality CO2 using ESP32 and CCS811

This tutorial covers how to monitor indoor air quality using ESP32 and CCS811. In more detail, we want to monitor the air quality using two parameters:

  • eCO2 = equivalent Carbon dioxide
  • tVoC = total volatile organic compounds

We will measure them using the CCS811 sensor with the ESP32. Moreover, we will show the result using a color LCD display based on ST7755. This is an interesting project because it demonstrated how easy is to build a monitoring system.

Brief introduction to CCS811

The CCS811 sensor is a gas sensor that is able to detect several compounds in the air. It can measure the equivalent CO2 present in the air and the total volatile organic compounds named VOCs. These are a class of compounds that are considered pollutants and sensory irritants. They are produced by a variety of sources including people’s breath. Therefore, we can use the CCS811 with the ESP32 to monitor the air quality. Remember that before using this sensor you should run it for 48 hours and wait at least 20 minutes when you use the sensor.

How to connect the CCS811 to the ESP32 to monitor the air quality

Before using the CCS811 sensor, it is important to know how to connect it to the ESP32. The table below shows the connections:

ESP32 PinsCCS811 Pins
GNDGND
3V3Vcc
GPIO21SDA
GPIO22CLK
WakeGND

This device uses a I2C interface.

There are several libraries you can use to read values from CCS811. Anyway, this project uses this library. Now we can monitor the air quality using the ESP32 and CCS811 sensor.

Connecting the RGB display ST7735s to the ESP32

As said before, to display the readings from the CCS811, we use an LCD TFT display based on ST7735s. This device uses an SPI interface. The table below shows how to connect the ST7735s to the ESP32:

ESP32 PinTFT LCD ST7735
GNDGND
3V3Vcc
GPIO5CS
GPIO18RST
GPIO2RS
GPIO23SDA
GPIO18CLK

To mange this device, this project uses the Adafruit Library.

More interesting resources:
How to use Tensorflow with ESP32
How to use Websocket with ESP32 to control pins
ESP32 with ESP-Now protocol
How to use ESP32-CAM with TFT display

Project source code with PlatformIO

This code can be used to monitor the quality air using CCS811 and ESP32 and to display the sensor reading to a TFT LCD based on ST7735s:

#include <Arduino.h> #include <Wire.h> // I2C library #include "ccs811.h" // CCS811 library #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library for ST7735 #include <SPI.h> #define TFT_SCLK 18 // SPI clock #define TFT_MOSI 23 #define TFT_CS 5 #define TFT_RST 4 #define TFT_DC 2 CCS811 ccs811(-1); //Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); void setup() { // Enable serial Serial.begin(9600); Serial.println(""); // Enable I2C Wire.begin(); // Enable CCS811 ccs811.set_i2cdelay(50); bool ok= ccs811.begin(); if( !ok ) Serial.println("setup: CCS811 begin FAILED"); // Start measuring ok= ccs811.start(CCS811_MODE_1SEC); if( !ok ) Serial.println("setup: CCS811 start FAILED"); tft.initR(INITR_BLACKTAB); } void displayValue(uint16_t eco2, uint16_t etvoc) { tft.fillScreen(ST77XX_BLACK); tft.setTextColor(ST77XX_GREEN); tft.setTextSize(2); tft.setCursor(1,15); tft.print("CO2 " + String(eco2) + "ppm"); tft.setCursor(1,40); tft.setTextColor(ST77XX_YELLOW); tft.setTextSize(2); tft.print("etVOC " + String(etvoc) + "ppb"); } void loop() { // Read uint16_t eco2, etvoc, errstat, raw; ccs811.read(&eco2,&etvoc,&errstat,&raw); // Print measurement results based on status if( errstat==CCS811_ERRSTAT_OK ) { displayValue(eco2, etvoc); } else if( errstat==CCS811_ERRSTAT_OK_NODATA ) { Serial.println("CCS811: waiting for (new) data"); } else if( errstat & CCS811_ERRSTAT_I2CFAIL ) { Serial.println("CCS811: I2C error"); } else { Serial.print("CCS811: errstat="); Serial.print(errstat,HEX); Serial.print("="); Serial.println( ccs811.errstat_str(errstat) ); } // Wait delay(1000); }
Code language: C++ (cpp)

while the platformio.ini file should be like:

[env:esp32dev] platform = espressif32 board = esp32dev framework = arduino upload_port = /dev/tty.SLAB_USBtoUART lib_deps = # RECOMMENDED # Accept new functionality in a backwards compatible manner and patches adafruit/Adafruit GFX Library @ ^1.10.5 adafruit/Adafruit ST7735 and ST7789 Library @ ^1.6.0 adafruit/Adafruit BusIO @ ^1.7.2
Code language: PHP (php)

How to read CO2 and tVoc using CCS811

This a brief explanation of the code above. The first thing is initiliazing the class that will handle the sensor:

CCS811 ccs811(-1);

Next, the code connect the ESP32 to th CCS811 sensor in the setup() method:

// Enable CCS811 ccs811.set_i2cdelay(50); bool ok= ccs811.begin(); if( !ok ) Serial.println("setup: CCS811 begin FAILED");
Code language: JavaScript (javascript)

and finally, it selects how often the sensor reads the data:

// Start measuring ok= ccs811.start(CCS811_MODE_1SEC); if( !ok ) Serial.println("setup: CCS811 start FAILED");
Code language: JavaScript (javascript)

while in the loop() method, we read the CO2 and tVOC values:

uint16_t eco2, etvoc, errstat, raw; ccs811.read(&eco2,&etvoc,&errstat,&raw);
Code language: CSS (css)

How to display the CO2 and tVoC using TFT LCD display ST7735

In this last step, we will visualize the CO2 and tVOC values using a TFT LCD display. To handle this display, the code uses the Adafruit library. Therefore, the code defines the pins used and the class that handles the display:

#define TFT_SCLK 18 // SPI clock #define TFT_MOSI 23 #define TFT_CS 5 #define TFT_RST 4 #define TFT_DC 2 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
Code language: PHP (php)

next, in the setup() method the code initializes the display:

tft.initR(INITR_BLACKTAB);
Code language: CSS (css)

Finally, using this piece of code, we visualize the results:

void displayValue(uint16_t eco2, uint16_t etvoc) { tft.fillScreen(ST77XX_BLACK); tft.setTextColor(ST77XX_GREEN); tft.setTextSize(2); tft.setCursor(1,15); tft.print("CO2 " + String(eco2) + "ppm"); tft.setCursor(1,40); tft.setTextColor(ST77XX_YELLOW); tft.setTextSize(2); tft.print("etVOC " + String(etvoc) + "ppb"); }
Code language: C++ (cpp)

Below the final result:

ESP32 Air quality monitor using CCS811

Wrapping up

At the end of this post, we have covered how to monitor the air quality in your room using the ESP32 and a CCS811 sensor. Using this sensor, we measure the CO2 e tVOC values and we can recognize if this values are over the thresholds.