Оглавление:

Система мониторинга качества воздуха на предмет загрязнения твердыми частицами: 4 шага
Система мониторинга качества воздуха на предмет загрязнения твердыми частицами: 4 шага

Видео: Система мониторинга качества воздуха на предмет загрязнения твердыми частицами: 4 шага

Видео: Система мониторинга качества воздуха на предмет загрязнения твердыми частицами: 4 шага
Видео: О проекте breathe.moscow и проблеме загрязнения воздуха 2024, Ноябрь
Anonim
Система мониторинга качества воздуха на предмет загрязнения твердыми частицами
Система мониторинга качества воздуха на предмет загрязнения твердыми частицами
Система мониторинга качества воздуха на предмет загрязнения твердыми частицами
Система мониторинга качества воздуха на предмет загрязнения твердыми частицами

ВСТУПЛЕНИЕ:

1 В этом проекте я показываю, как создать детектор частиц с отображением данных, резервным копированием данных на SD-карту и IOT. Визуально неопиксельный кольцевой дисплей показывает качество воздуха.

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

Например:

www.atmos-meas-tech.net/11/4823/2018/amt-1…

3 Поэтому я решил создать устройство, способное измерять количество частиц по классам размера (от 0,5 мкм до 10 мкм), визуально с простым отображением результата (неопиксельное кольцо), более подробным отображением на экране TFT и резервное копирование с меткой времени на SD-карту.

4 Кроме того, я добавил модуль связи Bluetooth, чтобы иметь возможность общаться с приложением Android и, таким образом, публиковать результаты на сервере IOT.

5 Общая стоимость всего не превышает 60 €.

Запасы

-Arduino uno R3

-Ардуино прото-щит

-TFT экран ST7735

-Неопиксельное кольцо 24 светодиода

-Площадка PMS5003

-HC-06 модуль bluetooth

Шаг 1: Подключение компонентов

Подключение компонентов
Подключение компонентов

различные компоненты подключаются в соответствии со схемой выше

Шаг 2: библиотека и программа Arduino

1 библиотека

для экрана TFT

github.com/adafruit/Adafruit-GFX-Library

для кольца neo pixel

github.com/adafruit/Adafruit_NeoPixel

для sd-карты

github.com/arduino-libraries/SD

2 скетч Arduino

#include #include // Библиотека для I2C #include "RTClib.h" // Библиотека для модуля RTC RTC_DS1307 RTC; #включают

// Какой вывод на Arduino подключен к NeoPixels?

#define PIN 6 // На Trinket или Gemma предложите изменить его на 1

// Сколько NeoPixels подключено к Arduino?

#define NUMPIXELS 24 // Популярный размер кольца NeoPixel Adafruit_NeoPixel пикселей (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t vert = пикселей. Цвет (0, 250, 0); uint32_t оранжевый = пикселей. Цвет (250, 250, 0); uint32_t rouge = пикселей. Цвет (255, 0, 0);

SoftwareSerial pmsSerial (2, 3);

#define cs 10 #define dc 9 #define rst 8 // вы также можете подключить это к сбросу Arduino

#include // Базовая графическая библиотека

#include // Аппаратная библиотека #include #include const int cs_sd = 4; int temps; // время захвата double tempsInit; // инициализация таймера с остановкой цикла ()

#if defined (_ SAM3X8E_)

#undef _FlashStringHelper:: F (строковый_литерал) #define F (строковый_литерал) строковый_литерал #endif

// Вариант 1: использовать любые булавки, но немного медленнее

// Adafruit_ST7735 tft = Adafruit_ST7735 (cs, dc, mosi, sclk, rst);

// Вариант 2: необходимо использовать аппаратные выводы SPI

// (для UNO это sclk = 13 и sid = 11) и вывод 10 должен быть // выходом. Это намного быстрее - также требуется, если вы // хотите использовать карту microSD (см. Пример рисования изображения) Adafruit_ST7735 tft = Adafruit_ST7735 (cs, dc, rst); поплавок nombre_leds = 0; void setup () {Serial.begin (9600); // Инициализируем связь I2C Wire.begin (); // Инициализировать модуль файла RTC RTC.begin (); Serial.print ("инициализация SD"); задержка (1000); if (! SD.begin (cs_sd)) // Условие проверено по карте SD, если оно указано в приложении {Serial.print ("Defaut SD"); возвращение; } Serial.print ("Карта SD ОК");

Данные файла = SD.open ("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"

data.println (""); data.println («Приобретение Демаража»); // Ecrit dans ce fichier data.close (); tft.initR (INITR_GREENTAB); // инициализируем микросхему ST7735S, черная вкладка Serial.println ("init"); // наш отладочный вывод tft.fillScreen (ST7735_BLACK); // скорость передачи датчика 9600 pmsSerial.begin (9600);

pixel.begin (); // ИНИЦИАЛИЗИРУЕМ объект полосы NeoPixel (ОБЯЗАТЕЛЬНО)

pixel.setBrightness (2);

}

struct pms5003data {

uint16_t framelen; uint16_t pm10_standard, pm25_standard, pm100_standard; uint16_t pm10_env, pm25_env, pm100_env; uint16_t частицы_03um, частицы_05um, частицы_10um, частицы_25um, частицы_50um, частицы_100um; uint16_t не используется; uint16_t контрольная сумма; };

данные struct pms5003data; void loop () {пикселей.clear (); // Устанавливаем все цвета пикселей на «выключено» DateTime now = RTC.now (); // Обновить дату и время // affiche_date_heure (сейчас);

temps = ((millis () - tempsInit)) / 1000; // Démarrage du chrono

if (readPMSdata (& pmsSerial)) {// tft.fillScreen (ST7735_BLACK); tft.setCursor (10, 5); tft.setTextColor (ST7735_WHITE); tft.println («количество частей / 0,1 л»);

tft.setCursor (10, 17); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.setCursor (10, 17); tft.print ("0,3 мкм); tft.print (data.particles_03um); tft.print (" ");

tft.setCursor (10, 29);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("0,5 мкм"); tft.print (data.particles_05um); tft.print ("");

tft.setCursor (10, 41);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("1,0 мкм"); tft.print (data.particles_10um); tft.print ("");

tft.setCursor (10, 53);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("2,5 мкм"); tft.print (data.particles_25um); tft.print ("");

tft.setCursor (10, 65);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("5,0 мкм"); tft.print (data.particles_50um); tft.print ("");

tft.setCursor (10, 77);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("10 мкм"); tft.print (data.particles_100um); tft.print ("");

tft.setCursor (2, 89);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("PM 1.0"); tft.setTextColor (ST7735_YELLOW, ST7735_BLACK); tft.print (data.pm10_standard); tft.print (""); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.print (" мкг / м3 ");

tft.setCursor (2, 100); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print («PM 2.5»); tft.setTextColor (ST7735_YELLOW, ST7735_BLACK); tft.print (data.pm25_standard); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.print («мкг / м3»);

tft.setCursor (2, 110);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print («PM 10»); tft.setTextColor (ST7735_YELLOW, ST7735_BLACK); tft.print (data.pm100_standard); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.print («мкг / м3»);

tft.setCursor (10, 5);

tft.setTextColor (ST7735_WHITE, ST7735_BLACK); tft.setTextSize (1); tft.println («количество частей / 0,1 л»);

// Serial.print (temps);

// Serial.print (""); Serial.print ("#"); Serial.print («03 мкм»); Serial.print (data.particles_03um); Serial.print (""); Serial.print («05 мкм»); Serial.print (data.particles_05um); Serial.print (""); Serial.print («1 мкм»); Serial.print (data.particles_10um); Serial.print (""); Serial.print («25 мкм»); Serial.print (data.particles_25um); Serial.print (""); Serial.print («50 мкм»); Serial.print (data.particles_50um); Serial.print (""); Serial.print («100 мкм»); Serial.print (data.particles_100um); Serial.println (""); nombre_leds = int (((float (data.particles_03um) / 65535) * 24)); // nombre_leds = (8); Serial.println (nombre_leds);

if ((nombre_leds = 1)) {

pixel.fill (vert, 0, nombre_leds); } else if ((nombre_leds = 8)) {пикселей.fill (vert, 0, 8); pixel.fill (оранжевый, 8, ((nombre_leds) -8)); } else if (nombre_leds> 16) {

pixel.fill (верт, 0, 8); pixel.fill (оранжевый, 8, 8); пикселей.fill (румяна, 16, ((nombre_leds) -16)); } иначе, если (nombre_leds <= 1) {пикселей.fill (верт, 0, 1); } pixel.show (); // Отправляем обновленные цвета пикселей на оборудование.

// Не указано определение String PM03 = String (data.particles_03um); Строка PM05 = Строка (data.particles_05um); Строка PM10 = Строка (data.particles_10um); Строка PM25 = Строка (data.particles_25um); Строка PM50 = Строка (data.particles_50um); Строка PM100 = Строка (data.particles_100um); Строка PMS10 = Строка (data.pm10_standard); Строка PMS25 = Строка (data.pm25_standard); Строка PMS100 = Строка (data.pm100_standard); Строка Temps = Строка (temps);

// Ecriture des données dans le fichier texte

Данные файла = SD.open ("donnees.txt", FILE_WRITE); data.println (Temps + "" + PM03 + "" + PM05 + "" + PM10 + "" + PM25 + "" + PM50 + "" + PM100 + "" + PMS10 + "" + PMS25 + "" + PMS100 + ""); data.close (); }

}

логическое readPMSdata (Stream * s) {

если (! s-> доступно ()) {вернуть ложь; } // Читаем по байту, пока не дойдем до специального начального байта '0x42' if (s-> peek ()! = 0x42) {s-> read (); вернуть ложь; }

// Теперь читаем все 32 байта

если (s-> available () readBytes (буфер, 32);

// получаем готовую контрольную сумму

для (uint8_t я = 0; я <30; я ++) {сумма + = буфер [я]; }

/ * отладка

для (uint8_t я = 2; я <32; я ++) {Serial.print ("0x"); Serial.print (буфер , HEX); Serial.print (","); } Serial.println (); * / // Данные поступают в порядке порядка следования байтов, это решает проблему и работает на всех платформах uint16_t buffer_u16 [15]; для (uint8_t я = 0; я <15; я ++) {buffer_u16 [я] = буфер [2 + я * 2 + 1]; buffer_u16 + = (буфер [2 + i * 2] << 8); }

// поместим в красивую структуру:)

memcpy ((void *) & data, (void *) buffer_u16, 30);

if (sum! = data.checksum) {

Serial.println («Ошибка контрольной суммы»); вернуть ложь; } // успех! вернуть истину; }

// Converti le numéro de jour en jour /! / La semaine begin un dimanche

Строка donne_jour_semaine (uint8_t j) {переключатель (j) {case 0: return "DIM"; случай 1: вернуть «LUN»; случай 2: вернуть «МАР»; случай 3: вернуть «MER»; случай 4: вернуть «JEU»; случай 5: вернуть «ВЕН»; случай 6: вернуть «SAM»; по умолчанию: return ""; }}

// affiche la date et l'heure sur l'écran

void affiche_date_heure (DateTime datetime) {// Строка даты jour = donne_jour_semaine (datetime.dayOfTheWeek ()) + "" + Vers2Chiffres (datetime.day ()) + "/" + Vers2Chiffres (datetime.month ()) + "/" + Строка (datetime.year (), DEC); // heure String heure = ""; heure = Vers2Chiffres (datetime.hour ()) + ":" + Vers2Chiffres (datetime.minute ()) + ":" + Vers2Chiffres (datetime.second ());

Serial.print (журнал); Serial.print (""); Serial.print (heure); //Serial.print (""); Данные файла = SD.open ("donnees.txt", FILE_WRITE); data.print (jour + "" + heure + ""); data.close ();

tft.setCursor (2, 120);

tft.setTextColor (ST7735_GREEN); tft.setTextSize (1); tft.print ("дата"); tft.setTextColor (ST7735_YELLOW); tft.print (jour); tft.setTextColor (ST7735_GREEN); tft.setCursor (2, 130); tft.print ("heure"); tft. setTextColor (ST7735_YELLOW); tft.print (heure);

задержка (500);

}

// permet d'afficher les nombres sur deux chiffres

String Vers2Chiffres (число байтов) {String resultat = ""; если (число <10) результат = "0"; вернуть результатat + = String (nombre, DEC); }

Шаг 3. Программа MIT App Inventor 2

Программа MIT App Inventor 2
Программа MIT App Inventor 2

это блок кода изобретателя приложения MIT

Шаг 4: РЕЗУЛЬТАТ

вот видео результата

Рекомендуемые: