В этом проекте Интернета вещей (IoT) мы разработаем систему мониторинга частиц PM1.0, PM2.5 и PM10 на основе платы ESP32 и датчика PMS5003 вместе с автоматической системой освежения воздуха. Устройство может контролировать и измерять концентрацию PM1.0, PM2.5 и PM10 в воздухе. Оно также может активировать освежитель воздуха, когда уровень PM превышает опасное значение. Устройство можно использовать дома, на производстве, в школах, офисах и в местах массового скопления людей.
Твердые частицы (Particulate Matter, PM) относятся к микроскопическим частицам твердого или жидкого вещества, взвешенным в воздухе. PM — это твердые частицы, а 10 и 2,5 — это значение их диаметра: 10 микрометров или меньше и 2,5 микрометра или меньше. Твердые частицы являются наиболее вредной формой загрязнения воздуха. PM2.5 и PM10 обладают способностью проникать глубоко в легкие, кровеносные сосуды и мозг, вызывая проблемы со здоровьем, включая сердечные приступы, респираторные заболевания и преждевременную смерть.
Итак, в данной статье мы рассмотрим создание систему на основе Интернета вещей, использующую модуль ESP32 и датчик твердых частиц PM2.5 и PM10 PMS5003. Устройство может быть встроено в небольшую печатную плату. При включении устройство начинает измерять концентрацию твердых частиц в воздухе и отображает их значение в реальном времени на 0,96-дюймовом OLED-дисплее. ESP32 также подключается к сети WiFi и загружает данные на веб-сервер . Используя локальный IP-адрес ESP32, вы можете получить значение PM1.0, PM2.5 и PM10 в любом веб-браузере. Веб-страница не нуждается в обновлении, поскольку код Ajax уже встроен в код нашей программы.
Значение индекса качества воздуха (AQI) выше 50 является вредным для дыхания. Поэтому, когда уровень загрязнения воздуха превышает норму, вентилятор будет автоматически включаться для подачи свежего воздуха. Вместо вентилятора вы можете использовать любое другое устройство для освежения воздуха, например, увлажнитель, подключенный к реле.
Ранее датчик PMS5003 мы использовали в следующих проектах на нашем сайте:
- комплексный мониторинг качества воздуха на NodeMCU ESP8266;
- анализатор качества воздуха с определением частиц PM1.0, PM2.5 и PM10 на Arduino и датчике PMS5003;
- монитор качества воздуха 5 в 1 на Arduino своими руками.
Необходимые компоненты
- Модуль ESP32 (купить на AliExpress).
- Датчик PM2.5/PM10 PMS5003 (купить на AliExpress).
- Вентилятор 12 В постоянного тока.
- SSD1306 0.96” OLED дисплей (купить на AliExpress). Для этого проекта выбирайте модель дисплея с 4 контактами.
- Реле 5В (купить на AliExpress).
- Регулятор напряжения LM7805 (купить на AliExpress).
- Диод 1N4007 купить на AliExpress).
- Резистор 330 Ом.
- Зуммер 5В (купить на AliExpress).
- Транзистор BC547.
- Разъем питания постоянного тока.
- Источник питания постоянного тока 12 В.
- Разъемы типа "мама".
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Модуль датчика PM2.5/PM10 PMS5003
PMS5003 — это своего рода цифровой и универсальный датчик концентрации частиц, который может использоваться для получения количества взвешенных частиц в воздухе. Он выводит концентрацию PM через цифровой интерфейс.
В PMS5003 используется принцип лазерного рассеяния. Это означает, что он производит рассеяние, используя лазер для излучения взвешенных частиц в воздухе, затем собирает рассеянный свет до определенной степени и, наконец, получает кривую изменения рассеянного света со временем.
Датчик имеет интерфейс UART, вы можете использовать преобразователь USB-Serial и анализировать данные на компьютере. Датчик работает в диапазоне от 4,5 В до 5 В с активным потреблением тока 100 мА. Датчик измеряет PM1.0, PM2.5 и PM10 в эффективном диапазоне 0~500 мкг/м³ и с максимальным диапазоном 1000 мкг/м³. Вы можете проверить технический паспорт PMS5003, если хотите узнать больше об этом датчике.
Технические характеристики PMS5003
- Диапазон измерения: 0,3~1,0; 1,0~2,5; 2,5~10 мкм.
- Эффективный диапазон: 0~500 мкг/м³.
- Максимальный диапазон: ≥1000 мкг/м³.
- Разрешение: 1 мкг/м³.
- Источник питания постоянного тока: тип: 5,0 / мин: 4,5 / макс: 5,5 В.
- Активный ток: ≤100 мА.
- Ток в режиме ожидания: ≤200 мкА.
- Диапазон рабочих температур: -10~+60 ℃.
- Диапазон рабочей влажности: 0~99%.
- Размеры сенсорного модуля: 50 × 38 × 21 мм.
Распиновка PMS5003
PMS5003 имеет 8 контактов, из которых только 4 контакта могут использоваться. Контакт 1 находится с правой стороны и требует 8-контактного разъема (растр 1,25 мм).
Номер контакта | Функция | Описание | Примечания |
1 | VCC | Напряжение питания 5В | 4,5 – 5,5 В |
2 | GND | Земля (общий провод) | |
3 | SET | HIGH или SUSPENDED – рабочий режим LOW – спящий режим |
3.3V logic |
4 | RXD | Прием данных UART/TTL | 3.3V logic |
5 | TXD | Передача данных UART/TTL | 3.3V logic |
6 | Reset | LOW для сброса | 3.3V logic |
7 | NC | не подключается | |
8 | NC | не подключается |
При текущем курсе доллара датчик стоит на Алиэкспрессе около 1400 руб.
Проектирование схем и аппаратных средств
Теперь давайте спроектируем всю нашу систему. Основными компонентами системы являются ESP32, PMS5003 и OLED-дисплей вместе с реле, зуммером, вентилятором постоянного тока и блоком питания . Мы используем 12 В/9 В для питания всей схемы. Питание 12 В преобразуется в 5 В с помощью регулятора напряжения 7805 IC. Затем ESP32 и PMS5003 питаются от 5 В. Реле также требует 5 В, но вентилятору постоянного тока требуется 12 В для активации. В случае, если вы хотите использовать увлажнитель, вам нужно изменить подключение реле и тип реле.
Схема системы мониторинга частиц PM1.0, PM2.5 и PM10 на основе ESP32, PMS5003 и OLED-дисплее приведена на следующем рисунке.
OLED-дисплей — это модуль I2C, поэтому он подключен к контактам I2C ESP32, т. е. контакты SDA и SCL дисплея подключены к контактам GPIO21 и GPIO22 ESP32 соответственно. Реле включается через NPN транзистор BC547, который подключен к GPIO23 ESP32. Аналогично датчик PMS5003 подключен к контакту UART2 ESP32, т. е. TX и RX PMS5003 подключены к RX2 и TX2 ESP32. 5-вольтовый зуммер подключен к GPIO15 ESP32, который активируется только в том случае, если уровень PM2.5 пересекает пороговое значение, определенное в коде.
Проектирование печатной платы для проекта
Печатная плата для мониторинга PM2.5 на базе платы ESP32 с системой освежителя воздуха была разработана в онлайн-инструменте для создания печатных плат EasyEDA. Ниже представлен вид спереди и вид сзади печатной платы.
Файл Gerber для изготовления этой печатной платы вы можете скачать по следующей ссылке. Вы можете заказать изготовление печатной платы в любом сервисе, в котором вы привыкли это делать.
После изготовления качество печатной платы оказалось отличное.
Наконец, после пайки и монтажа всех компонентов на полученной печатной плате, плата выглядит великолепно. Вы можете сделать это оборудование более красивым, спроектировав 3D-корпус для правильного размещения и упаковки деталей.
Исходный код программы
Теперь давайте посмотрим на код для нашего проекта. Код требует несколько библиотек для компиляции. Вы можете скачать необходимые библиотеки по следующей ссылкам:
- Библиотека PMS5003 : https://github.com/fu-hsi/PMS
- Библиотека Adafruit GFX : https://github.com/adafruit/Adafruit-GFX-Library
- Библиотека SSD1306 : https://github.com/adafruit/Adafruit_SSD1306
В следующих строках кода измените SSID и пароль WiFi на данный для своей WiFi сети.
1 2 |
const char* ssid = "Alexahome"; const char* password = "loranthus"; |
Измените пороговое значение на желаемое. В настоящее время оно установлено на 150. Это пороговое значение используется для включения/выключения реле, а также зуммера.
1 |
if (val2.toFloat() >= 150) |
Полный код проекта приведен ниже. Вы можете выбрать плату ESP32 из списка Board Manager и загрузить код на плату ESP32.
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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
#include <WiFi.h> #include <WebServer.h> #include "PMS.h" #include <HardwareSerial.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> PMS pms(Serial2); PMS::DATA data; #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); String val1; String val2; String val3; int relayPin = 23; int buzzerPin = 15; const char* ssid = "Alexahome"; const char* password = "loranthus"; WebServer server(80); void setup() { Serial.begin(9600); Serial2.begin(9600); pinMode(relayPin, OUTPUT); pinMode(buzzerPin, OUTPUT); digitalWrite(relayPin, LOW); digitalWrite(buzzerPin, LOW); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.display(); delay(100); display.clearDisplay(); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(10, 20); display.print("Initializing...."); display.display(); delay(3000); 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(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected..!"); Serial.print("Got IP: "); Serial.println(WiFi.localIP()); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(20, 20); display.print("WiFi connected..!"); display.setTextSize(1); display.setCursor(20, 40); display.print(WiFi.localIP()); display.display(); delay(4000); server.on("/", handle_OnConnect); server.onNotFound(handle_NotFound); server.begin(); Serial.println("HTTP server started"); delay(2000); } void loop() { if (pms.read(data)) { val1 = data.PM_AE_UG_1_0; val2 = data.PM_AE_UG_2_5; val3 = data.PM_AE_UG_10_0; Serial.println("Air Quality Monitor"); Serial.println("PM1.0 :" + val1 + "(ug/m3)"); Serial.println("PM2.5 :" + val2 + "(ug/m3)"); Serial.println("PM10 :" + val3 + "(ug/m3)"); Serial.println(""); display.clearDisplay(); display.setTextSize(1); display.setCursor(10, 10); display.print("PM1.0: "); display.print(val1); display.print(" ug/m3"); display.setCursor(10, 30); display.print("PM2.5: "); display.print(val2); display.print(" ug/m3"); display.setCursor(10, 50); display.print("PM10 : "); display.print(val3); display.print(" ug/m3"); display.display(); delay(2000); } if (val2.toFloat() >= 150) { digitalWrite(relayPin, HIGH); digitalWrite(buzzerPin, HIGH); } else { digitalWrite(relayPin, LOW); digitalWrite(buzzerPin, LOW); } server.handleClient(); } void handle_OnConnect() { server.send(200, "text/html", SendHTML(val1.toFloat(), val2.toFloat(), val3.toFloat())); } void handle_NotFound() { server.send(404, "text/plain", "Not found"); } String SendHTML(int val1, int val2, int val3) { 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>Wireless Weather Station</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>Particulate Matter Monitoring</h1>\n"; ptr += "<p>PM1.0: "; ptr += val1; ptr += " ug/m3</p>"; ptr += "<p>PM2.5: "; ptr += val2; ptr += " ug/m3</p>"; ptr += "<p>PM10: "; ptr += val3; ptr += " ug/m3</p>"; ptr += "</div>\n"; ptr += "</body>\n"; ptr += "</html>\n"; return ptr; } |
Тестирование работы проекта
После успешной загрузки кода устройство будет готово к работе. На OLED-дисплее отобразится сообщение об инициализации датчика. Датчику PMS5003 требуется некоторое время для нагрева. После нагрева вентилятор внутри него начнет вращаться, на OLED-дисплее отобразятся правильные значения PM1.0, PM2.5 и PM10.
Чтобы проверить работу датчика, принесите некоторые материалы, которые выделяют дым или газы. Дым можно подать около вентилятора датчика. В моем случае я предпочел ароматическую палочку для проверки устройства. Как только дым попадет около датчика, значения PM1.0, PM2.5 и PM10 увеличатся и их можно будет наблюдать на OLED-экране. Кроме того, вентилятор включится и начнет выдувать воздух, чтобы поддерживать свежесть воздуха.
Вы также можете контролировать PM1.0, PM2.5, PM10 на платформе IoT по беспроводной сети. Для этого мы добавили код веб-сервера в указанную выше программу. Используя код веб-сервера, данные о твердых частицах можно контролировать на веб-сервере ESP32. Чтобы получить доступ к веб-серверу, нажмите кнопку сброса на OLED-экране. Он отобразит IP-адрес.
Теперь вы можете использовать IP-адрес и вставить его в веб-браузер компьютера или мобильного телефона. После нажатия Enter отобразится страница, на которой вы можете увидеть данные PM1.0, PM2.5, PM10. Вам не нужно обновлять страницу снова и снова, чтобы увидеть данные, поскольку данные обновляются автоматически через несколько секунд. Это потому, что код уже имеет скрипт AJAX (асинхронный Javascript и XML), поэтому мы можем запрашивать данные с сервера асинхронно (в фоновом режиме) без обновления страницы.