В этом проекте мы будем подключать датчик CO2 и TVOC CCS811 к плате NodeMCU ESP8266 или ESP32 и отслеживать данные CO2/TVOC на веб-сервере. CCS811 — это цифровой датчик газа или качества воздуха, способный определять широкий диапазон уровней общих летучих органических соединений (TVOC) и эквивалентного диоксида углерода (eCO2) с оксидами металлов (MOX). Датчик можно использовать для определения индекса качества воздуха.
Ранее мы использовали датчик CCS811 с Arduino для отображения значений CO2 и TVOC на OLED-дисплее. Но в этом проекте вместо OLED-дисплея мы создадим собственный веб-сервер и будем контролировать качество воздуха удаленно с компьютера или смартфона с помощью любого веб-браузера. Веб-сервер — это система, которая управляет веб-сайтом или веб-страницей и осуществляет связь с помощью протокола передачи гипертекста (HTTP). Это программа, которая распределяет веб-страницы по мере их поступления. Основная цель веб-сервера — хранить, обрабатывать и доставлять веб-страницы пользователям.
Программа веб-сервера для CCS811 хранится здесь, в ESP8266 или ESP32, и доставляется по беспроводной сети по запросу с некоторого IP-адреса ESP8266 или ESP32.
Необходимые компоненты
- Модуль ESP32 (купить на AliExpress).
- NodeMCU ESP8266 (купить на AliExpress).
- Датчик качества воздуха (Air Quality Sensor) CCS811 (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Модуль датчика качества воздуха CCS811
Плата датчика качества воздуха CCS811 представляет собой цифровой газовый датчик, который определяет широкий спектр общих летучих органических соединений (TVOC), а также эквивалентные уровни диоксида углерода (eCO2) и оксида металла (MOX). Датчик может использоваться для мониторинга качества воздуха в помещении. Система может использоваться с микроконтроллерным блоком (MCU), который включает в себя аналого-цифровой преобразователь (ADC) и интерфейс I²C.
Датчик работает в диапазоне от 1,8 В до 3,6 В, поэтому его можно использовать с выводом 3,3В в Arduino/ESP8266/ESP32. Адрес I2C по умолчанию для CCS811 — 0x5A, тогда как некоторые платы имеют адрес 0X5B. Используя датчик CCS811, мы можем измерять eCO2 от 400 до 8192 частей на миллион и TVOC от 0 до 1187 частей на миллиард. Чтобы узнать больше об этом датчике, вы можете ознакомиться с техническим описанием CCS811.
Схема проекта
Датчик CCS811 работает по протоколу связи I2C. Давайте подключим датчик CCS811 к платам ESP8266 и ESP32. В случае платы NodeMCU ESP8266 выводы SCL и SDA — это D1 и D2 соответственно. Таким образом, схема соединения между CCS811 и ESP8266 приведена на следующем рисунке.
Если вы используете WiFi-модуль ESP32, то схема подключения к нему датчика CCS811 приведена на следующем рисунке. Контакты SCL и SDA ESP32 — это GPIO22 и GPIO21 соответственно.
Не подавайте на датчик напряжение 5 В, так как датчик может поддерживать максимум 3,6 В. Не оставляйте вывод WAKE датчика пустым, так как контроллер не будет считывать адрес I2C. Вывод WAKE всегда должен быть подтянут к GND.
Исходный код программы для NodeMCU ESP8266
Я использовал библиотеку CCS811 от Maarten Pennings для сопряжения CCS811 с ESP8266. Библиотеку можно загрузить по следующей ссылке.
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 |
#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 с ESP32 приведен ниже. Вы можете скопировать код и загрузить его на плату ESP32. Но перед этим обязательно измените свой WiFi SSID и пароль.
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 |
#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; } |
Тестирование работы веб-сервера
После загрузки кода плата ESP8266/ESP32 попытается подключиться к сети WiFi. Вы можете открыть Serial Monitor (последовательный монитор) и увидеть в нем считанные с датчика показания.
Теперь вы можете нажать кнопку сброса на вашей плате ESP8266/ESP32. IP-адрес платы будет отображен в последовательном мониторе. Используя тот же IP-адрес, вставьте его в веб-браузер и нажмите Enter. Появится красивая веб-страница со значением CO2 и TVOC.
Вам не нужно обновлять веб-страницу снова и снова, чтобы получить значение датчика. В коде уже есть скрипт AJAX (Asynchronous Javascript And Xml), так что мы можем запрашивать данные с сервера асинхронно (в фоновом режиме) без обновления страницы.
25 просмотров