สารบัญ:
- เสบียง
- ขั้นตอนที่ 1: เชื่อมต่อส่วนประกอบ
- ขั้นตอนที่ 2: โปรแกรมไลบรารีและ Arduino
- ขั้นตอนที่ 3: โปรแกรม MIT App Inventor 2
- ขั้นตอนที่ 4: ผลลัพธ์
วีดีโอ: ระบบตรวจสอบคุณภาพอากาศฝุ่นละออง: 4 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:04
บทนำ:
1 ในโครงการนี้ ฉันจะแสดงวิธีสร้างเครื่องตรวจจับอนุภาคด้วยการแสดงข้อมูล การสำรองข้อมูลบนการ์ด SD และ IOT การแสดงวงแหวนนีโอพิกเซลด้วยสายตาบ่งบอกถึงคุณภาพอากาศ
2 คุณภาพอากาศเป็นปัญหาที่สำคัญมากขึ้นในปัจจุบัน มีระบบวัดอัตราฝุ่นแต่มีราคาแพงมาก มีเครื่องตรวจจับอนุภาคคุณภาพสูงราคาประหยัดในท้องตลาดดังที่แสดงโดยการศึกษาบางส่วน
ตัวอย่างเช่น:
www.atmos-meas-tech.net/11/4823/2018/amt-1…
3 ฉันจึงตัดสินใจสร้างอุปกรณ์ที่สามารถวัดจำนวนอนุภาคตามคลาสขนาด (0.5µm ถึง 10 µm) ด้วยการแสดงผลอย่างง่าย (วงแหวนนีโอพิกเซล) การแสดงรายละเอียดเพิ่มเติมบนหน้าจอ TFT และ การสำรองข้อมูลประทับเวลาบนการ์ด SD
4 นอกจากนี้ ฉันได้เพิ่มโมดูลการสื่อสารบลูทูธเพื่อให้สามารถสื่อสารกับแอปพลิเคชัน Android และเผยแพร่ผลลัพธ์บนเซิร์ฟเวอร์ IOT
5 ค่าใช้จ่ายทั้งหมดไม่เกิน 60 €
เสบียง
-Arduino uno R3
-Arduino โปรโตชิลด์
- หน้าจอ TFT ST7735
-วงแหวน Neopixel 24 led
-แพลนทาวเวอร์ 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 ร่าง Arduino
#include #include // Bibliothèque pour l'I2C #include "RTClib.h" // Bibliothèque สำหรับโมดูล 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 = pixels. Color (255, 0, 0);
ซอฟต์แวร์Serial pmsSerial(2, 3);
#define cs 10 #define dc 9 #define rst 8 // คุณสามารถเชื่อมต่อสิ่งนี้เข้ากับการรีเซ็ต Arduino
#include // ไลบรารีกราฟิกหลัก
#include // ไลบรารีเฉพาะฮาร์ดแวร์ #include #include const int cs_sd=4; อุณหภูมิภายใน; // temps d'acquisition double 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); ลอย nombre_leds=0; การตั้งค่าเป็นโมฆะ () { Serial.begin (9600); // เริ่มต้น la liaison 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 ("รายการ SD ตกลง");
ข้อมูลไฟล์ = 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);
พิกเซล.begin(); // เริ่มต้นวัตถุแถบ NeoPixel (จำเป็น)
พิกเซล.setBrightness(2);
}
โครงสร้าง pms5003data {
uint16_t กรอบ; 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 เช็คซัม; };
โครงสร้างข้อมูล pms5003data; วงเป็นโมฆะ () { พิกเซล. ชัดเจน (); // ตั้งค่าสีพิกเซลทั้งหมดเป็น 'ปิด' DateTime now=RTC.now(); // Récupère l'heure et le date courante //affiche_date_heure (ตอนนี้);
temps = ((มิลลิวินาที() - tempsInit))/1000; // Démarrage du chrono
ถ้า (readPMSdata (&pmsSerial)) { // tft.fillScreen (ST7735_BLACK); tft.setCursor(10, 5); tft.setTextColor(ST7735_WHITE); tft.println(" ส่วน nbre/ 0.1 l");
tft.setCursor(10, 17); tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.setCursor(10, 17); tft.print("0.3 อืม");tft.print(data.particles_03um);tft.print(" ");
tft.setCursor(10, 29);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("0.5 อืม");tft.print(data.particles_05um);tft.print(" ");
tft.setCursor(10, 41);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("1.0 อืม");tft.print(data.particles_10um);tft.print(" ");
tft.setCursor(10, 53);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("2.5 อืม");tft.print(data.particles_25um);tft.print(" ");
tft.setCursor(10, 65);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("5.0 อืม");tft.print(data.particles_50um);tft.print(" ");
tft.setCursor(10, 77);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("10 อืม");tft.print(data.particles_100um);tft.print(" ");
tft.setCursor(2, 89);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.setTextSize(1); tft.print("น. 1.0");tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);tft.print(data.pm10_standard);tft.print(" ");tft.setTextColor(ST7735_GREEN, ST7735_BLACK);tft.print(" ไมโครกรัม/ลบ.ม. ");
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(" microg/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(" microg/m3 ");
tft.setCursor(10, 5);
tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.setTextSize(1); tft.println(" ส่วน nbre/ 0.1 l");
// Serial.print (ชั่วคราว);
// 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 (((ลอย (data.particles_03um)/65535)*24); //nombre_leds =(8); Serial.println (nombre_leds);
ถ้า ((nombre_leds=1)){
pixels.fill(vert, 0, nombre_leds); } else if ((nombre_leds=8)) { pixels.fill(vert, 0, 8); pixels.fill(สีส้ม, 8, ((nombre_leds)-8)); } else if (nombre_leds>16) {
pixels.fill(vert, 0, 8); pixels.fill(สีส้ม, 8, 8); pixels.fill(rouge, 16, ((nombre_leds)-16)); } else if (nombre_leds<=1) { pixels.fill(vert, 0, 1); } pixels.show(); // ส่งสีพิกเซลที่อัปเดตไปยังฮาร์ดแวร์
// นิยาม données String PM03=String(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); สตริง Temps = สตริง (ชั่วคราว);
//Ecriture des données dans le fichier texte
ข้อมูลไฟล์=SD.open("donnees.txt", FILE_WRITE); data.println(Temps + " " + PM03+ " " + PM05 +" " +PM10+" " +PM25+" "+PM50+" " +PM100+" "+PMS10+" "+PMS25+" "+PMS100+" "); data.close(); }
}
บูลีน readPMSdata (สตรีม * s) {
if (! s->available()) { return false; } // อ่านทีละไบต์จนกว่าเราจะไปถึงไบต์เริ่มต้นพิเศษ '0x42' ถ้า (s->peek() != 0x42) { s->read(); คืนค่าเท็จ; }
// ตอนนี้อ่านทั้งหมด 32 ไบต์
if (s->available() readBytes(บัฟเฟอร์, 32);
// เตรียมเช็คซัมให้พร้อม
สำหรับ (uint8_t i=0; i<30; i++) { ผลรวม += บัฟเฟอร์; }
/* การดีบัก
สำหรับ (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 = บัฟเฟอร์[2 + i*2 + 1]; buffer_u16 += (บัฟเฟอร์[2 + i*2] << 8); }
// วางลงในโครงสร้างที่ดี:)
memcpy((เป็นโมฆะ *)&data, (เป็นโมฆะ *)buffer_u16, 30);
ถ้า (ผลรวม != data.checksum) {
Serial.println("เช็คซัมล้มเหลว"); คืนค่าเท็จ; } // ความสำเร็จ! คืนค่าจริง; }
//Converti le numéro de jour en jour /!\ la semaine beginning un dimanche
สตริง donne_jour_semaine (uint8_t j) { สวิตช์ (j) { กรณี 0: ส่งคืน "DIM"; กรณีที่ 1: ส่งคืน "LUN"; กรณีที่ 2: ส่งคืน "MAR"; กรณีที่ 3: ส่งคืน "MER"; กรณีที่ 4: ส่งคืน "JEU"; กรณีที่ 5: ส่งคืน "VEN"; กรณีที่ 6: ส่งคืน "SAM"; ค่าเริ่มต้น: ส่งคืน " "; } }
// affiche la date et l'heure sur l'écran
เป็นโมฆะ affiche_date_heure (DateTime datetime) { // Date String jour = donne_jour_semaine (datetime.dayOfTheWeek ()) + " " + Vers2Chiffres (datetime.day ())+ "/" + Vers2Chiffres (datetime.month ()) + "/" + สตริง (datetime.year(), ธ.ค.); // heure String 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 nombre sur deux chiffres
String Vers2Chiffres (byte nombre) { String resultat = ""; if(nombre < 10) resultat = "0"; ส่งคืน resultat += String(nombre, DEC); }
ขั้นตอนที่ 3: โปรแกรม MIT App Inventor 2
นี่คือบล็อกรหัสนักประดิษฐ์แอป MIT
ขั้นตอนที่ 4: ผลลัพธ์
นี่คือวิดีโอของผลลัพธ์
แนะนำ:
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: 5 ขั้นตอน
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: การตวัดเป็นวิธีง่ายๆ ในการสร้างเกม โดยเฉพาะอย่างยิ่งเกมปริศนา นิยายภาพ หรือเกมผจญภัย
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: 3 ขั้นตอน
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: ในคำแนะนำนี้ เราจะทำการตรวจจับใบหน้าบน Raspberry Pi 4 ด้วย Shunya O/S โดยใช้ Shunyaface Library Shunyaface เป็นห้องสมุดจดจำใบหน้า/ตรวจจับใบหน้า โปรเจ็กต์นี้มีจุดมุ่งหมายเพื่อให้เกิดความเร็วในการตรวจจับและจดจำได้เร็วที่สุดด้วย
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: 3 ขั้นตอน
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: ในบทช่วยสอนนี้ ฉันจะแสดงขั้นตอนสำคัญในการติดตั้งปลั๊กอิน WordPress ให้กับเว็บไซต์ของคุณ โดยทั่วไป คุณสามารถติดตั้งปลั๊กอินได้สองวิธี วิธีแรกคือผ่าน ftp หรือผ่าน cpanel แต่ฉันจะไม่แสดงมันเพราะมันสอดคล้องกับ
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): 8 ขั้นตอน
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): ตัวแปลงสัญญาณเสียงล้ำเสียง L298N Dc ตัวเมียอะแดปเตอร์จ่ายไฟพร้อมขา DC ตัวผู้ Arduino UNOBreadboardวิธีการทำงาน: ก่อนอื่น คุณอัปโหลดรหัสไปยัง Arduino Uno (เป็นไมโครคอนโทรลเลอร์ที่ติดตั้งดิจิตอล และพอร์ตแอนะล็อกเพื่อแปลงรหัส (C++)
เครื่อง Rube Goldberg 11 ขั้นตอน: 8 ขั้นตอน
เครื่อง 11 Step Rube Goldberg: โครงการนี้เป็นเครื่อง 11 Step Rube Goldberg ซึ่งออกแบบมาเพื่อสร้างงานง่ายๆ ในรูปแบบที่ซับซ้อน งานของโครงการนี้คือการจับสบู่ก้อนหนึ่ง