Sadržaj:
2025 Autor: John Day | [email protected]. Zadnja izmjena: 2025-01-13 06:57
INTRO:
1 U ovom projektu pokazujem kako izgraditi detektor čestica s prikazom podataka, sigurnosnom kopijom podataka na SD kartici i IOT -om. Vizuelno neopikselni prsten prikazuje kvalitet vazduha.
2 Kvaliteta zraka danas je sve važnija briga. postoje sistemi za mjerenje količine prašine, ali su vrlo skupi. Na tržištu postoje jeftini, visokokvalitetni detektori čestica, što pokazuju i neke studije.
na primjer:
www.atmos-meas-tech.net/11/4823/2018/amt-1…
3 Stoga sam odlučio izgraditi uređaj sposoban za mjerenje broja čestica po klasama veličine (0,5 μm do 10 µm), vizuelno sa jednostavnim prikazom rezultata (neo pikselni prsten), detaljnijim prikazom na TFT ekranu i sigurnosno kopiranje s oznakom vremena na SD kartici.
4 Osim toga, dodao sam bluetooth komunikacijski modul za komunikaciju s android aplikacijom i objavljivanje rezultata na IOT serveru.
5 Ukupni troškovi cjeline ne prelaze 60 €
Supplies
-Arduino uno R3
-Arduino proto štit
-TFT ekran ST7735
-Prsten od neopiksela 24 LED
-Plantower PMS5003
-HC-06 bluetooth modul
Korak 1: Povezivanje komponenti
različite komponente su povezane prema gornjem dijagramu
Korak 2: Biblioteka i Arduino program
1 biblioteka
za TFT ekran
github.com/adafruit/Adafruit-GFX-Library
za prsten neo piksela
github.com/adafruit/Adafruit_NeoPixel
za sd karticu
github.com/arduino-libraries/SD
2 arduino skica
#include #include // Biblioteka za l'I2C #include "RTClib.h" // Biblioteka za modul RTC RTC_DS1307 RTC; #include
// Koji je pin na Arduinu spojen na NeoPixels?
#define PIN 6 // Na Trinket ili Gemma predložite promjenu na 1
// Koliko je NeoPixela priključeno na Arduino?
#define NUMPIXELS 24 // Popularni NeoPixel prsten veličine Adafruit_NeoPixel piksela (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t vert = pixels. Color (0, 250, 0); uint32_t narančasta = pikseli. Boja (250, 250, 0); uint32_t rouge = pikseli. Boja (255, 0, 0);
SoftwareSerial pmsSerial (2, 3);
#define cs 10 #define dc 9 #define rst 8 // ovo možete spojiti i na Arduino reset
#include // Osnovna biblioteka grafike
#include // Biblioteka specifična za hardver #include #include const int cs_sd = 4; int temps; // temps d'acquisition double tempsInit; // inicijalizacija tajmera ili demarrage du loop ()
#if definirano (_ SAM3X8E_)
#undef _FlashStringHelper:: F (string_literal) #define F (string_literal) string_literal #endif
// Opcija 1: koristite sve pinove, ali malo sporije
// Adafruit_ST7735 tft = Adafruit_ST7735 (cs, dc, mosi, sclk, rst);
// Opcija 2: morate koristiti hardverske SPI pinove
// (za UNO to je sclk = 13 i sid = 11) i pin 10 mora biti // izlaz. Ovo je mnogo brže - potrebno je i ako želite // koristiti microSD karticu (pogledajte primjer crteža slike) Adafruit_ST7735 tft = Adafruit_ST7735 (cs, dc, rst); float nombre_leds = 0; void setup () {Serial.begin (9600); // Pokrećemo vezu I2C Wire.begin (); // Pokretanje modula RTC RTC.begin (); Serial.print ("init SD"); kašnjenje (1000); if (! SD.begin (cs_sd)) // Uslov za provjeru SD -a la carte SD est présente dans l'appareil {Serial.print ("Zadana SD"); return; } Serial.print ("Carte SD OK");
Podaci datoteke = SD.open ("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"
data.println (""); data.println ("Démarrage sticanje"); // Ecrit dans ce fichier data.close (); tft.initR (INITR_GREENTAB); // inicijalizira čip ST7735S, crna kartica Serial.println ("init"); // naš izlaz za otklanjanje grešaka tft.fillScreen (ST7735_BLACK); // brzina prijenosa senzora je 9600 pmsSerial.begin (9600);
pixels.begin (); // INICIALIZE NeoPixel strip objekt (OBAVEZNO)
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 čestice_03um, čestice_05um, čestice_10um, čestice_25um, čestice_50um, čestice_100um; uint16_t unused; uint16_t kontrolni zbroj; };
struct pms5003data data; void loop () {pikseli.clear (); // Postavi sve boje piksela na 'off' DateTime sada = RTC.now (); // Récupère l'heure et le date courante // affiche_date_heure (sada);
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 dijelovi/ 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 ("PM 1.0"); mikrog/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 ("mikrog/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 ("mikrog/m3");
tft.setCursor (10, 5);
tft.setTextColor (ST7735_WHITE, ST7735_BLACK); tft.setTextSize (1); tft.println ("nbre dijelovi/ 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 (narančasta, 8, ((nombre_leds) -8)); } else if (nombre_leds> 16) {
pixels.fill (vert, 0, 8); pixels.fill (narančasta, 8, 8); pixels.fill (rouge, 16, ((nombre_leds) -16)); } else if (nombre_leds <= 1) {pixels.fill (vert, 0, 1); } piksela.show (); // Pošaljite ažurirane boje piksela na hardver.
// Donja definicija String PM03 = String (data.particles_03um); Niz PM05 = Niz (data.particles_05um); Niz PM10 = Niz (data.particles_10um); Niz PM25 = Niz (data.particles_25um); Niz PM50 = Niz (data.particles_50um); Niz PM100 = Niz (data.particles_100um); Niz PMS10 = Niz (data.pm10_standard); Niz PMS25 = Niz (data.pm25_standard); Niz PMS100 = Niz (data.pm100_standard); String Temps = String (temps);
// Ecriture des données dans le fichier texte
Podaci datoteke = 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; } // Čitamo po jedan bajt dok ne dođemo do posebnog '0x42' početnog bajta if (s-> peek ()! = 0x42) {s-> read (); return false; }
// Sada pročitajte svih 32 bajta
if (s-> dostupan () readBytes (bafer, 32);
// pripremite kontrolni zbroj
for (uint8_t i = 0; i <30; i ++) {zbir+= bafer ; }
/* otklanjanje grešaka
for (uint8_t i = 2; i <32; i ++) {Serial.print ("0x"); Serial.print (bafer , HEX); Serial.print (","); } Serial.println (); */ // Podaci dolaze u endian'd -u, ovo ih rješava pa radi na svim platformama uint16_t buffer_u16 [15]; for (uint8_t i = 0; i <15; i ++) {buffer_u16 = bafer [2 + i*2 + 1]; bafer_u16 + = (bafer [2 + i*2] << 8); }
// stavi u lijepu strukturu:)
memcpy ((void *) & data, (void *) buffer_u16, 30);
if (zbir! = data.checksum) {
Serial.println ("Pogreška kontrolne sume"); return false; } // uspjeh! return true; }
// Pretvorite numéro de jour en jour /! / La semaine begin un dimanche
String donne_jour_semaine (uint8_t j) {switch (j) {case 0: return "DIM"; slučaj 1: povratak "LUN"; slučaj 2: povratak "MAR"; slučaj 3: vraćanje "MER"; slučaj 4: vratite "JEU"; slučaj 5: povratak "VEN"; slučaj 6: vrati "SAM"; default: return ""; }}
// affiche la date et l'heure sur l'écran
void affiche_date_heure (DateTime datetime) {// Datum niza 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 (""); Podaci datoteke = 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 ("datum"); 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);
kašnjenje (500);
}
// permet d'afficher les nombres sur deux chiffres
String Vers2Chiffres (broj bajtova) {String resultat = ""; if (nombre <10) resultat = "0"; return rezultat += String (nombre, DEC); }
Korak 3: Program MIT App Inventor 2
ovo je blok koda izumitelja aplikacije MIT
Korak 4: REZULTAT
evo video snimka rezultata