Sommario:

Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato: 4 passaggi
Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato: 4 passaggi

Video: Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato: 4 passaggi

Video: Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato: 4 passaggi
Video: Qualità dell’aria: presentazione delle tecniche per l’analisi del particolato atmosferico e.... 2024, Dicembre
Anonim
Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato
Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato
Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato
Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato

INTRODUZIONE:

1 In questo progetto mostro come costruire un rilevatore di particelle con visualizzazione dei dati, backup dei dati su scheda SD e IOT. Visivamente un display ad anello in neopixel indica la qualità dell'aria.

2 La qualità dell'aria è oggi una preoccupazione sempre più importante. ci sono sistemi per misurare il tasso di polvere ma sono molto costosi. Sul mercato sono presenti rilevatori di particelle a basso costo e di alta qualità, come dimostrato da alcuni studi.

per esempio:

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

3 Ho quindi deciso di realizzare un dispositivo in grado di misurare il numero di particelle per classi dimensionali (da 0,5µm a 10 µm), visivamente con una semplice visualizzazione del risultato (neo pixel ring), una visualizzazione più dettagliata su uno schermo TFT e un backup con data e ora su una scheda SD.

4 Inoltre ho aggiunto un modulo di comunicazione bluetooth per poter comunicare con un'applicazione Android e quindi pubblicare i risultati su un server IOT.

5 Il costo complessivo dell'insieme non supera i 60 €

Forniture

-Arduino uno R3

-Arduino proto scudo

-Schermo TFT ST7735

-Anello in neopixel 24 led

-Plantower PMS5003

-Modulo bluetooth HC-06

Passaggio 1: collegamento dei componenti

Collegamento dei componenti
Collegamento dei componenti

i diversi componenti sono collegati secondo lo schema sopra

Passaggio 2: libreria e programma Arduino

1 la biblioteca

per lo schermo TFT

github.com/adafruit/Adafruit-GFX-Library

per il neo pixel ring

github.com/adafruit/Adafruit_NeoPixel

per la scheda SD

github.com/arduino-libraries/SD

2 lo schizzo di arduino

#include #include // Bibliothèque per l'I2C #include "RTClib.h" // Bibliothèque per il modulo RTC RTC_DS1307 RTC; #includere

// Quale pin dell'Arduino è connesso ai NeoPixel?

#define PIN 6 // Su Trinket o Gemma, suggerisci di cambiarlo in 1

// Quanti NeoPixel sono collegati ad Arduino?

#define NUMPIXELS 24 // Dimensione dell'anello NeoPixel popolare Adafruit_NeoPixel pixel (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t vert = pixels. Color(0, 250, 0); uint32_t arancione = pixel. Color(250, 250, 0); uint32_t rouge = pixels. Color(255, 0, 0);

SoftwareSerial pmsSerial(2, 3);

#define cs 10 #define dc 9 #define rst 8 // puoi anche collegarlo al reset di Arduino

#include // Libreria grafica principale

#include // Libreria specifica per l'hardware #include #include const int cs_sd=4; temperature int; // temps d'acquisizione double tempsInit; // inizializzazione del timer au démarrage du loop()

#se definito(_SAM3X8E_)

#undef _FlashStringHelper::F(string_literal) #define F(string_literal) string_literal #endif

// Opzione 1: usa qualsiasi pin ma un po' più lentamente

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

// Opzione 2: deve utilizzare i pin SPI hardware

// (per UNO questo è sclk = 13 e sid = 11) e il pin 10 deve essere // un'uscita. Questo è molto più veloce - richiesto anche se si desidera // utilizzare la scheda microSD (vedere l'esempio di disegno dell'immagine) Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); float nombre_leds=0; void setup() { Serial.begin(9600); // Inizializza il collegamento I2C Wire.begin(); // Inizializza il modulo RTC RTC.begin(); Serial.print("init SD"); ritardo(1000); if(!SD.begin(cs_sd)) //Condition vérifiant si la carte SD est présente dans l'appareil { Serial.print("Defaut SD"); Restituzione; } Serial.print("Carta SD OK");

Dati file = SD.open("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"

data.println(""); data.println("Acquisizione demolizione"); // Ecrit dans ce fichier data.close(); tft.initR(INITR_GREENTAB); // inizializza un chip ST7735S, tab nero Serial.println("init"); // il nostro output di debug tft.fillScreen(ST7735_BLACK); // la velocità di trasmissione del sensore è 9600 pmsSerial.begin(9600);

pixel.begin(); // INIZIALIZZA oggetto striscia NeoPixel (OBBLIGATORIO)

pixels.setBrightness(2);

}

struttura pms5003data {

uint16_t framelen; uint16_t pm10_standard, pm25_standard, pm100_standard; uint16_t pm10_env, pm25_env, pm100_env; uint16_t particelle_03um, particelle_05um, particelle_10um, particelle_25um, particelle_50um, particelle_100um; uint16_t non utilizzato; uint16_t checksum; };

struttura pms5003data dati; void loop() { pixels.clear(); // Imposta tutti i colori dei pixel su 'off' DateTime now=RTC.now(); //Récupère l'heure et le date courante //affiche_date_heure(now);

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("nbre parti/ 0,1 l");

tft.setCursor(10, 17); tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.setCursor(10, 17); tft.print("0.3um ");tft.print(data.particles_03um);tft.print(" ");

tft.setCursor(10, 29);

tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("0.5um ");tft.print(data.particles_05um);tft.print(" ");

tft.setCursor(10, 41);

tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("1.0um ");tft.print(data.particles_10um);tft.print(" ");

tft.setCursor(10, 53);

tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("2.5um ");tft.print(data.particles_25um);tft.print(" ");

tft.setCursor(10, 65);

tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("5.0um ");tft.print(data.particles_50um);tft.print(" ");

tft.setCursor(10, 77);

tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("10um");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(" microg/m3 ");

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(" microg/m3 ");

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(" microg/m3 ");

tft.setCursor(10, 5);

tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.setTextSize(1); tft.println("nbre parti/ 0,1 l");

// Serial.print(temps);

// Serial.print (" "); Serial.print ("#"); Serial.print ("03µm "); Serial.print(data.particles_03um); Serial.print (" "); Serial.print ("05µm "); Serial.print(data.particles_05um); Serial.print (" "); Serial.print ("1µm "); Serial.print(data.particles_10um); Serial.print (" "); Serial.print ("25µm "); Serial.print(data.particles_25um); Serial.print (" "); Serial.print ("50µm "); Serial.print(data.particles_50um); Serial.print (" "); Serial.print ("100µm "); 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)){

pixels.fill(vert, 0, nombre_leds); } else if ((nombre_leds=8)) { pixels.fill(vert, 0, 8); pixels.fill(arancione, 8, ((nombre_leds)-8)); } else if (nombre_leds>16) {

pixel.fill(vert, 0, 8); pixel.fill(arancione, 8, 8); pixels.fill(rouge, 16, ((nombre_leds)-16)); } else if (nombre_leds<=1) { pixels.fill(vert, 0, 1); } pixel.mostra(); // Invia i colori dei pixel aggiornati all'hardware.

// Definizione dati String PM03=String(data.particles_03um); String PM05=String(data.particles_05um); String PM10=String(data.particles_10um); String PM25=String(data.particles_25um); String PM50=String(data.particles_50um); String PM100=String(data.particles_100um); Stringa PMS10=Stringa(data.pm10_standard); Stringa PMS25=Stringa(data.pm25_standard); Stringa PMS100=Stringa(data.pm100_standard); Tempi stringa=Stringa(Tempi);

//Ecriture des données dans le fichier texte

File data=SD.open("donnees.txt", FILE_WRITE); data.println(Temps + " " + PM03+ " " + PM05 +" " +PM10+" " +PM25+" "+PM50+" " +PM100+" "+PMS10+" "+PMS25+" "+PMS100+" "); data.close(); }

}

boolean readPMSdata(Stream *s) {

if (! s->available()) { return false; } // Legge un byte alla volta fino ad arrivare allo speciale byte iniziale '0x42' if (s->peek() != 0x42) { s->read(); restituire falso; }

// Ora leggi tutti i 32 byte

if (s->available() readBytes(buffer, 32);

// prepara il checksum

for (uint8_t i=0; i<30; i++) { sum += buffer; }

/* debugging

for (uint8_t i=2; i<32; i++) { Serial.print("0x"); Serial.print(buffer, HEX); Serial.print(", "); } Serial.println(); */ // I dati arrivano in endian'd, questo li risolve in modo che funzioni su tutte le piattaforme uint16_t buffer_u16[15]; for (uint8_t i=0; i<15; i++) { buffer_u16 = buffer[2 + i*2 + 1]; buffer_u16 += (buffer[2 + i*2] << 8); }

// lo metto in una bella struttura:)

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

if (somma != data.checksum) {

Serial.println("Checksum fallito"); restituire falso; } // successo! restituire vero; }

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

String donne_jour_semaine(uint8_t j){ switch(j){ case 0: return "DIM"; caso 1: restituisce "LUN"; caso 2: restituire "MAR"; caso 3: restituire "MER"; caso 4: restituire "JEU"; caso 5: restituire "VEN"; caso 6: restituire "SAM"; predefinito: ritorno " "; } }

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

void affiche_date_heure(DateTime datetime){ // Date String jour = donne_jour_semaine(datetime.dayOfTheWeek()) + " " + Vers2Chiffres(datetime.day())+ "/" + Vers2Chiffres(datetime.month())+ "/" + String(datetime.year(), DEC); // heure String heure = ""; heure = Vers2Chiffres(datetime.hour())+ ":" + Vers2Chiffres(datetime.minute())+ ":" + Vers2Chiffres(datetime.second());

Serial.print(jour); Serial.print(" "); Serial.print(heure); //Serial.print(" "); File data=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("data ");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);

ritardo (500);

}

//permet d'afficher les nombres sur deux chiffres

String Vers2Chiffres(byte numero) { String risultato = ""; if(nombre < 10) risultato = "0"; return risultato += String(nombre, DEC); }

Passaggio 3: programma MIT App Inventor 2

Programma MIT App Inventor 2
Programma MIT App Inventor 2

questo è il blocco di codice dell'inventore dell'app del MIT

Fase 4: IL RISULTATO

ecco il video del risultato

Consigliato: