תוכן עניינים:
- אספקה
- שלב 1: חיבור הרכיבים
- שלב 2: ספרייה ותוכנית Arduino
- שלב 3: תוכנית MIT App Inventor 2
- שלב 4: התוצאה
וִידֵאוֹ: מערכת לניטור איכות האוויר לזיהום חלקיקים: 4 שלבים
2024 מְחַבֵּר: John Day | [email protected]. שונה לאחרונה: 2024-01-30 09:14
הקדמה:
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
שלב 4: התוצאה
הנה הסרטון של התוצאה
מוּמלָץ:
תצוגת LED סטטוס איכות האוויר של PurpleAir: 4 שלבים
תצוגת LED סטטוס איכות האוויר של PurpleAir: עם השריפות האחרונות בקליפורניה, איכות האוויר בסן פרנסיסקו הושפעה מאוד. מצאנו את עצמנו בודקים את מפת PurpleAir שוב ושוב בטלפונים או במחשבים הניידים שלנו מנסים לראות מתי האוויר מספיק בטוח כדי לפתוח את הזכייה
חיישן איכות האוויר AEROBOT V1.0: 6 שלבים (עם תמונות)
חיישן איכות האוויר AEROBOT V1.0: מדריך זה עוסק בייצור חיישן איכות אוויר זול ומדויק ביותר בשם AEROBOT. פרויקט זה מציג טמפרטורה, לחות יחסית, צפיפות אבק PM 2.5 והתראות על איכות האוויר של הסביבה. הוא משתמש בחוש DHT11
עקוב אחר איכות האוויר באמצעות Grafana ו- Raspberry Pi: 7 שלבים
עקוב אחר איכות האוויר באמצעות גרפנה ופטל פי: חיפשתי פרויקט IOT קטן וחבר המליץ לי לבדוק את ההדרכה הזו: https: //dzone.com/articles/raspberry-pi-iot-sensor…I מאוד ממליץ לעקוב אחר ההדרכה להמשך בהגדרת פטל פטל לניטור
מדידת איכות האוויר: 17 שלבים
מדידת איכות האוויר: איכות האוויר וחלקיקים עדינים: החלקיקים המושעים (מסומנים "PM" ל"חלקיקים ") הם בדרך כלל החלקיקים המוצקים הדקים שנושאים על ידי האוויר (ויקיפדיה). חלקיקים עדינים חודרים עמוק לתוך הריאות. הם יכולים לגרום ב
הפלוגר: מכשיר לניטור פרמטר מזג האוויר: 6 שלבים
הפלוגר: מכשיר לניטור פרמטר מזג האוויר: מכשיר קטן ומחובר AUTONOMUS לניטור מספר משתנים שימושיים שיעזרו לך בגינון מכשיר זה מיועד למדידת פרמטרי מזג אוויר שונים: רצפת וטמפרטורת האוויר רצפת ולחות האוויר אור הצג אותו על