Sadržaj:
2025 Autor: John Day | [email protected]. Zadnja promjena: 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. Vizualno neopikselni prsten prikazuje kvalitetu zraka.
2 Kvaliteta zraka danas je sve važnija briga. postoje sustavi 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čina (0,5 μm do 10 µm), vizualno s jednostavnim prikazom rezultata (neo pikselni prsten), detaljnijim prikazom na TFT ekranu i sigurnosno kopiranje s vremenskom oznakom na SD kartici.
4 Osim toga, dodao sam bluetooth komunikacijski modul za komunikaciju s android aplikacijom i objavljivanje rezultata na IOT poslužitelju.
5 Ukupni trošak cjeline ne prelazi 60 €
Pribor
-Arduino uno R3
-Arduino proto štit
-TFT ekran ST7735
-Prsten od neopiksela 24 led
-Plantower PMS5003
-HC-06 bluetooth modul
Korak 1: Spajanje komponenti
različite komponente su spojene prema gornjem dijagramu
Korak 2: Knjižnica i Arduino program
1 knjižnica
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 // Bibliothèque pour l'I2C #include "RTClib.h" // Bibliothèque pour le module RTC RTC_DS1307 RTC; #uključi
// Koji je pin na Arduinu spojen na NeoPixels?
#define PIN 6 // Na Trinket -u ili Gemmi 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 = pikseli. Boja (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 // Knjižnica specifična za hardver #include #include const int cs_sd = 4; int temps; // temps d'acquisition dvostruki tempsInit; // inicijalizacija du timer au démarrage du loop ()
#if definirano (_ SAM3X8E_)
#undef _FlashStringHelper:: F (string_literal) #define F (string_literal) string_literal #endif
// Opcija 1: upotrijebite bilo koje 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 - također je potrebno 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); // Pokretanje veze I2C Wire.begin (); // Pokretanje modula RTC RTC.begin (); Serial.print ("init SD"); kašnjenje (1000); if (! SD.begin (cs_sd)) // Condition vérifiant si la carte SD est présente dans l'appareil {Serial.print ("Zadani SD"); povratak; } Serial.print ("Carte SD OK");
Podaci datoteke = SD.open ("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"
data.println (""); data.println ("Démarrage stjecanje"); // Ecrit dans ce fichier data.close (); tft.initR (INITR_GREENTAB); // inicijalizirati čip ST7735S, crna kartica Serial.println ("init"); // naš izlaz za ispravljanje pogrešaka tft.fillScreen (ST7735_BLACK); // brzina prijenosa senzora je 9600 pmsSerial.begin (9600);
pikseli.begin (); // INICIALIZE NeoPixel strip objekt (OBAVEZNO)
piksela.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 neiskorišteno; uint16_t kontrolni zbroj; };
struct pms5003podaci podataka; void loop () {pikseli.clear (); // Postavi sve boje piksela na 'isključeno' 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"); Serijski.ispis (data.particles_03um); Serial.print (""); Serial.print ("05µm"); Serijski.ispis (data.particles_05um); Serial.print (""); Serial.print ("1µm"); Serijski.ispis (data.particles_10um); Serial.print (""); Serial.print ("25µm"); Serijski.ispis (data.particles_25um); Serial.print (""); Serial.print ("50µm"); Serijski.ispis (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); pikseli.fill (narančasto, 8, ((nombre_leds) -8)); } else if (nombre_leds> 16) {
pikseli.fill (vert, 0, 8); pikseli.fill (narančasta, 8, 8); pikseli.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.
// Definicija ne sadrži 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; } // Čitajte po jedan bajt dok ne dođemo do posebnog početnog bajta '0x42' if (s-> peek ()! = 0x42) {s-> read (); return false; }
// Sada pročitajte svih 32 bajta
if (s-> dostupan () readBytes (međuspremnik, 32);
// pripremiti kontrolni zbroj
za (uint8_t i = 0; i <30; i ++) {zbroj+= međuspremnik ; }
/* ispravljanje pogrešaka
for (uint8_t i = 2; i <32; i ++) {Serial.print ("0x"); Serijski ispis (međuspremnik , 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]; za (uint8_t i = 0; i <15; i ++) {buffer_u16 = međuspremnik [2 + i*2 + 1]; bafer_u16 + = (međuspremnik [2 + i*2] << 8); }
// stavi u lijepu strukturu:)
memcpy ((void *) & data, (void *) buffer_u16, 30);
if (zbroj! = data.checksum) {
Serial.println ("Pogreška kontrolne sume"); return false; } // uspjeh! return true; }
// Converti le 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: povratak "MER"; slučaj 4: vratiti "JEU"; slučaj 5: povratak "VEN"; slučaj 6: vratiti "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 ()) + "/" + Niz (datetime.year (), DEC); // heure String heure = ""; heure = Vers2Chiffres (datetime.hour ()) + ":" + Vers2Chiffres (datetime.minute ()) + ":" + Vers2Chiffres (datetime.second ());
Serijski.ispis (jour); Serial.print (""); Serijski.ispis (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
Niz Vers2Chiffres (broj bajtova) {String resultat = ""; if (nombre <10) resultat = "0"; povratni rezultat += niz (nombre, DEC); }
Korak 3: Program MIT App Inventor 2
ovo je blok koda izumitelja aplikacije MIT
Korak 4: REZULTAT
evo video rezultata