תוכן עניינים:

מערכת לניטור איכות האוויר לזיהום חלקיקים: 4 שלבים
מערכת לניטור איכות האוויר לזיהום חלקיקים: 4 שלבים

וִידֵאוֹ: מערכת לניטור איכות האוויר לזיהום חלקיקים: 4 שלבים

וִידֵאוֹ: מערכת לניטור איכות האוויר לזיהום חלקיקים: 4 שלבים
וִידֵאוֹ: יום כדור הארץ - קהילת הוריזון 2024, נוֹבֶמבֶּר
Anonim
מערכת לניטור איכות האוויר לזיהום חלקיקים
מערכת לניטור איכות האוויר לזיהום חלקיקים
מערכת לניטור איכות האוויר לזיהום חלקיקים
מערכת לניטור איכות האוויר לזיהום חלקיקים

הקדמה:

1 בפרויקט זה אני מראה כיצד בונים גלאי חלקיקים עם תצוגת נתונים, גיבוי נתונים בכרטיס SD ו- IOT. מבחינה ויזואלית תצוגת טבעת של neopixels מציינת את איכות האוויר.

2 איכות האוויר מהווה דאגה חשובה יותר ויותר כיום. ישנן מערכות למדידת קצב האבק אך הן יקרות מאוד. קיימים בשוק גלאי חלקיקים בעלות נמוכה ואיכותית, כפי שמראים כמה מחקרים.

לדוגמה:

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

3 לכן החלטתי לבנות מכשיר המסוגל למדוד את מספר החלקיקים לפי כיתות גודל (0.5 מיקרון עד 10 מיקרון), ויזואלית עם תצוגה פשוטה של התוצאה (טבעת ניאו פיקסל), תצוגה מפורטת יותר על מסך TFT ו גיבוי עם חותמת זמן בכרטיס SD.

4 בנוסף הוספתי מודול תקשורת בלוטות 'כדי להיות מסוגל לתקשר עם אפליקציית אנדרואיד ובכך לפרסם את התוצאות בשרת IOT.

5 העלות הכוללת של המכלול אינה עולה על 60 €

אספקה

-ארדואינו אונו R3

-מגן פרוטו ארדואינו

-מסך TFT ST7735

-טבעת ניאופיקסל 24 לד

-שתילה PMS5003

-מודול בלוטות 'HC-06

שלב 1: חיבור הרכיבים

חיבור הרכיבים
חיבור הרכיבים

הרכיבים השונים מחוברים על פי התרשים לעיל

שלב 2: ספרייה ותוכנית Arduino

1 הספרייה

למסך TFT

github.com/adafruit/Adafruit-GFX-Library

עבור טבעת הניאו פיקסל

github.com/adafruit/Adafruit_NeoPixel

לכרטיס sd

github.com/arduino-libraries/SD

2 מערכון הארדואינו

#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

// כמה 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 d'acquisition tempsInit; // אתחול du timer au démarrage du loop ()

#אם מוגדר (_ 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 () {Serial.begin (9600); // התחל את הקשר I2C Wire.begin (); // אתחל את המודול RTC RTC.begin (); Serial.print ("init SD"); עיכוב (1000); if (! SD.begin (cs_sd)) // Condition vérifiant si la carte SD est présente dans l'appareil {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); // קצב שידור החיישן הוא 9600 pmsSerial.begin (9600);

פיקסלים.התחל (); // התחל אובייקט רצועה NeoPixel (חובה)

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 בדיקת סכום; };

struct pms5003 נתוני נתונים; לולאת void () {pixels.clear (); // הגדר את כל צבעי הפיקסלים ל- 'off' DateTime עכשיו = 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 ליטר");

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 (" מיקרוגרם/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 ("מיקרוגרם/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 ("מיקרוגרם/m3");

tft.setCursor (10, 5);

tft.setTextColor (ST7735_WHITE, ST7735_BLACK); tft.setTextSize (1); tft.println ("חלקים nbre/ 0.1 ליטר");

// Serial.print (זמני);

// 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);

אם ((nombre_leds = 1)) {

פיקסלים.מילוי (vert, 0, nombre_leds); } אחרת אם ((nombre_leds = 8)) {pixels.fill (vert, 0, 8); פיקסלים.מילוי (כתום, 8, ((nombre_leds) -8)); } אחר אם (nombre_leds> 16) {

פיקסלים.מילוי (vert, 0, 8); פיקסלים.מילוי (כתום, 8, 8); פיקסלים.מילוי (אדום, 16, ((nombre_leds) -16)); } אחרת אם (nombre_leds <= 1) {pixels.fill (vert, 0, 1); } פיקסלים.הצג (); // שלח את צבעי הפיקסלים המעודכנים לחומרה.

// Définition données מחרוזת PM03 = מחרוזת (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); זמני מחרוזת = מחרוזת (זמניות);

// Ecriture des données dans le fichier texte

נתוני קובץ = SD.open ("donnees.txt", FILE_WRITE); data.println (זמני+""+PM03+""+PM05+""+PM10+""+PM25+""+PM50+""+PM100+""+PMS10+""+PMS25+""+PMS100+""); data.close (); }

}

קריאה בוליאנית PMSdata (זרמים *) {

אם (! s-> זמין ()) {return false; } // קראו כל פעם בתים עד שנגיע לבייל-בתים ההתחלתי המיוחד '0x42' אם (s-> הצצה ()! = 0x42) {s-> קריאה (); להחזיר שקר; }

// קראו כעת את כל 32 הבייטים

אם (s-> זמין () readBytes (מאגר, 32);

// הכינו את סכום הביקורת

עבור (uint8_t i = 0; i <30; i ++) {sum+= buffer ; }

/* איתור באגים

עבור (uint8_t i = 2; i <32; i ++) {Serial.print ("0x"); Serial.print (חיץ , HEX); Serial.print (","); } Serial.println (); */ // הנתונים מגיעים endian'd, זה פותר אותם כך שהם עובדים על כל הפלטפורמות 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 ((void *) & data, (void *) buffer_u16, 30);

אם (סכום! = data.checksum) {

Serial.println ("כשל בסיכום צ'קים"); להחזיר שקר; } // הצלחה! להחזיר נכון; }

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

מחרוזת 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 ()) + "/" + מחרוזת (datetime.year (), DEC); // heure מחרוזת 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

מחרוזת Vers2Chiffres (נייט בתים) {תוצאות מחרוזת = ""; if (nombre <10) resultat = "0"; תוצאות החזרה += מחרוזת (nombre, DEC); }

שלב 3: תוכנית MIT App Inventor 2

תוכנית MIT App Inventor 2
תוכנית MIT App Inventor 2

זהו בלוק קוד הממציא של אפליקציית MIT

שלב 4: התוצאה

הנה הסרטון של התוצאה

מוּמלָץ: