DIY-набор датчика PM10, температуры и влажности на Arduino
Компоненты и материалы
| Arduino Nano R3 | 1 шт. |
| Датчик пыли SDS018 (PM2.5/PM10) | 1 шт. |
| Датчик температуры/влажности DHT22 (модуль с подтяжкой и конденсатором) | 1 шт. |
| OLED-дисплей I2C SSD1306 128×32 | 1 шт. |
| Светодиоды 3 мм: зелёный, жёлтый, красный | по 1 шт. |
| Резисторы 390 Ом (для светодиодов) | 3 шт. |
| Конденсатор 100 нФ (опционально, для DHT22) | 1 шт. |
| Резистор 4.7 кОм (опционально, подтяжка DHT22) | 1 шт. |
| Power Bank (питание через USB) | 1 шт. |
| Корпус: винты M3×16 (4 шт.), M3×6 (1 шт.), термоусадка, пины, перемычки | — |
Инструменты
- Паяльник и припой
- 3D-принтер
- Клеевой пистолет
- Дрель
Программное обеспечение
- Arduino IDE
- Библиотеки: Adafruit SSD1306 v2.2.1, DHT sensor library v1.3.10
Обоснование проекта
Проблема: Частицаты как переносчики вирусов
Экспериментальные исследования указывают, что взвешенные частицы (PM) могут выступать «переносчиками» вирусных инфекций, включая COVID-19. Вирусы адсорбируются на частицах, перелетают на большие расстояния и остаются живучими часами, днями и даже неделями.
В Северной Италии локдаун не снизил уровень PM10, так как крупный вклад вносит интенсивное животноводство (навоз → аммиак, PM). Высокая корреляция между превышением PM10 и случаями COVID-19 в Паньской равнине (Ломбардия) подтверждена исследованием SIMA (март 2020).
Влажность также влияет: при <40% и >60% вирусы дольше сохраняют активность в аэрозоле.
Решение: Портативный монитор
Устройство измеряет PM10, температуру и влажность, предупреждая о потенциально опасных условиях. Данные на OLED-дисплее, 3 светодиода индицируют уровень тревоги:
| Уровень | PM10 (мкг/м³) | Влажность (%) | Светодиоды |
|---|---|---|---|
| Норма | 0–25 | 40–60 | Все выкл. |
| Низкий | 0–25 | <40 или >60 | Зелёный |
| Низкий | 26–50 | 40–60 | Зелёный |
| Предупреждение | 26–50 | <40 или >60 | Зелёный + Жёлтый |
| Предупреждение | >51 | 40–60 | Зелёный + Жёлтый |
| Тревога | >51 | <40 или >60 | Все три (зелёный, жёлтый, красный) |
Датчик SDS018 (PM10/PM2.5)
Лазерное рассеяние, диапазон 0.3–10 мкм, UART/TTL, встроенный вентилятор, разрешение 0.3 мкг/м³, CE/FCC/RoHS.
Пин-аут: 1-NC, 2-PWM 1мкм, 3-5V, 4-PWM 2.5мкм, 5-GND, 6-RX, 7-TX.
Подключение к Nano: 5V→5V, GND→GND, TX (pin 7) → RX (pin D0) Nano.
Датчик DHT22
Цифровой, 3–5В, 0–100% влажность (±2–5%), -40…80°C (±0.5°C), 0.5 Гц.
Подключение: VDD→5V, GND→GND, DATA→D2. На модуле уже есть подтяжка 4.7к и конденсатор 100нФ.
OLED SSD1306 I2C 128×32
Подключение: VCC→5V, GND→GND, SCL→A5, SDA→A4.
Светодиоды
Аноды: красный→D3, зелёный→D4, жёлтый→D5. Катоды через 390Ом→GND.
Модификация Arduino Nano
Для чтения UART от SDS018 на пине RX (D0) нужно убрать конфликт с USB-UART конвертером. Удаляем SMD-резистор на линии RX (стрелка на фото), паяем его вертикально и выводим два провода на pin header. Джемпер на pin header надевается только при прошивке. После прошивки можно убрать резистор навсегда (но перепрошить станет нельзя).
Питание
Arduino Nano через USB от Power Bank (5В).
Корпус и сборка
3D-печатный корпус из оранжевого PLA (2 части: нижняя – Arduino и SDS018, верхняя – DHT22, дисплей, светодиоды). Файлы на Sketchfab:
Сборка на горячий клей: фиксация плат, пайка проводов, усадка, закрытие 4 винтами M3×16.
Прошивка (алгоритм)
- Инициализация периферии, тест светодиодов.
- Цикл (каждые 2 сек):
- Чтение DHT22 (влажность, температура) → Serial Monitor.
- Чтение SDS018 (10 байт, проверка заголовка 0xAA 0xC0, контрольная сумма) → PM2.5, PM10 → Serial Monitor.
- Логика тревог по таблице выше → управление светодиодами.
- Дисплей: чередует экраны (PM10 + влажность) / (PM2.5 + температура). При тревоге вместо PM10 пишет «Alarm!!!».
Исходный код (полный скетч)
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
int startdhr22 = 0;
int switchDisplay = 0;
const int ledRed = 3, ledGreen = 4, ledYellow = 5;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledYellow, OUTPUT);
dht.begin();
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); }
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
// Тест светодиодов
digitalWrite(ledGreen, HIGH); delay(500);
digitalWrite(ledYellow, HIGH); delay(500);
digitalWrite(ledRed, HIGH); delay(500);
digitalWrite(ledGreen, LOW); digitalWrite(ledYellow, LOW); digitalWrite(ledRed, LOW);
delay(500);
}
void loop() {
if(0 == startdhr22) { delay(2000); startdhr22 = 1; }
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) { Serial.println("DHT error"); return; }
Serial.print("Humidity: "); Serial.print(h); Serial.print("% Temp: "); Serial.print(t); Serial.println("°C");
// SDS018
uint8_t dataIN[10] = {0};
float pm25 = 0, pm10 = 0;
while(Serial.available() > 0) {
for(int i=0; i<10; i++) dataIN[i] = Serial.read();
if(dataIN[0]==0xAA && dataIN[1]==0xC0 && dataIN[9]==0xAB) {
uint8_t cksum = 0;
for(int i=2; i<=7; i++) cksum += dataIN[i];
if(cksum == dataIN[8]) {
digitalWrite(LED_BUILTIN, HIGH);
pm25 = ((dataIN[3]*256.0)+dataIN[2])/10.0;
pm10 = ((dataIN[5]*256.0)+dataIN[4])/10.0;
Serial.print("PM2.5: "); Serial.print(pm25); Serial.println(" ug/m3");
Serial.print("PM10: "); Serial.print(pm10); Serial.println(" ug/m3");
}
}
Serial.flush();
}
// Светодиоды
if(pm10 <= 25 && h >= 40 && h <= 60) { digitalWrite(ledGreen,LOW); digitalWrite(ledYellow,LOW); digitalWrite(ledRed,LOW); }
else if(pm10 <= 25 && (h < 40 || h > 60)) { digitalWrite(ledGreen,HIGH); digitalWrite(ledYellow,LOW); digitalWrite(ledRed,LOW); }
else if(pm10 > 25 && pm10 <= 50 && h >= 40 && h <= 60) { digitalWrite(ledGreen,HIGH); digitalWrite(ledYellow,LOW); digitalWrite(ledRed,LOW); }
else if(pm10 > 25 && pm10 <= 50 && (h < 40 || h > 60)) { digitalWrite(ledGreen,HIGH); digitalWrite(ledYellow,HIGH); digitalWrite(ledRed,LOW); }
else if(pm10 > 50 && h >= 40 && h <= 60) { digitalWrite(ledGreen,HIGH); digitalWrite(ledYellow,HIGH); digitalWrite(ledRed,LOW); }
else { digitalWrite(ledGreen,HIGH); digitalWrite(ledYellow,HIGH); digitalWrite(ledRed,HIGH); }
// Дисплей
if(switchDisplay == 0) {
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
if(pm10 > 50) display.print("Alarm!!!");
else { display.print("PM10:"); display.println(pm10); }
display.print("HR%:"); display.println(h);
display.display();
switchDisplay = 1;
} else {
display.clearDisplay();
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.setCursor(0,0);
display.print("PM25:"); display.println(pm25);
display.print("T[C]:"); display.println(t);
display.display();
switchDisplay = 0;
}
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(1500);
}
3D-модели корпуса
Электрическая схема
Схема подключения всех модулей к Arduino Nano.
Производственный процесс
- Циклический подход SABIC: пластиковая упаковка, безопасность и устойчивость в условиях COVID-19
- Как COVID-19 ускорил автоматизацию в пластиковой отрасли
- COVID-19 и конец послевоенной экономической парадигмы
- Пандемийный эффект: COVID-19 ускоряет инновации в блокчейне и криптовалюте
- COVID-19 ускоряет конец годовых RFP отгрузчиков
- Wayfair и COVID-19: преодоление вызовов налогового освобождения продавцов в постпандемической экономике
- Преодоление разрыва навыков: переобучение и переквалификация после COVID для производителей
- Руководство и ресурсы по COVID-19 для лидеров производства
- Как COVID-19 переформирует будущее работы и автоматизации — инсайты из нового исследования
- Быстрое, точное обнаружение COVID-19 с использованием графеновых технологий