Sommario:
- Forniture
- Passaggio 1: collegamento dei componenti
- Passaggio 2: libreria e programma Arduino
- Passaggio 3: programma MIT App Inventor 2
- Fase 4: IL RISULTATO
Video: Sistema per il monitoraggio della qualità dell'aria per l'inquinamento da particolato: 4 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:01
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
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
questo è il blocco di codice dell'inventore dell'app del MIT
Fase 4: IL RISULTATO
ecco il video del risultato
Consigliato:
Semplice monitoraggio della qualità dell'aria con display LCD TFT - Ameba Arduino: 3 passaggi
Semplice monitoraggio della qualità dell'aria con display LCD TFT - Ameba Arduino: introduzione Ora che la maggior parte delle persone rimane a casa per evitare il contatto ravvicinato con il potenziale portatore del virus COVID-19, la qualità dell'aria diventa un fattore importante per il benessere delle persone, specialmente nei paesi tropicali dove l'uso dell'aria condizionata è un must durante il giorno
Monitoraggio della qualità dell'aria con DSM501A Con Nokia LCD: 7 passaggi
Monitoraggio della qualità dell'aria con DSM501A con LCD Nokia: Ciao amici! In questo breve tutorial ti mostrerò come monitorare la qualità dell'aria a casa tua o ovunque. È abbastanza facile assemblare questa stazione di monitoraggio della qualità dell'aria a un prezzo economico
Monitoraggio della qualità dell'aria utilizzando il fotone particellare: 11 passaggi (con immagini)
Monitoraggio della qualità dell'aria mediante fotone di particelle: in questo progetto il sensore di particelle PPD42NJ viene utilizzato per misurare la qualità dell'aria (PM 2,5) presente nell'aria con fotone di particelle. Non solo visualizza i dati su Particle console e dweet.io, ma indica anche la qualità dell'aria utilizzando il LED RGB modificandolo
AirCitizen - Monitoraggio della qualità dell'aria: 11 passaggi (con immagini)
AirCitizen - Monitoraggio della qualità dell'aria: Ciao a tutti! Oggi vi insegneremo come riprodurre il nostro progetto: AirCitizen del team AirCitizenPolytech!--Proveniente da 'OpenAir / What's your air?' Progetti, il progetto AirCitizen mira a consentire ai cittadini di valutare attivamente la qualità
Monitoraggio della qualità dell'aria alimentato a particelle: 7 passaggi
Monitoraggio della qualità dell'aria alimentato da particelle: qualità dell'aria. Probabilmente ci pensi di più ora che la nostra aria pulita si è trasformata in una foschia permanente nel cielo. Che schifo. Una cosa su cui hai il controllo è la qualità dell'aria all'interno della tua casa. In questo tutorial, ti mostrerò come costruire un'aria