İçindekiler:
2025 Yazar: John Day | [email protected]. Son düzenleme: 2025-01-13 06:58
GİRİŞ:
1 Bu projede veri görüntüleme, SD kartta veri yedekleme ve IOT ile bir partikül dedektörünün nasıl oluşturulacağını gösteriyorum. Görsel olarak bir neopiksel halka ekranı hava kalitesini gösterir.
2 Hava kalitesi günümüzde giderek daha önemli bir sorun haline geliyor. toz oranını ölçen sistemler var ama çok pahalılar. Bazı çalışmaların gösterdiği gibi piyasada düşük maliyetli, yüksek kaliteli partikül dedektörleri bulunmaktadır.
Örneğin:
www.atmos-meas-tech.net/11/4823/2018/amt-1…
3 Bu nedenle, partikül sayısını boyut sınıflarına göre (0,5 µm ila 10 µm), görsel olarak sonucun basit bir gösterimi (neo piksel halkası), bir TFT ekranda daha ayrıntılı bir görüntü ve bir SD kartta zaman damgalı yedekleme.
4 Ayrıca bir android uygulama ile haberleşebilmek ve sonuçları bir IOT sunucusunda yayınlayabilmek için bir bluetooth iletişim modülü ekledim.
5 Bütünün toplam maliyeti 60 €'yu geçmez
Gereçler
-Arduino uno R3
-Arduino proto kalkanı
-TFT ekran ST7735
-Neopiksel halka 24 led
-Plantower PMS5003
-HC-06 bluetooth modülü
Adım 1: Bileşenleri Bağlama
farklı bileşenler yukarıdaki şemaya göre bağlanır
Adım 2: Kütüphane ve Arduino Programı
1 kütüphane
TFT ekran için
github.com/adafruit/Adafruit-GFX-Library
neo piksel halkası için
github.com/adafruit/Adafruit_NeoPixel
sd kart için
github.com/arduino-libraries/SD
2 arduino taslağı
#include #include // Bibliothèque pour l'I2C #include "RTClib.h" // Bibliothèque döküm modülü RTC RTC_DS1307 RTC; #Dahil etmek
// Arduino'daki hangi pin NeoPixels'e bağlı?
#define PIN 6 // Biblo veya Gemma'da bunu 1 olarak değiştirmenizi öneririz
// Arduino'ya kaç NeoPiksel bağlı?
#define NUMPIXELS 24 // Popüler NeoPixel halka boyutu Adafruit_NeoPixel piksel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t dikey = piksel. Color(0, 250, 0); uint32_t turuncu = piksel. Color(250, 250, 0); uint32_t allık = piksel. Renk(255, 0, 0);
YazılımSeri pmsSeri(2, 3);
#define cs 10 #define dc 9 #define rst 8 // Bunu Arduino sıfırlamasına da bağlayabilirsiniz
#include // Temel grafik kitaplığı
#include // Donanıma özel kitaplık #include #include const int cs_sd=4; int temps; // temps d'acquisition double tempsInit; // başlatma du timer au démarrage du loop()
#if tanımlı(_SAM3X8E_)
#undef _FlashStringHelper::F(string_literal) #define F(string_literal) string_literal #endif
// Seçenek 1: herhangi bir pin kullanın ama biraz daha yavaş
//Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);
// Seçenek 2: donanım SPI pinlerini kullanmalıdır
// (UNO için sclk = 13 ve sid = 11) ve pin 10 // çıkış olmalıdır. Bu çok daha hızlıdır - ayrıca microSD kartı kullanmak istiyorsanız // gereklidir (resim çizim örneğine bakın) Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); float nombre_leds=0; geçersiz kurulum() { Serial.begin(9600); // Bağlantıyı başlat I2C Wire.begin(); // RTC modülünü başlat RTC.begin(); Serial.print("SD'yi başlat"); gecikme(1000); if(!SD.begin(cs_sd)) //Durum geçerli si la carte SD est présente dans l'appareil { Serial.print("Defaut SD"); dönüş; } Serial.print("Kart SD Tamam");
Dosya verisi = SD.open("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"
data.println(""); data.println("Démarrage edinimi"); // Ecrit dans ce fichier data.close(); tft.initR(INITR_GREENTAB); // bir ST7735S çipini başlat, siyah sekme Serial.println("init"); // hata ayıklama çıktımız tft.fillScreen(ST7735_BLACK); // sensör baud hızı 9600 pmsSerial.begin(9600);
piksel.begin(); // NeoPixel şerit nesnesini BAŞLATIN (GEREKLİ)
piksel.setBrightness(2);
}
yapı pms5003veri {
uint16_t çerçeve; uint16_t pm10_standard, pm25_standard, pm100_standard; uint16_t pm10_env, pm25_env, pm100_env; uint16_t parçacıklar_03um, parçacıklar_05um, parçacıklar_10um, parçacıklar_25um, parçacıklar_50um, parçacıklar_100um; uint16_t kullanılmayan; uint16_t sağlama toplamı; };
struct pms5003veri verileri; boşluk döngüsü() { piksel.clear(); // Tüm piksel renklerini 'kapalı' olarak ayarlayın DateTime now=RTC.now(); //Recupère l'heure et le date courante //affiche_date_heure(şimdi);
temps = ((millis() - tempsInit))/1000; // Démarrage du chrono
if (readPMSdata(&pmsSerial)) { // tft.fillScreen(ST7735_BLACK); tft.setCursor(10, 5); tft.setTextColor(ST7735_BEYAZ); tft.println(" nbre parçalar/ 0.1 l");
tft.setCursor(10, 17); tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); 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_YEŞİL, ST7735_SİYAH); tft.setTextSize(1); tft.print("0.5 um ");tft.print(data.particles_05um);tft.print(" ");
tft.setCursor(10, 41);
tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); tft.setTextSize(1); tft.print("1.0 um ");tft.print(data.particles_10um);tft.print(" ");
tft.setCursor(10, 53);
tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); tft.setTextSize(1); tft.print("2,5 um ");tft.print(data.particles_25um);tft.print(" ");
tft.setCursor(10, 65);
tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); tft.setTextSize(1); tft.print("5.0 um ");tft.print(data.particles_50um);tft.print(" ");
tft.setCursor(10, 77);
tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); tft.setTextSize(1); tft.print("10 um ");tft.print(data.particles_100um);tft.print(" ");
tft.setCursor(2, 89);
tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); 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(" mikrog/m3");
tft.setCursor(2, 100); tft.setTextColor(ST7735_YEŞİL, ST7735_SİYAH); 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_YEŞİL, ST7735_SİYAH); 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_BEYAZ, ST7735_BLACK); tft.setTextSize(1); tft.println(" nbre parçalar/ 0.1 l");
// Serial.print(geçici);
// Seri.baskı (" "); Seri.print ("#"); Seri.baskı ("03µm "); Serial.print(data.particles_03um); Seri.baskı (" "); Seri.baskı ("05µm "); Serial.print(data.particles_05um); Seri.baskı (" "); Seri.baskı ("1µm "); Serial.print(data.particles_10um); Seri.baskı (" "); Seri.baskı ("25µm"); Serial.print(data.particles_25um); Seri.baskı (" "); Seri.baskı ("50µm"); Serial.print(data.particles_50um); Seri.baskı (" "); Seri.baskı ("100µm"); Serial.print(data.particles_100um); Seri.println (" "); nombre_leds =int (((kayan (data.particles_03um)/65535)*24)); //nombre_leds =(8); Serial.println (nombre_led'ler);
if ((nombre_leds=1)){
piksel.doldur(vert, 0, nombre_leds); } else if ((nombre_leds=8)) { piksel.fill(vert, 0, 8); piksel.doldur(turuncu, 8, ((nombre_leds)-8)); } else if (nombre_leds>16) {
piksel.doldur(vert, 0, 8); piksel.doldur(turuncu, 8, 8); piksel.doldur(ruj, 16, ((nombre_leds)-16)); } else if (nombre_leds<=1) { piksel.fill(vert, 0, 1); } piksel.göster(); // Güncellenen piksel renklerini donanıma gönder.
// Tanımlama bilgileri String PM03=String(data.particles_03um); Dize PM05=Dize(data.particles_05um); Dize PM10=Dize(data.particles_10um); String PM25=String(data.particles_25um); Dize PM50=Dize(data.particles_50um); Dize PM100=Dize(data.particles_100um); Dize PMS10=Dize(data.pm10_standard); Dize PMS25=Dize(data.pm25_standard); Dize PMS100=Dize(data.pm100_standard); String Temps=String(temps);
//Ecriture des données dans le fichier texte
Dosya verisi=SD.open("donnees.txt", FILE_WRITE); data.println(Sıcaklık + " " + PM03+ " " + PM05 +" " +PM10+" " +PM25+" "+PM50+" " +PM100+" "+PMS10+" "+PMS25+" "+PMS100+" "); data.close(); }
}
boolean readPMSdata(Akış *s) {
if (! s->mevcut()) { return false; } // Özel '0x42' başlangıç baytına ulaşana kadar her seferinde bir bayt oku if (s->peek() != 0x42) { s->read(); yanlış döndür; }
// Şimdi 32 baytın hepsini oku
if (s->mevcut() readBytes(buffer, 32);
// sağlama toplamını hazırla
for (uint8_t i=0; i<30; i++) { toplam += arabellek; }
/* hata ayıklama
for (uint8_t i=2; i<32; i++) { Serial.print("0x"); Serial.print(arabellek, HEX); Seri.print(", "); } Seri.println(); */ // Veriler endian'd olarak gelir, bu onu çözer, böylece tüm platformlarda çalışır uint16_t buffer_u16[15]; for (uint8_t i=0; i<15; i++) { buffer_u16 = arabellek[2 + i*2 + 1]; buffer_u16 += (buffer[2 + i*2] << 8); }
// güzel bir yapıya koy:)
memcpy((void *)&data, (void *)buffer_u16, 30);
if (sum != data.checksum) {
Serial.println("Doğrulama hatası"); yanlış döndür; } // başarı! true döndür; }
//Günlük dönüştürme /!\ la semaine un dimanche başlangıcı
String donne_jour_semaine(uint8_t j){ switch(j){ durum 0: "DIM" döndür; durum 1: "LUN" döndür; durum 2: "MAR" döndür; durum 3: "MER" döndür; durum 4: "JEU" döndür; durum 5: "VEN" döndür; durum 6: "SAM" döndür; varsayılan: " " döndür; } }
// 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(tarihsaat.yıl(), Aralık); // heure Dize heure = ""; heure = Vers2Chiffres(datetime.hour())+ ":" + Vers2Chiffres(datetime.dakika())+ ":" + Vers2Chiffres(datetime.second());
Seri.baskı(günlük); Seri.print(" "); Serial.print(heure); //Seri.print(" "); Dosya verisi=SD.open("donnees.txt", FILE_WRITE); data.print(günlük + " " + heure+" "); data.close();
tft.setCursor(2, 120);
tft.setTextColor(ST7735_YEŞİL); tft.setTextSize(1); tft.print("date ");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);
gecikme(500);
}
//permet d'afficher les nomres sur deux chiffres
String Vers2Chiffres(byte nombre) { String sonuç = ""; if(isim < 10) sonuç = "0"; sonucu döndür += String(nombre, DEC); }
Adım 3: MIT App Inventor 2 Programı
bu MIT uygulaması mucit kod bloğudur
4. Adım: SONUÇ
işte sonucun videosu