Overview
In this project, we will interface CCS811 CO2 TVOC Sensor with ESP8266 or ESP32 and monitor the CO2/TVOC Data on Webserver. The CCS811 is a digital gas or Air Quality sensor capable of sensing a wide range of Total Volatile Organic Compounds (TVOC) & equivalent carbon dioxide (eCO2) with metal oxide (MOX) levels. The sensor can be used to determine the Air Quality Index.
Earlier, we used the sensor CCS811 sensor with Arduino to display the CO2 & TVOC value on OLED Display. But instead of OLED display, we will create our own webserver and monitor the air quality remotely from the computer or from Smartphone using any web browser. A web server is a system that runs a website or a webpage & does communication using intercommunication is done using Hypertext Transfer Protocol (HTTP). It’s a program that distributes web pages as they are requisitioned. The basic objective of the web server is to store, process & deliver web pages to the users.
The web server program for CCS811 is stored here in ESP8266 or ESP32 and delivered wirelessly when requested by some IP Address of ESP8266 or ESP32.
Bill of Materials
All the components required for this project can be easily purchased from Amazon. The components purchase link is given below.
| S.N. | Components Name | Quantity | Purchase Links |
|---|---|---|---|
| 1 | NodeMCU ESP8266 Board | 1 | Amazon | AliExpress |
| 2 | ESP32 WiFi Module | 1 | Amazon | AliExpress |
| 3 | CCS811 CO2 TVOC Sensor | 1 | Amazon | AliExpress |
| 4 | Connecting Wires | 10 | Amazon | AliExpress |
| 5 | Breadboard | 1 | Amazon | AliExpress |
CCS811 Air Quality Gas Sensor Module
The CCS811 Air Quality Sensor Breakout Board is a digital gas sensor that senses a wide range of Total Volatile Organic Compounds (TVOCs) along with equivalent carbon dioxide (eCO2) and metal oxide (MOX) levels. The sensor can be used for monitoring Indoor Air Quality. The system can be used with a microcontroller unit (MCU), which includes an Analog-to-Digital converter (ADC) & an I²C interface.
The sensor operates between 1.8V to 3.6V hence it can be used with a 3.3V pin of Arduino/ESP8266/ESP32. The default I2C address of the CCS811 is 0x5A whereas some board has an address of 0X5B. Using the CCS811 sensor we can measure eCO2 from 400 to 8192ppm & TVOC from 0 to 1187ppb. To learn more about this sensor, you can follow the CCS811 Datasheet.
Interfacing CCS811 Air Quality Gas Sensor with ESP8266/ESP32
The CCS811 Sensor works on I2C Communication protocol. So let us interface the CCS811 Sensor with ESP8266 & ESP32. In case of NodeMCU ESP8266 Board, the SCL & SDA pin are D1 & D2 respectively. So the connection digaram between CCS811 & ESP8266 is given below.
If you are using ESP32 WiFi Module, then the connection diagram is given below. The SCL & SDA pins of ESP32 are GPIO22 & GPIO21 respectively.
Do not power the sensor with 5V as the sensor can support a maximum of 3.6V only. Do not leave the WAKE pin empty as the controller won’t read the I2C Address. The WAKE pin should always be pulled down to GND.
ESP8266 CCS811 Code/Program
I used the CCS811 library from Maarten Pennings for interfacing CCS811 wiith ESP8266. The library can be downloaded from the following link.
The complete source code for ESP8266 CCS811 Webserver is given below. Before uploading the code, make sure to change your WiFi SSID & Password.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
#include <ESP8266WebServer.h> #include <Wire.h> // I2C library #include "ccs811.h" // CCS811 library // Wiring for ESP8266 NodeMCU boards: VDD to 3V3, GND to GND, SDA to D2, SCL to D1, nWAKE to D3 (or GND) CCS811 ccs811(D3); // nWAKE on D3 float val1, val2; const char* ssid = "Alexahome"; // Enter SSID here const char* password = "loranthus"; //Enter Password here ESP8266WebServer server(80); void setup() { // Enable serial Serial.begin(115200); Serial.println(""); Serial.println("setup: Starting CCS811 basic demo"); Serial.print("setup: ccs811 lib version: "); Serial.println(CCS811_VERSION); // Enable I2C Wire.begin(); // Enable CCS811 ccs811.set_i2cdelay(50); // Needed for ESP8266 because it doesn't handle I2C clock stretch correctly bool ok = ccs811.begin(); if ( !ok ) Serial.println("setup: CCS811 begin FAILED"); // Print CCS811 versions Serial.print("setup: hardware version: "); Serial.println(ccs811.hardware_version(), HEX); Serial.print("setup: bootloader version: "); Serial.println(ccs811.bootloader_version(), HEX); Serial.print("setup: application version: "); Serial.println(ccs811.application_version(), HEX); // Start measuring ok = ccs811.start(CCS811_MODE_1SEC); if ( !ok ) Serial.println("setup: CCS811 start FAILED"); Serial.println("Connecting to "); Serial.println(ssid); //connect to your local wi-fi network WiFi.begin(ssid, password); //check wi-fi is connected to wi-fi network while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected..!"); Serial.print("Got IP: "); Serial.println(WiFi.localIP()); server.on("/", handle_OnConnect); server.onNotFound(handle_NotFound); server.begin(); Serial.println("HTTP server started"); } 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 ) { val1 = eco2; val2 = etvoc; Serial.print("CCS811: "); Serial.print("eco2="); Serial.print(val1); Serial.print(" ppm "); Serial.print("etvoc="); Serial.print(val2); Serial.print(" ppb "); Serial.println(); } 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); server.handleClient(); } void handle_OnConnect() { server.send(200, "text/html", SendHTML(val1, val2)); } void handle_NotFound() { server.send(404, "text/plain", "Not found"); } String SendHTML(float val1, float val2) { String ptr = "<!DOCTYPE html> <html>\n"; ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"; ptr += "<title>Measured Air Quality</title>\n"; ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n"; ptr += "p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n"; ptr += "</style>\n"; ptr += "<script>\n"; ptr += "setInterval(loadDoc,1000);\n"; ptr += "function loadDoc() {\n"; ptr += "var xhttp = new XMLHttpRequest();\n"; ptr += "xhttp.onreadystatechange = function() {\n"; ptr += "if (this.readyState == 4 && this.status == 200) {\n"; ptr += "document.body.innerHTML =this.responseText}\n"; ptr += "};\n"; ptr += "xhttp.open(\"GET\", \"/\", true);\n"; ptr += "xhttp.send();\n"; ptr += "}\n"; ptr += "</script>\n"; ptr += "</head>\n"; ptr += "<body>\n"; ptr += "<div id=\"webpage\">\n"; ptr += "<h1>Measured Air Quality</h1>\n"; ptr += "<p>CO2: "; ptr += val1; ptr += " ppm</p>"; ptr += "<p>TVOC: "; ptr += val2; ptr += " ppb</p>"; ptr += "</div>\n"; ptr += "</body>\n"; ptr += "</html>\n"; return ptr; } |
ESP32 CCS811 Code/Program
The complete source code for Interfacing CCS811 with ESP32 is given below. You can copy the code and upload it to the ESP32 Board. But before that make sure to change your WiFi SSID & Password.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
#include <WebServer.h> #include <Wire.h> // I2C library #include "ccs811.h" // CCS811 library // Wiring for ESP8266 NodeMCU boards: VDD to 3V3, GND to GND, SDA to D2, SCL to D1, nWAKE to D3 (or GND) CCS811 ccs811(23); // nWAKE on D3 float val1, val2; const char* ssid = "Alexahome"; // Enter SSID here const char* password = "loranthus"; //Enter Password here WebServer server(80); void setup() { // Enable serial Serial.begin(115200); Serial.println(""); Serial.println("setup: Starting CCS811 basic demo"); Serial.print("setup: ccs811 lib version: "); Serial.println(CCS811_VERSION); // Enable I2C Wire.begin(); // Enable CCS811 ccs811.set_i2cdelay(50); // Needed for ESP8266 because it doesn't handle I2C clock stretch correctly bool ok = ccs811.begin(); if ( !ok ) Serial.println("setup: CCS811 begin FAILED"); // Print CCS811 versions Serial.print("setup: hardware version: "); Serial.println(ccs811.hardware_version(), HEX); Serial.print("setup: bootloader version: "); Serial.println(ccs811.bootloader_version(), HEX); Serial.print("setup: application version: "); Serial.println(ccs811.application_version(), HEX); // Start measuring ok = ccs811.start(CCS811_MODE_1SEC); if ( !ok ) Serial.println("setup: CCS811 start FAILED"); Serial.println("Connecting to "); Serial.println(ssid); //connect to your local wi-fi network WiFi.begin(ssid, password); //check wi-fi is connected to wi-fi network while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected..!"); Serial.print("Got IP: "); Serial.println(WiFi.localIP()); server.on("/", handle_OnConnect); server.onNotFound(handle_NotFound); server.begin(); Serial.println("HTTP server started"); } 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 ) { val1 = eco2; val2 = etvoc; Serial.print("CCS811: "); Serial.print("eco2="); Serial.print(val1); Serial.print(" ppm "); Serial.print("etvoc="); Serial.print(val2); Serial.print(" ppb "); Serial.println(); } 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); server.handleClient(); } void handle_OnConnect() { server.send(200, "text/html", SendHTML(val1, val2)); } void handle_NotFound() { server.send(404, "text/plain", "Not found"); } String SendHTML(float val1, float val2) { String ptr = "<!DOCTYPE html> <html>\n"; ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"; ptr += "<title>Measured Air Quality</title>\n"; ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n"; ptr += "p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n"; ptr += "</style>\n"; ptr += "<script>\n"; ptr += "setInterval(loadDoc,1000);\n"; ptr += "function loadDoc() {\n"; ptr += "var xhttp = new XMLHttpRequest();\n"; ptr += "xhttp.onreadystatechange = function() {\n"; ptr += "if (this.readyState == 4 && this.status == 200) {\n"; ptr += "document.body.innerHTML =this.responseText}\n"; ptr += "};\n"; ptr += "xhttp.open(\"GET\", \"/\", true);\n"; ptr += "xhttp.send();\n"; ptr += "}\n"; ptr += "</script>\n"; ptr += "</head>\n"; ptr += "<body>\n"; ptr += "<div id=\"webpage\">\n"; ptr += "<h1>Measured Air Quality</h1>\n"; ptr += "<p>CO2: "; ptr += val1; ptr += " ppm</p>"; ptr += "<p>TVOC: "; ptr += val2; ptr += " ppb</p>"; ptr += "</div>\n"; ptr += "</body>\n"; ptr += "</html>\n"; return ptr; } |
Testing CCS811 ESP8266/ESP32 Webserver
Once you upload the code, the ESP8266/ESP32 Board will try connecting to the WiFi Network. You can open the Serial Monitor and you will see the sensor giving the reading on Serial Monitor.
You can now press the reset button on your ESP8266/ESP32 Board. The IP Address will be displayed on Serial Monitor. Using the same IP Address, paste it on the web browser and hit enter. A beautiful webpage will come with the value of CO2 & TVOC.
You don’t need to refresh the web page again and again to retrieve the sensor value. The code already has the AJAX (Asynchronous Javascript And Xml) script so that we can request data from the server asynchronously (in the background) without refreshing the page.
So this is how you can use CCS811 CO2 TVOC Sensor with ESP8266 or ESP32.











1 Comment
how to add an old display to this project? (Monitor CCS811 CO2 & TVOC on ESP8266/ESP32 Webserver)