Table des matières:
- Fournitures
- Étape 1: connexion des composants
- Étape 2: Bibliothèque et programme Arduino
- Étape 3: programme MIT App Inventor 2
- Étape 4: LE RÉSULTAT
Vidéo: Système de surveillance de la qualité de l'air pour la pollution par les particules : 4 étapes
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:06
INTRO:
1 Dans ce projet, je montre comment construire un détecteur de particules avec affichage des données, sauvegarde des données sur carte SD et IOT. Visuellement, un affichage annulaire en néopixels indique la qualité de l'air.
2 La qualité de l'air est aujourd'hui une préoccupation de plus en plus importante. il existe des systèmes pour mesurer le taux de poussière mais ils sont très coûteux. Il existe sur le marché des détecteurs de particules bon marché et de haute qualité, comme le montrent certaines études.
par exemple:
www.atmos-meas-tech.net/11/4823/2018/amt-1…
3 J'ai donc décidé de construire un appareil capable de mesurer le nombre de particules par classes de taille (0,5µm à 10 µm), visuellement avec un simple affichage du résultat (néo pixel ring), un affichage plus détaillé sur un écran TFT et un sauvegarde horodatée sur une carte SD.
4 De plus j'ai ajouté un module de communication bluetooth pour pouvoir communiquer avec une application android et ainsi publier les résultats sur un serveur IOT.
5 Le coût global de l'ensemble ne dépasse pas 60 €
Fournitures
-Arduino uno R3
-Bouclier proto Arduino
-Écran TFT ST7735
-Anneau néopixel 24 led
-Plantower PMS5003
-Module bluetooth HC-06
Étape 1: connexion des composants
les différents composants sont connectés selon le schéma ci-dessus
Étape 2: Bibliothèque et programme Arduino
1 la bibliothèque
pour l'écran TFT
github.com/adafruit/Adafruit-GFX-Library
pour la bague neo pixel
github.com/adafruit/Adafruit_NeoPixel
pour la carte sd
github.com/arduino-libraries/SD
2 le croquis arduino
#include #include // Bibliothèque pour l'I2C #include "RTClib.h" // Bibliothèque pour le module RTC RTC_DS1307 RTC; #comprendre
// Quelle broche de l'Arduino est connectée aux NeoPixels ?
#define PIN 6 // Sur Trinket ou Gemma, suggérez de le changer en 1
// Combien de NeoPixels sont attachés à l'Arduino ?
#define NUMPIXELS 24 // Taille de bague NeoPixel populaire Adafruit_NeoPixel pixels (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t vert = pixels. Couleur (0, 250, 0); uint32_t orange = pixels. Couleur (250, 250, 0); uint32_t rouge = pixels. Couleur(255, 0, 0);
LogicielSérie pmsSerial(2, 3);
#define cs 10 #define dc 9 #define rst 8 // vous pouvez également le connecter à la réinitialisation Arduino
#include // Bibliothèque graphique principale
#include // Bibliothèque spécifique au matériel #include #include const int cs_sd=4; int temps; // temps d'acquisition double tempsInit; // initialisation du timer au démarrage de la boucle()
#si défini(_SAM3X8E_)
#undef _FlashStringHelper::F(string_literal) #define F(string_literal) string_literal #endif
// Option 1: utiliser n'importe quelle broche mais un peu plus lentement
//Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);
// Option 2: doit utiliser les broches SPI matérielles
// (pour UNO c'est sclk = 13 et sid = 11) et la broche 10 doit être // une sortie. C'est beaucoup plus rapide - également requis si vous souhaitez // utiliser la carte microSD (voir l'exemple de dessin de l'image) Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); float nombre_leds=0; void setup() { Serial.begin(9600); // Initialise la liaison I2C Wire.begin(); // Initialise le module RTC RTC.begin(); Serial.print("init SD"); retard(1000); if(!SD.begin(cs_sd)) //Condition vérifiant si la carte SD est présente dans l'appareil { Serial.print("Defaut SD"); revenir; } Serial.print("Carte SD OK");
Données du fichier = SD.open("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"
data.println(""); data.println("Démarrage acquisition"); // Ecrit dans ce fichier data.close(); tft.initR(INITR_GREENTAB); // initialise une puce ST7735S, onglet noir Serial.println("init"); // notre sortie de débogage tft.fillScreen(ST7735_BLACK); // le débit en bauds du capteur est de 9600 pmsSerial.begin(9600);
pixels.begin(); // INITIALISER l'objet bande NeoPixel (OBLIGATOIRE)
pixels.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 particules_03um, particules_05um, particules_10um, particules_25um, particules_50um, particules_100um; uint16_t inutilisé; somme de contrôle uint16_t; };
struct pms5003data data; boucle vide() { pixels.clear(); // Définit toutes les couleurs de pixels sur 'off' DateTime now=RTC.now(); //Récupère l'heure et la 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 pièces/ 0,1 l");
tft.setCursor(10, 17); tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.setCursor (10, 17); tft.print("0.3 um ");tft.print(data.particles_03um);tft.print(" ");
tft.setCursor(10, 29);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("0,5 um ");tft.print(data.particles_05um);tft.print(" ");
tft.setCursor (10, 41);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("1.0 um ");tft.print(data.particles_10um);tft.print(" ");
tft.setCursor (10, 53);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("2,5 um ");tft.print(data.particles_25um);tft.print(" ");
tft.setCursor(10, 65);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("5.0 um ");tft.print(data.particles_50um);tft.print(" ");
tft.setCursor (10, 77);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("10 um ");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 pièces/ 0,1 l");
// Serial.print(temps);
// Serial.print (" "); Serial.print ("#"); Impression.série ("03µm "); Serial.print(data.particles_03um); Serial.print (" "); Impression.série ("05µm "); Serial.print(data.particles_05um); Serial.print (" "); Serial.print ("1µm "); Serial.print(data.particles_10um); Serial.print (" "); Impression.série ("25µm "); Serial.print(data.particles_25um); Serial.print (" "); Impression.série ("50µm "); Serial.print(data.particles_50um); Serial.print (" "); Impression.série ("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);
si ((nombre_leds=1)){
pixels.fill(vert, 0, nombre_leds); } else if ((nombre_leds=8)) { pixels.fill(vert, 0, 8); pixels.fill(orange, 8, ((nombre_leds)-8)); } else if (nombre_leds>16) {
pixels.fill(vert, 0, 8); pixels.fill(orange, 8, 8); pixels.fill(rouge, 16, ((nombre_leds)-16)); } else if (nombre_leds<=1) { pixels.fill(vert, 0, 1); } pixels.show(); // Envoie les couleurs de pixels mises à jour au matériel.
// Définition des données String PM03=String(data.particles_03um); Chaîne PM05=Chaîne(data.particles_05um); Chaîne PM10=Chaîne(data.particles_10um); Chaîne PM25=Chaîne(data.particles_25um); Chaîne PM50=Chaîne(data.particles_50um); Chaîne PM100=Chaîne(data.particles_100um); Chaîne PMS10=Chaîne(data.pm10_standard); Chaîne PMS25=Chaîne(data.pm25_standard); Chaîne PMS100=Chaîne(data.pm100_standard); Chaîne Temps=Chaîne(temps);
//Ecriture des données dans le fichier texte
Données de fichier=SD.open("donnees.txt", FILE_WRITE); data.println(Temps + " " + PM03+ " " + PM05 +" " +PM10+" " +PM25+" "+PM50+" " +PM100+" "+PMS10+" "+PMS25+" "+PMS100+" "); data.close(); }
}
booléen readPMSdata(Stream *s) {
if (! s->available()) { return false; } // Lire un octet à la fois jusqu'à ce que nous arrivions à l'octet de début spécial '0x42' if (s->peek() != 0x42) { s->read(); renvoie faux; }
// Maintenant, lisez les 32 octets
if (s->available() readBytes(buffer, 32);
// prépare la somme de contrôle
for (uint8_t i=0; i<30; i++) { sum += buffer; }
/* débogage
pour (uint8_t i=2; i<32; i++) { Serial.print("0x"); Serial.print(tampon, HEX); Serial.print(", "); } Serial.println(); */ // Les données sont en endian, cela résout le problème afin que cela fonctionne sur toutes les plates-formes uint16_t buffer_u16[15]; pour (uint8_t i=0; i<15; i++) { buffer_u16 = buffer[2 + i*2 + 1]; buffer_u16 += (buffer[2 + i*2] << 8); }
// le mettre dans une belle structure:)
memcpy((void *)&data, (void *)buffer_u16, 30);
if (somme != data.checksum) {
Serial.println("échec de la somme de contrôle"); renvoie faux; } // Succès! renvoie vrai; }
//Converti le numéro de jour en jour /!\ la semaine commence un dimanche
String donne_jour_semaine(uint8_t j){ switch(j){ case 0: renvoie "DIM"; cas 1: retour « LUN »; cas 2: retour « MAR »; cas 3: retour « MER »; cas 4: retour « JEU »; cas 5: retour « VEN »; cas 6: retour « SAM »; par défaut: return " "; } }
// affiche la date et l'heure sur l'écran
void affiche_date_heure(DateTime datetime){ // Chaîne de date jour = donne_jour_semaine(datetime.dayOfTheWeek()) + " " + Vers2Chiffres(datetime.day())+ "/" + Vers2Chiffres(datetime.month())+ "/" + Chaîne(dateheure.année(), DEC); // heure String heure = ""; heure = Vers2Chiffres(dateheure.heure())+ ":" + Vers2Chiffres(dateheure.minute())+ ":" + Vers2Chiffres(dateheure.seconde());
Serial.print(jour); Serial.print(" "); Serial.print(heure); //Série.print(" "); Données de fichier=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("date ");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);
retard (500);
}
//permet d'afficher les nombres sur deux chiffres
String Vers2Chiffres(byte nombre) { String resultat = ""; if(nombre < 10) resultat = "0"; return resultat += String(nombre, DEC); }
Étape 3: programme MIT App Inventor 2
c'est le bloc de code de l'inventeur de l'application MIT
Étape 4: LE RÉSULTAT
voici la vidéo du résultat
Conseillé:
Surveillance simple de la qualité de l'air avec écran LCD TFT - Ameba Arduino : 3 étapes
Surveillance simple de la qualité de l'air avec écran LCD TFT - Ameba Arduino : Introduction Maintenant que la plupart des gens restent à la maison pour éviter tout contact étroit avec un porteur potentiel du virus COVID-19, la qualité de l'air devient un facteur important pour le bien-être des gens, en particulier dans les pays tropicaux où l'utilisation de l'air conditionné est un must pendant la journée
Surveillance de la qualité de l'air avec DSM501A et Nokia LCD : 7 étapes
Surveillance de la qualité de l'air avec DSM501A avec Nokia LCD : Bonjour les amis ! Dans ce court instructable, je vais vous montrer comment surveiller la qualité de l'air chez vous ou n'importe où
Surveillance de la qualité de l'air à l'aide de photons de particules : 11 étapes (avec photos)
Surveillance de la qualité de l'air à l'aide de photons de particules : Dans ce projet, le capteur de particules PPD42NJ est utilisé pour mesurer la qualité de l'air (PM 2,5) présente dans l'air avec des photons de particules. Il affiche non seulement les données sur Particle console et dweet.io, mais indique également la qualité de l'air à l'aide de LED RVB en la modifiant
AirCitizen - Surveillance de la qualité de l'air : 11 étapes (avec photos)
AirCitizen - Surveillance de la qualité de l'air : Bonjour à tous ! Aujourd'hui, nous allons vous apprendre à reproduire notre projet : AirCitizen par l'équipe AirCitizenPolytech !--Issu de l'OpenAir / What's your air? Projets, le projet AirCitizen vise à permettre aux citoyens d'évaluer activement la qualité
Moniteur de qualité de l'air alimenté par particules : 7 étapes
Moniteur de qualité de l'air alimenté par les particules : qualité de l'air. Vous y pensez probablement davantage maintenant que notre air pur s'est transformé en une brume permanente dans le ciel. Beurk. Une chose sur laquelle vous avez le contrôle est la qualité de l'air à l'intérieur de votre maison. Dans ce tutoriel, je vais vous montrer comment construire un air