В этом проекте мы рассмотрим создание системы мониторинга загрязнения воздуха на основе Arduino, с помощью которой можно будет удаленно (через веб-сервер по интернету) осуществлять контроль состояния воздуха и включать сигнализацию когда качество воздуха падает ниже определенного уровня. Качество воздуха будет оцениваться по наличию в нем CO2, дыма, алкоголя, бензола и NH3. Качество воздуха в нашем проекте будет показываться на ЖК дисплее и передаваться на веб-сервер, что позволит получать информацию о состоянии воздуха в интересующем нас месте из любой точки мира где есть интернет. Данный проект относится к так называемой категории интернета вещей (IoT – Internet of Things).
Ранее на нашем сайте мы уже рассматривали детектор утечки природного газа на основе Arduino на датчике MQ3. Но в этом проекте мы будем использовать датчик MQ135, который является наилучшим выбором для мониторинга качества воздуха поскольку позволяет обнаруживать большинство вредных газов и измерять их количество. Вы можете установить это устройство в любом нужном месте, а сами сможете контролировать измеряемое им качество воздуха из любой точки с помощью компьютера или смартфона. Также можно реализовать информирование о состоянии воздуха с помощью отправки SMS и передачи Email.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Датчик газа MQ135 (купить на AliExpress).
- Wi-Fi модуль ESP8266 (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Резисторы 1 кОм - 3 шт. (купить на AliExpress).
- Резистор 220 Ом (купить на AliExpress).
- Зуммер (Buzzer) (купить на AliExpress).
- Макетная плата.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Работа схемы
Схема устройства представлена на следующем рисунке.
Сначала необходимо соединить модуль ESP8266 с платой Arduino. Модуль ESP8266 работает от напряжения 3.3V, поэтому если мы подадим на него 5V с платы Arduino, то мы можем повредить его. Поэтому соедините контакты VCC CH_PD модуля ESP8266 с контактом 3.3V платы Arduino. Контакт RX модуля ESP8266 также работает с напряжением 3.3V, поэтому его также нельзя напрямую подключать к плате Arduino. Поэтому мы будем использовать делитель напряжения чтобы преобразовать 5V в 3.3V. На нашей схеме это реализовано при помощи последовательного соединения 3-х резисторов. Соедините контакт TX модуля ESP8266 к контакту 10 платы Arduino, а его контакт RX – к контакту 9 платы Arduino при помощи резисторов.
Wi-Fi модуль ESP8266 обеспечивает вашему проекту доступ к Wi-Fi или интернету. Его можно подключить практически к любому микроконтроллеру. Более подробно о взаимодействии с ним можно прочитать в статье про передачу данных на веб-страницу с помощью Arduino.
Затем подсоедините контакты VCC и землю датчика MQ135 к контактам 5V и земле платы Arduino, а аналоговый контакт датчика – к контакту A0 платы Arduino.
Подсоедините зуммер (buzzer) к контакту 8 платы Arduino – он будет выдавать звуковой сигнал когда загрязнение воздуха превысит определенную норму.
Затем необходимо сделать следующие соединения платы Arduino с ЖК дисплеем:
- pin 1 (VEE) – на землю.
- pin 2 (VDD или VCC) - к 5V.
- pin 3 (V0) – на средний контакт потенциометра 10 кОм, остальные 2 контакта потенциометра – на VCC и землю (GND). Потенциометр используется для управления контрастностью ЖК дисплея. Можно также использовать потенциометр с сопротивлением 10 кОм.
- pin 4 (RS) – к контакту 12 платы Arduino.
- pin 5 (Read/Write) – на землю платы Arduino. Этот контакт ЖК дисплея используется редко, поэтому мы соединим его на землю.
- pin 6 (E) – к контакту 11 платы Arduino. Контакты RS и E – это контакты управления ЖК дисплеем.
- остальные 4 контакта данных используется для передачи данных от платы Arduino. pin 11 (D4) – к контакту 5 Arduino. pin 12 (D5) – к контакту 4 Arduino. pin 13 (D6) – контакту 3 Arduino. pin 14 (D7) – к контакту 2 Arduino.
- pin 15 - к VCC через резистор 220 Ом. Резистор используется для установки яркости черного цвета ЖК дисплея. Большее значение сопротивления сделает черный цвет более темным.
- pin 16 – на землю.
Принцип работы проекта
Датчик MQ135 может обнаруживать газы NH3, NOx, CO2, алкоголь, бензол, дым и некоторые другие. Измеряет он их в PPM (parts per million - частиц на миллион). Поэтому, можно сказать, этот датчик является идеальным решением для нашего проекта контроля загрязнения воздуха. При подсоединении к плате Arduino он будет подавать на вход Arduino напряжение определенного уровня, соответствующее количеству измеренного PPM, а в Arduino это значение напряжения нужно будет конвертировать в PPM. Для работы с датчиком MQ135 мы использовали специальную библиотеку – она будет описана далее в статье.
Датчик будет выдавать значение 90 когда рядом нет никакого газа, безопасный уровень качества воздуха находится на отметке 350 PPM и не должен превышать 1000 PPM. Когда он будет превышать 1000 PPM это может привести к появлению у человека головных болей, сонливости, вялости, чрезмерному утомлению, а если он будет превышать 2000 PPM, то он может вызвать увеличение частоты пульса и множество других заболеваний.
В нашем проекте когда качество воздуха будет меньше 1000 PPM, то на ЖК дисплее будет показываться сообщение “Fresh Air” (чистый воздух). Когда измеренное значение качества воздуха будет превышать 1000, то зуммер начнет издавать звуковой сигнал и на ЖК дисплее и на веб-странице высветится сообщение “Poor Air, Open Windows” (загрязнение воздуха, откройте окна). А если значение будет превышать 2000 PPM, то зуммер продолжит издавать звуковой сигнал и на ЖК дисплее и на веб-странице появится сообщение “Danger! Move to fresh Air” (опасность, выйдите на свежий воздух).
Объяснение работы программы
Перед началом работы необходимо откалибровать датчик газа MQ135. Если идти обычным путем, то сначала нужно сделать ряд вычислений, направленных на получение требуемого значения PPM. Эти вычисления мы рассмотрели в статье про детектор дыма на Arduino. Но в данном проекте для упрощения работы мы будем использовать специальную библиотеку для датчика MQ135, вы можете скачать ее по следующей ссылке - https://github.com/GeorgK/MQ135.
С помощью данной библиотеки вы напрямую (без всяких вычислений) можете получить значение PPM с выхода датчика, используя следующие две строки:
MQ135 gasSensor = MQ135(A0);
float air_quality = gasSensor.getPPM();
Но перед этим нужно откалибровать датчик, для этого скачайте приведенный после этого абзаца код программы, запустите его на выполнение на промежуток от 12 до 24 часов и после этого получите значение RZERO.
#include "MQ135.h"
void setup (){
Serial.begin (9600);
}
void loop() {
MQ135 gasSensor = MQ135(A0); // Attach sensor to pin A0
float rzero = gasSensor.getRZero();
Serial.println (rzero);
delay(1000);
}
После того как вы в результате выполнения этой программы получите значение RZERO, запишите его в файл скачанной библиотеки "MQ135.h": #define RZERO 494.63. (здесь нужно будет подставить свое значение RZERO).
После этого можно приступать к написанию кода для основной программы нашего проекта. Сначала необходимо подключить все библиотеки, которые мы будем использовать, и инициализировать необходимые переменные. При помощи использования библиотеки Software Serial Library (библиотеки для последовательной связи) мы можем задействовать последовательный порт на любых цифровых контактах Arduino, в данном случае у нас это будут контакты 9 (RX) и 10 (TX) – к ним мы подключили модуль ESP8266. Также необходимо подключить библиотеку для работы с ЖК дисплеем и сообщить плате Arduino, к каким ее контактам мы подключили ЖК дисплей. Также мы инициализировали две дополнительные переменные: одну для аналогового контакта датчика и вторую для хранения значения качества воздуха.
#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(9,10);
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11, 5, 4, 3, 2);
const int sensorPin= 0;
int air_quality;
После этого мы зададим режим работы для контакта 8 на вывод данных – к нему подключен зуммер. Команда lcd.begin(16,2) переведет ЖК дисплей в режим приема данных, после этого мы переведем курсор на первую строку и напечатаем сообщение ‘circuitdigest’. После этого мы переведем курсор на 2-ю строку и выведем сообщение: ‘Sensor Warming’ (датчик нагревается).
pinMode(8, OUTPUT);
lcd.begin(16,2);
lcd.setCursor (0,0);
lcd.print ("circuitdigest ");
lcd.setCursor (0,1);
lcd.print ("Sensor Warming ");
delay(1000);
Затем установим скорость (в бодах) для последовательной связи. Разные модули ESP поддерживают различные скорости передачи данных – это надо учитывать при установке скорости работы нашего последовательного порта. После этого мы установим связь с модулем ESP и покажем IP в окне монитора последовательной связи (serial monitor).
Serial.begin(115200);
esp8266.begin(115200);
sendData("AT+RST\r\n",2000,DEBUG);
sendData("AT+CWMODE=2\r\n",1000,DEBUG);
sendData("AT+CIFSR\r\n",1000,DEBUG);
sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG);
sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG);
pinMode(sensorPin, INPUT);
lcd.clear();
Для вывода сообщения на веб-страницу используем HTML программирование. Для этого мы создадим переменную с именем webpage и сохраним в ней строку, которую нам нужно будет выводить на веб-страницу. Необходимо будет вычесть 48 из выходного значения поскольку функция read() возвращает десятичное значение ASCII, а первая десятичная цифра (в нем) 0 начинается с позиции 48.
if(esp8266.available())
{
if(esp8266.find("+IPD,"))
{
delay(1000);
int connectionId = esp8266.read()-48;
String webpage = "<h1>IOT Air Pollution Monitoring System</h1>";
webpage += "<p><h2>";
webpage+= " Air Quality is ";
webpage+= air_quality;
webpage+=" PPM";
webpage += "<p>";
Далее в функции sendData мы будем передавать на веб-страницу необходимые данные и сообщения.
sendData(cipSend,1000,DEBUG);
sendData(webpage,1000,DEBUG);
cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
В следующем участке кода мы будем выводить сообщения на ЖК дисплей. Мы будем использовать несколько условий для проверки качества воздуха и в соответствии с ними выводить сообщения на ЖК дисплей и включать/выключать зуммер. Зуммер будет включаться когда уровень загрязнения воздуха будет превышать 1000 PPM.
lcd.setCursor (0, 0);
lcd.print ("Air Quality is ");
lcd.print (air_quality);
lcd.print (" PPM ");
lcd.setCursor (0,1);
if (air_quality<=1000)
{
lcd.print("Fresh Air");
digitalWrite(8, LOW);
Наконец, в следующей функции мы будем передавать и показывать данные на веб-странице. Данные, которые мы хранили в переменной (строке) под именем ‘webpage’ будут сохранены в строке под именем ‘command’. Затем модуль ESP будет последовательно, по одному символу, считывать данные из строки ‘command’ и печатать их на веб-странице.
String sendData(String command, const int timeout, boolean debug)
{
String response = "";
esp8266.print(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.print(response);
}
return response;
}
Тестирование нашего проекта
Перед тем как загружать код в Arduino, что ваш модуль ESP8266 подключен к Wi-Fi. После загрузки кода откройте окно монитора последовательной связи (serial monitor) и в нем вы должны увидеть IP адрес, к примеру, как показано на следующем рисунке.
Напечатайте этот IP адрес в строке вашего браузера и вы увидите сообщения, которые выводятся нашим устройством на эту веб-страницу. Чтобы увидеть свежие значения качества воздуха необходимо будет обновить страницу.
Исходный код программы
Для демонстрации работы проекта мы использовали локальный веб-сервер – подробно все эти процессы вы можете посмотреть в видео в конце статьи. Но чтобы мониторить качество воздуха из любой точки земного шара вы должны переадресовать порт 80 (используемый для HTTP или интернета) на локальный или частный IP адрес (192.168*) вашего устройства. После переадресации порта все входящие соединения будут переадресованы на этот локальный адрес и вы сможете открывать необходимую веб-страницу из любой точки мира просто вводя публичный IP адрес вашего интернета. Вы можете настроить переадресацию зайдя в настройки своего роутера (по адресу 192.168.1.1) и найти там опцию переадресации порта.
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 |
#include "MQ135.h" #include <SoftwareSerial.h> #define DEBUG true SoftwareSerial esp8266(9,10); // This makes pin 9 of Arduino as RX pin and pin 10 of Arduino as the TX pin const int sensorPin= 0; int air_quality; #include <LiquidCrystal.h> LiquidCrystal lcd(12,11, 5, 4, 3, 2); void setup() { pinMode(8, OUTPUT); lcd.begin(16,2); lcd.setCursor (0,0); lcd.print ("circuitdigest "); lcd.setCursor (0,1); lcd.print ("Sensor Warming "); delay(1000); Serial.begin(115200); esp8266.begin(115200); // your esp's baud rate might be different sendData("AT+RST\r\n",2000,DEBUG); // reset module sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point sendData("AT+CIFSR\r\n",1000,DEBUG); // get ip address sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG); // configure for multiple connections sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80 pinMode(sensorPin, INPUT); //Gas sensor will be an input to the arduino lcd.clear(); } void loop() { MQ135 gasSensor = MQ135(A0); float air_quality = gasSensor.getPPM(); if(esp8266.available()) // check if the esp is sending a message { if(esp8266.find("+IPD,")) { delay(1000); int connectionId = esp8266.read()-48; /* We are subtracting 48 from the output because the read() function returns the ASCII decimal value and the first decimal number which is 0 starts at 48*/ String webpage = "<h1>IOT Air Pollution Monitoring System</h1>"; webpage += "<p><h2>"; webpage+= " Air Quality is "; webpage+= air_quality; webpage+=" PPM"; webpage += "<p>"; if (air_quality<=1000) { webpage+= "Fresh Air"; } else if(air_quality<=2000 && air_quality>=1000) { webpage+= "Poor Air"; } else if (air_quality>=2000 ) { webpage+= "Danger! Move to Fresh Air"; } webpage += "</h2></p></body>"; String cipSend = "AT+CIPSEND="; cipSend += connectionId; cipSend += ","; cipSend +=webpage.length(); cipSend +="\r\n"; sendData(cipSend,1000,DEBUG); sendData(webpage,1000,DEBUG); cipSend = "AT+CIPSEND="; cipSend += connectionId; cipSend += ","; cipSend +=webpage.length(); cipSend +="\r\n"; String closeCommand = "AT+CIPCLOSE="; closeCommand+=connectionId; // append connection id closeCommand+="\r\n"; sendData(closeCommand,3000,DEBUG); } } lcd.setCursor (0, 0); lcd.print ("Air Quality is "); lcd.print (air_quality); lcd.print (" PPM "); lcd.setCursor (0,1); if (air_quality<=1000) { lcd.print("Fresh Air"); digitalWrite(8, LOW); } else if( air_quality>=1000 && air_quality<=2000 ) { lcd.print("Poor Air, Open Windows"); digitalWrite(8, HIGH ); } else if (air_quality>=2000 ) { lcd.print("Danger! Move to Fresh Air"); digitalWrite(8, HIGH); // turn the LED on } lcd.scrollDisplayLeft(); delay(1000); } String sendData(String command, const int timeout, boolean debug) { String response = ""; esp8266.print(command); // send the read character to the esp8266 long int time = millis(); while( (time+timeout) > millis()) { while(esp8266.available()) { // The esp has data so display its output to the serial window char c = esp8266.read(); // read the next character. response+=c; } } if(debug) { Serial.print(response); } return response; } |
Хотел бы узнать какой номинал у последовательных трех резисторов?
1 кОм. Внес поправки в статью.
А ошибки в коде это нормально?
Строка 22
sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG);
Команда АТ с air_quality? Не похоже на правду
Строка 24: pinmod( Тут мы ссылаемся на константу sensorpin(в коде у нас sensorpin=0 хотя должно быть А0, поскольку мы используем аналоговый вывод!, input)
Специально ошибки в коде никто не делает, но айтишники люди часто рассеянные, поэтому опечатки, к сожалению, иногда случаются
А есть принципиальная схема по этому проекту? Просто я делаю диплом по этому проекту. Хотелось бы больше информации, если так возможно? Был бы премного благодарен
Нет, схема нарисована таким образом чтобы по ней было удобно собирать проект сразу на макетной плате. Но вы же можете легко перерисовать ее в принципиальную схему.
А этим кодом прошивать arduino или сам esp модуль?
Arduino. ESP модуль используется здесь только для связи по WiFi, но управляет всей его работой плата Arduino.