Πίνακας περιεχομένων:

Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων: 4 βήματα
Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων: 4 βήματα

Βίντεο: Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων: 4 βήματα

Βίντεο: Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων: 4 βήματα
Βίντεο: ΠΗΡΑ ενα κουτι ΠΡΟΦΥΛΑΚΤΙΚΑ…. 2024, Ιούνιος
Anonim
Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων
Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων
Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων
Σύστημα παρακολούθησης της ποιότητας του αέρα για ρύπανση σωματιδίων

ΕΙΣΑΓΩΓΗ:

1 Σε αυτό το έργο παρουσιάζω τον τρόπο δημιουργίας ανιχνευτή σωματιδίων με εμφάνιση δεδομένων, δημιουργία αντιγράφων ασφαλείας δεδομένων σε κάρτα SD και IOT. Οπτικά μια οθόνη δακτυλίου neopixels δείχνει την ποιότητα του αέρα.

2 Η ποιότητα του αέρα αποτελεί ολοένα και πιο σημαντική ανησυχία σήμερα. υπάρχουν συστήματα για τη μέτρηση του ρυθμού σκόνης αλλά είναι πολύ ακριβά. Υπάρχουν χαμηλού κόστους, υψηλής ποιότητας ανιχνευτές σωματιδίων στην αγορά, όπως φαίνεται από ορισμένες μελέτες.

για παράδειγμα:

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

3 Αποφάσισα λοιπόν να φτιάξω μια συσκευή ικανή να μετρήσει τον αριθμό των σωματιδίων ανά κατηγορίες μεγέθους (0,5μm έως 10μm), οπτικά με μια απλή απεικόνιση του αποτελέσματος (δακτύλιο neo pixel), μια πιο λεπτομερή οθόνη σε οθόνη TFT και αντίγραφο ασφαλείας με σφραγίδα χρόνου σε κάρτα SD.

4 Επιπλέον έχω προσθέσει μια μονάδα επικοινωνίας bluetooth για να μπορώ να επικοινωνώ με μια εφαρμογή android και έτσι να δημοσιεύω τα αποτελέσματα σε έναν διακομιστή IOT.

5 Το συνολικό κόστος του συνόλου δεν υπερβαίνει τα 60 €

Προμήθειες

-Arduino uno R3

-Αρντουνο πρωτό ασπίδα

-TFT οθόνη ST7735

-Δαχτυλίδι neopixel 24 led

-Plantower 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 // Bibliothèque pour l'I2C #include "RTClib.h" // Bibliothèque pour le module RTC RTC_DS1307 RTC; #περιλαμβάνω

// Ποια ακίδα στο Arduino είναι συνδεδεμένη με τα NeoPixels;

#define PIN 6 // Σε Trinket ή Gemma, προτείνετε να το αλλάξετε σε 1

// Πόσα NeoPixel είναι προσαρτημένα στο Arduino;

#define NUMPIXELS 24 // Δημοφιλές μέγεθος δακτυλίου NeoPixel Adafruit_NeoPixel pixel (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t vert = pixels. Color (0, 250, 0); uint32_t πορτοκαλί = εικονοστοιχεία. Χρώμα (250, 250, 0); uint32_t rouge = pixels. Color (255, 0, 0);

ΛογισμικόSerial pmsSerial (2, 3);

#define cs 10 #define dc 9 #define rst 8 // μπορείτε επίσης να το συνδέσετε στην επαναφορά του Arduino

#include // Βασική βιβλιοθήκη γραφικών

#include // Βιβλιοθήκη ειδική για υλικό #include #include const int cs_sd = 4; int temps? // temps d'acquisition double tempsInit; // initialisation du timer au démarrage du loop ()

#if καθορισμένα (_ SAM3X8E_)

#undef _FlashStringHelper:: F (string_literal) #define F (string_literal) string_literal #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); 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"); καθυστέρηση (1000)? εάν (! SD.begin (cs_sd)) // Συνθήκη που είναι κατανοητή ως εκ των προτέρων SD είναι προσιτή στις εφαρμογές {Serial.print ("Defaut SD"); ΕΠΙΣΤΡΟΦΗ; } Serial.print ("Carte SD OK");

Δεδομένα αρχείου = SD.open ("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"

data.println (""); data.println ("Απόκτηση Démarrage"); // Ecrit dans ce fichier data.close (); tft.initR (INITR_GREENTAB); // προετοιμάστε ένα τσιπ ST7735S, μαύρη καρτέλα Serial.println ("init"); // η έξοδος εντοπισμού σφαλμάτων tft.fillScreen (ST7735_BLACK); // ο ρυθμός baud του αισθητήρα είναι 9600 pmsSerial.begin (9600).

pixels.begin (); // INITIALIZE NeoPixel strip object (ΑΠΑΙΤΟΥΜΕΝΟ)

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 σωματιδια_03um, σωματιδια_05um, σωματιδια_10um, σωματιδια_25um, σωματιδια_50um, σωματιδια_100um? uint16_t αχρησιμοποίητο uint16_t checksum? };

Struct pms5003 δεδομένα δεδομένων. void loop () {pixels.clear (); // Ορίστε όλα τα χρώματα εικονοστοιχείων σε "απενεργοποίηση" DateTime now = RTC.now (); // Récupère l'heure et le date courante // 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 ("nbre μέρη/ 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 μέρη/ 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);

εάν ((nombre_leds = 1)) {

pixels.fill (vert, 0, nombre_leds); } else if ((nombre_leds = 8)) {pixels.fill (vert, 0, 8); pixels.fill (πορτοκαλί, 8, ((nombre_leds) -8)); } else if (nombre_leds> 16) {

pixels.fill (vert, 0, 8); pixels.fill (πορτοκαλί, 8, 8) pixels.fill (ρουζ, 16, ((nombre_leds) -16)); } else if (nombre_leds <= 1) {pixels.fill (vert, 0, 1); } pixels.show (); // Αποστολή των ενημερωμένων χρωμάτων pixel στο υλικό.

// Définition données 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); String PMS10 = String (data.pm10_standard); String PMS25 = String (data.pm25_standard); String PMS100 = String (data.pm100_standard); String Temps = String (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 (); }

}

boolean readPMSdata (Stream *s) {

εάν (! s-> διαθέσιμο ()) {return false? } // Διαβάζουμε ένα byte κάθε φορά μέχρι να φτάσουμε στην ειδική εκκίνηση byte '0x42' if (s-> peek ()! = 0x42) {s-> read (); επιστροφή ψευδής? }

// Τώρα διαβάστε και τα 32 byte

εάν (s-> διαθέσιμο () readBytes (buffer, 32)?

// ετοιμάστε το άθροισμα ελέγχου

για (uint8_t i = 0; i <30; i ++) {sum+= buffer ; }

/* εντοπισμός σφαλμάτων

για (uint8_t i = 2; i <32; i ++) {Serial.print ("0x"); Serial.print (buffer , HEX); Serial.print (","); } Serial.println (); */ // Τα δεδομένα έρχονται εν τέλει, αυτό το λύνει έτσι λειτουργεί σε όλες τις πλατφόρμες uint16_t buffer_u16 [15]? για (uint8_t i = 0; i <15; i ++) {buffer_u16 = buffer [2 + i*2 + 1]; buffer_u16 + = (buffer [2 + i*2] << 8); }

// βάλτε το σε μια ωραία δομή:)

memcpy ((άκυρο *) & δεδομένα, (άκυρο *) buffer_u16, 30);

εάν (άθροισμα! = data.checksum) {

Serial.println ("Αποτυχία αθροίσματος ελέγχου"); επιστροφή ψευδής? } // επιτυχία! επιστροφή αληθινός? }

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

String donne_jour_semaine (uint8_t j) {switch (j) {case 0: return "DIM"? περίπτωση 1: επιστροφή "LUN"? περίπτωση 2: επιστροφή "MAR". περίπτωση 3: επιστροφή "MER". περίπτωση 4: επιστροφή "JEU". περίπτωση 5: επιστροφή "VEN". περίπτωση 6: επιστροφή "SAM". προεπιλογή: επιστροφή ""; }}

// 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 (""); Δεδομένα αρχείου = 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 (byte nombre) {String resultat = ""; if (nombre <10) resultat = "0"; return resultat += String (nombre, DEC); }

Βήμα 3: Πρόγραμμα MIT App Inventor 2

Πρόγραμμα MIT App Inventor 2
Πρόγραμμα MIT App Inventor 2

αυτό είναι το μπλοκ κωδικών εφευρέτη της εφαρμογής MIT

Βήμα 4: ΤΟ ΑΠΟΤΕΛΕΣΜΑ

εδώ είναι το βίντεο του αποτελέσματος

Συνιστάται: