Детектор-измеритель уровня пыли в воздухе

Летом обычно повышается запыленность воздуха, и особенно много опасных для здоровья источников PM2,5 частиц (взвешенная пыль PM2,5 с диаметром не более 2,5 мкм). Это простое устройство позволяет не только обнаруживать их и измерять содержание в воздухе, но и определять источники пыли.

По данным Всемирной организации здравоохранения (ВОЗ), пыль PM2,5 является одним из наиболее вредных для здоровья человека загрязнителей воздуха. Как показывают отчеты ВОЗ, длительное воздействие пыли PM2,5 приводит к сокращению продолжительности жизни. А кратковременное воздействие высоких концентраций этого типа пыли может вызвать респираторные и сердечно-сосудистые заболевания, повысить риск возникновения чрезвычайных ситуаций, требующих госпитализации (астма, острая респираторная реакция, снижение функции легких). Это связано с тем, что такая мелкая пыль способна проходить через легкие в кровь. По оценке ВОЗ, из-за этого среднестатистический житель РФ теряет более 10 месяцев жизни.

Чтобы уменьшить количество загрязнения вокруг нас, необходимо знать его источники. Только тогда они могут быть устранены или изолированы. Даже в наших домах есть много источников этой пыли. Предлагаемый прибор позволяет отслеживать их местонахождение путем выборочной проверки содержания PM2,5 в воздухе. Это возможно благодаря датчику Honeywell. Он имеет собственный вентилятор и окна входа – выхода, через которые воздух поступает к датчику. На базе него и разработана система селективного отбора проб воздуха в виде портативного устройства с питанием от батареек.



Детектор-измеритель уровня пыли в воздухе

Для сборки необходимо несколько электронных модулей, которые можно приобрести в интернет-магазинах. Базовым и самым дорогим элементом является датчик пыли HPMA115S0-TIR, установленную в модуле PMS5003. Это лазерный детектор и счетчик переносимых по воздуху пылевых частиц. Он работает по принципу рассеяния света на частицах пыли – анализируемый воздух проходит через лазерный луч света, который отражается от частиц пыли – эти отражения регистрируются встроенными фотодетекторами и преобразуются в электрический сигнал, который позволяет датчику рассчитать концентрацию пыли в воздухе.

Датчик пыли связывается с микроконтроллером через последовательный интерфейс UART. В качестве контроллера использован модуль с микросхемой ESP32 – D1 MINI. Это недорогой контроллер, оснащенный мощным процессором и беспроводными интерфейсами WiFi и Bluetooth.



Плата микроконтроллера и датчик питаются от одной банки Li-Ion 18650 через модуль питания с повышающим преобразователем. Этот модуль обеспечивает управление всей силовой частью, предотвращая опасно глубокую разрядку элемента и контролирует его зарядку.

Пользовательский интерфейс состоит из двух элементов – OLED-экрана и триггера. Дисплей имеет диагональ 0,96 дюйма и разрешение 128 х 64 пикселя, чего с таким маленьким экраном более чем достаточно для обеспечения четкого изображения. Триггер управляет микровыключателем на устройстве, запускающем измерение. Его значение затем отображается на OLED-экране. Вторая кнопка, расположенная на корпусе, управляет подачей питания на схему.

В дополнение к электронным компонентам для сборки также необходим корпус. Он полностью выполнен в 3D-печати. Для проекта требуется напечатать пять элементов.

Анализатор сконструирован таким образом что вентиляторы, встроенные в датчик, перемещают воздух через устройство. Сопло на одном конце подключается непосредственно к входным портам датчика, а выпускное отверстие проходит через корпус и через несколько отверстий в задней крышке. Благодаря этому можно вводить воздух в датчик из точно определенного места. Это наглядно показано на рисунке.

Полезное на сайте:
Чертеж короба для сабвуфера 12 дюймов

Детектор-измеритель уровня пыли в воздухе

Порт зарядки расположен в нижней части корпуса наконечника. Спусковой механизм состоит из кнопки, напечатанной как одно целое. Во время сборки убедитесь, что она свободно перемещается, и нажимает на рычаг концевого выключателя, замыкающего цепь.

Схема сборки анализатора пыли

Детектор-измеритель уровня пыли в воздухе

Схема подключения отдельных модулей показана на рисунке. Датчик пыли подсоединен к модулю с микроконтроллером через интерфейс UART на контактах X (21) и Y (22) модуля с ESP32. Дисплей связывается с микроконтроллером через интерфейс I2C на контактах 19 (SDA) и 20 (SCL). Модуль с микроконтроллером, светодиодами RGB и датчиком пыли питаются от напряжения 5 В, поступающего от преобразователя. OLED-экран питается от линейного стабилизатора 3,3 В, который интегрирован в модуль с микроконтроллером. Инвертор питается от одного литий-ионного элемента 18650.

Программное обеспечение

Всё запрограммировано в среде Arduino IDE. Код программы управления приведен в листинге.

Listing 1.
#include <HardwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerifBoldItalic24pt7b.h>
#include <Fonts/FreeSerifBold9pt7b.h>
// Szerokosc ekranu OLED w pikselach
#define SCREEN_WIDTH 128
// Wysokosc ekranu OLED w pikselach
#define SCREEN_HEIGHT 64
#include <Adafruit_NeoPixel.h>
#define PIN 18
// Deklaracja pinow do podlaczenia kontrolera SSD1306
Adafruit_SSD1306 display
(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Deklaracja pinow do podlaczenia diod RGB LED
Adafruit_NeoPixel strip = Adafruit_NeoPixel
(12, PIN, NEO_GRB + NEO_KHZ800);
long lastMsg = 0;
char msg[50];
bool HPMAstatus = false;
int zedLevel = 1;
int PM25;
int PM10;
int oldP;
HardwareSerial HPMA115S0(1);
TXD2 17
void setup(){
Serial.begin(9600, SERIAL_8N1);
delay(100);
while (!Serial);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(“SSD1306 allocation failed”);
for(;;);
}
delay(2000);
strip.begin();
strip.show(); // inicjalizacja LED RGB jako wylaczone
HPMA115S0.begin(9600, SERIAL_8N1, RXD2, TXD2);
while (!HPMA115S0);
start_autosend();
}
void loop(){
strip.show();
brighten(zedLevel);
long now = millis();
if (now – lastMsg > 1000) {
lastMsg = now;
display.clearDisplay();
// Odbior informacji z sensora pylow
HPMAstatus = receive_measurement();
if (!HPMAstatus) {
Serial.println
(“Cannot receive data from HPMA115S0!”);
return;
}
snprintf (msg, 16, “%D”, PM25);
snprintf (msg, 16, “%D”, PM10);
if(PM10 != 0){
Serial.println(“PM 2.5:\t” + String(PM25) + ” ug/m3″);
Serial.println(“PM 10:\t” + String(PM10) + ” ug/m3″);
Serial.println(“MQTT published HPMA115S0.”);
display.setFont(&FreeSerifBold9pt7b);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(10,13);
display.print(“PPM”);
display.setCursor(90,13);
display.println(“2.5”);
display.setFont(&FreeSerifBoldItalic24pt7b);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(30,50);
display.println(String(PM25));
display.display();
if(PM25 < 25) zedLevel = 3;
else if(PM25 > 24 && PM25 < 80) zedLevel = 2;
else zedLevel = 1;
Serial.println(zedLevel);
}
}
bool receive_measurement (void){
while(HPMA115S0.available() < 32);
byte HEAD0 = HPMA115S0.read();
byte HEAD1 = HPMA115S0.read();
while (HEAD0 != 0x42) {
if (HEAD1 == 0x42) {
HEAD0 = HEAD1;
HEAD1 = HPMA115S0.read();
} else {
HEAD0 = HPMA115S0.read();
HEAD1 = HPMA115S0.read();
}
}
if (HEAD0 == 0x42 && HEAD1 == 0x4D) {
byte LENH = HPMA115S0.read();
byte LENL = HPMA115S0.read();
byte Data0H = HPMA115S0.read();
byte Data0L = HPMA115S0.read();
byte Data1H = HPMA115S0.read();
byte Data1L = HPMA115S0.read();
byte Data2H = HPMA115S0.read();
byte Data2L = HPMA115S0.read();
byte Data3H = HPMA115S0.read();
byte Data3L = HPMA115S0.read();
byte Data4H = HPMA115S0.read();
byte Data4L = HPMA115S0.read();
byte Data5H = HPMA115S0.read();
byte Data5L = HPMA115S0.read();
byte Data6H = HPMA115S0.read();
byte Data6L = HPMA115S0.read();
byte Data7H = HPMA115S0.read();
byte Data7L = HPMA115S0.read();
byte Data8H = HPMA115S0.read();
byte Data8L = HPMA115S0.read();
byte Data9H = HPMA115S0.read();
byte Data9L = HPMA115S0.read();
byte Data10H = HPMA115S0.read();
byte Data10L = HPMA115S0.read();
byte Data11H = HPMA115S0.read();
byte Data11L = HPMA115S0.read();
byte Data12H = HPMA115S0.read();
byte Data12L = HPMA115S0.read();
byte CheckSumH = HPMA115S0.read();
byte CheckSumL = HPMA115S0.read();
if (((HEAD0 + HEAD1 + LENH + LENL + Data0H + Data0L +
Data1H + Data1L + Data2H + Data2L + Data3H + Data3L +
Data4H + Data4L + Data5H + Data5L + Data6H + Data6L +
Data7H + Data7L + Data8H + Data8L + Data9H + Data9L +
Data10H + Data10L + Data11H + Data11L + Data12H + Data12L)
% 256) != CheckSumL){
Serial.println(“Checksum fail”);
return 0;
}
PM25 = (Data1H * 256) + Data1L;
PM10 = (Data2H * 256) + Data2L;
return 1;
}
}
bool start_autosend(void){
// Start auto send
byte start_autosend[] = {0x68, 0x01, 0x40, 0x57 };
HPMA115S0.write(start_autosend, sizeof(start_autosend));
HPMA115S0.flush();
delay(500);
// Czekanie na odpowiedz
while(HPMA115S0.available() < 2);
byte read1 = HPMA115S0.read();
byte read2 = HPMA115S0.read();
// Sprawdzanie poprawnosci odpowiedzi
if ((read1 == 0xA5) && (read2 == 0xA5)){
// ACK
return 1;
} else if ((read1 == 0x96) && (read2 == 0x96)) {
// NACK
return 0;
}
else return 0;
}
void brighten(int q){
uint16_t i, j;
Serial.print(“this is q”);
Serial.println(q);
switch (q) {
case 1:
for (j = 5; j < 155; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, j, 0, 0);
}
strip.show();
delay(255/(j+1));
}
for (j = 155; j > 6; j–) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, j, 0, 0);
}
strip.show();
delay(255/(j+1));
}
break;
case 2:
for (j = 5; j < 155; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0, j, 0);
}
strip.show();
delay(255/(j+1));
}
for (j = 155; j > 6; j–) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0, j, 0);
}
strip.show();
delay(255/(j+1));
}
break;
case 3:
for (j = 5; j < 155; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0, 0, j);
}
strip.show();
delay(255/(j+1)); ‘p4h m
}
for (j = 155; j > 6; j–) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0, 0, j);
}
strip.show();
delay(255/(j+1));
}
break;
}
}

Программа использует последовательный порт для связи с датчиком. Измерение выполняется 1 раз в секунду, а результаты отправляются в модуль ESP32. Результаты измерений отображаются на OLED-экране с контроллером SSD1306, управляемым по интерфейсу I2C. Светодиоды управляются библиотекой Adafruit Neopixel обычным образом – цвет светодиодов зависит от измеренной концентрации пыли PM2,5.

  • Если уровень меньше 25, светодиоды мигают синим,
  • если уровень находится между 25 и 80 – зеленым,
  • если уровень больше 80 – красным.
Полезное на сайте:
Усилитель измерительных сигналов

Эти предустановленные уровни можно изменить в программном коде, настроив устройство в соответствии с потребностями или стандартами. После компиляции программы и программирования модуля ESP32 (достаточно обычного USB-кабеля) детектор готов к работе. Просто нажмите на кнопку, чтобы измерить и проконтролировать уровень пыли вокруг.