Монитор качества воздуха на Arduino с датчиком пыли DSM501A
Компоненты и материалы
| Arduino Nano R3 | ×1 |
| Модуль датчика пыли DSM501A | ×1 |
| Символьный LCD 16×2 (HD44780) | ×1 |
| Вентилятор 40 мм | ×1 |
| Светодиоды (разных цветов) | ×5 |
| Резистор 220 Ом | ×1 |
| Потенциометр 10 кОм | ×1 |
Инструменты
- Паяльник
Программное обеспечение
- Arduino IDE
О проекте
Устройство для мониторинга качества воздуха на базе недорогого датчика DSM501A (Samyoung), способного определять частицы PM2.5 и PM10. Данные выводятся на LCD-дисплей и в Serial Monitor, а уровень загрязнения индицируется 5 цветными светодиодами.
Принцип работы датчика DSM501A
Датчик выдаёт два PWM-сигнала: Vout1 (PM2.5) и Vout2 (PM10). Низкий уровень сигнала соответствует наличию частиц. Arduino измеряет длительность низких импульсов за фиксированный интервал (3 сек), вычисляет концентрацию по формуле из даташита.
Схема подключения
- Vout1 (PM2.5) → D2 Arduino
- Vout2 (PM10) → D3 Arduino
- Vcc → +5V, GND → GND
- 5 светодиодов → A1–A5 (как выходы)
- LCD 16×2 → стандартная схема (RS, E, D4–D7)
- Вентилятор 40 мм дует воздух через датчик для стабильных показаний
Индикация качества воздуха (по PM10)
| Диапазон (шт/0.01 л) | Статус | Светодиод |
|---|---|---|
| < 1000 | CLEAN (Чисто) | Белый (A1) |
| 1000–10000 | GOOD (Хорошо) | Зелёный (A2) |
| 10000–20000 | ACCEPTABLE (Допустимо) | Жёлтый (A3) |
| 20000–50000 | HEAVY (Тяжело) | Красный (A4) |
| > 50000 | HAZARD (Опасно) | Синий (A5) |
Программная реализация
Скетч использует pulseIn() для измерения длительности LOW-импульсов, накапливает их за 3 секунды, считает коэффициент заполнения (ratio) и концентрацию по полиному 3-й степени из спецификации датчика. На LCD выводится концентрация PM10 и текстовый статус. В Serial Monitor — обе концентрации (PM10 и PM2.5).
Важные замечания
- Вентилятор критически важен — без него показания «плавают» и дают ложные пики.
- Устройство собрано в коробке для электроустановки.
- Автор планирует тестировать другие дешёвые датчики пыли в следующих проектах.
Код (основной скетч)
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int pin2 = 3; int pin1 = 2;
unsigned long duration1, duration2, starttime;
unsigned long sampletime_ms = 3000;
unsigned long lowpulseoccupancy1 = 0, lowpulseoccupancy2 = 0;
float ratio1 = 0, ratio2 = 0, concentration1 = 0, concentration2 = 0;
int wLed = A1, gLed = A2, yLed = A3, rLed = A4, bLed = A5;
void setup() {
Serial.begin(9600);
pinMode(2, INPUT); pinMode(3, INPUT);
pinMode(wLed, OUTPUT); pinMode(gLed, OUTPUT);
pinMode(yLed, OUTPUT); pinMode(rLed, OUTPUT); pinMode(bLed, OUTPUT);
starttime = millis();
lcd.begin(16, 2);
}
void loop() {
duration1 = pulseIn(pin1, LOW);
duration2 = pulseIn(pin2, LOW);
lowpulseoccupancy1 += duration1;
lowpulseoccupancy2 += duration2;
if ((millis() - starttime) > sampletime_ms) {
ratio1 = lowpulseoccupancy1 / (sampletime_ms * 10.0);
concentration1 = 1.1*pow(ratio1,3) - 3.8*pow(ratio1,2) + 520*ratio1 + 0.62;
ratio2 = lowpulseoccupancy2 / (sampletime_ms * 10.0);
concentration2 = 1.1*pow(ratio2,3) - 3.8*pow(ratio2,2) + 520*ratio2 + 0.62;
lcd.setCursor(0, 0);
lcd.print("PM10 ");
lcd.setCursor(6, 0);
lcd.print(concentration1, 3);
Serial.print("concentration1 = "); Serial.print(concentration1);
Serial.print(" pcs/0.01cf - ");
Serial.print("concentration2 = "); Serial.print(concentration2);
Serial.println(" pcs/0.01cf - ");
// Индикация на LCD и светодиодах
lcd.setCursor(0, 1);
for (int i = 0; i < 16; ++i) lcd.write(' ');
lcd.setCursor(4, 1);
if (concentration1 < 1000) { lcd.print("CLEAN"); setLED(wLed); }
else if (concentration1 < 10000) { lcd.print("GOOD"); setLED(gLed); }
else if (concentration1 < 20000) { lcd.print("ACCEPTABLE"); setLED(yLed); }
else if (concentration1 < 50000) { lcd.print("HEAVY"); setLED(rLed); }
else { lcd.print("HAZARD"); setLED(bLed); }
lowpulseoccupancy1 = 0; lowpulseoccupancy2 = 0;
starttime = millis();
}
}
void setLED(int active) {
digitalWrite(wLed, LOW); digitalWrite(gLed, LOW);
digitalWrite(yLed, LOW); digitalWrite(rLed, LOW); digitalWrite(bLed, LOW);
digitalWrite(active, HIGH);
}
Схема сборки
Все компоненты размещены на макетной плате или пайке в корпусе. Вентилятор установлен на выходе датчика для принудительного дутья.
Производственный процесс
- Измерение качества воздуха с OpenSensors: руководство по Arduino и Python
- Солнечный датчик качества воздуха на Helium: руководство по проектированию и развёртыванию
- Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
- Многопозиционная система датчиков температуры для интеграции в умный дом
- Датчик CO2 K30: мониторинг качества воздуха в реальном времени на Arduino
- Простой ИК-датчик препятствий на Arduino: ИК-светодиод и фотодиод
- Интеграция ёмкостного сканера отпечатков DFRobot с Arduino или ESP8266
- Веб-управляемый IoT-индикатор на Arduino, Yaler и IFTTT
- Магнитная левитация на отталкивании с Arduino: Простая схема и DIY-руководство
- Продвинутый углеродный датчик NO₂ улучшает мониторинг качества воздуха в помещениях