作為單片機應用教學,我們著眼于綜合知識的集成應用,下面我們通過自制pm2.5檢測儀過程掌握arduino相關接口電路,1602液晶顯示屏顯示數據,L298N電機控制板,手機藍牙控制,混色LED燈,灰塵傳感器以及相關用到的arduino編程語言。 3.6.1、灰塵傳感器知識準備對于激光式灰塵傳感器,基本原理是傳感器讓空氣自由流過(一些空氣測試儀內部有小風扇起到空氣流通的作用,在這里我們用來回走動的方式代替小風扇),定向發射LED光,通過檢測經過空氣中灰塵折射過后的光線來判斷灰塵的含量。灰塵傳感器市面上較為普及的是高精度的攀藤 G5 PMS5003傳感器(那個寶價約88元)和較為便宜的夏普SHARP GP2Y1010AU0F型灰塵/粉塵傳感器(那個寶價約25元),出于普及的考慮我們選用了SHARP GP2Y1010AU0F型灰塵/粉塵傳感器。 file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg 灰塵傳感器接線 Arduino 接線 1 Vled –> 5V (先接150歐姆電阻,再接5v,買傳感器時有配套) 2 LED-GND –> GND(接地) 3 LED –> Digital pin2 (Arduino板子上數字D2端) 4 S-GND 黃色 –> GND(接地) 5 Vo 黑色 –> Analog pin 0(Arduino板子上模擬A0端) 6 Vcc 紅色 –> 5V file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg 粉塵濃度dustdensity= 0.17 * voltage - 0.1;//大概的線性函數關系。 在圖上可看到粉塵濃度超過0.5mg/m3的時候,傳感器輸出的電壓受到限制,不會無限增高,也就超出了傳感器的有效測量范圍。這也就是我們常說的爆表:pm2.5超過500ug/m3(1mg=1000ug)。 到這里,其實我們已經可以測試空氣中的粉塵濃度了,只不過要和電腦連線,通過arduino軟件的串口監視器功能得到電壓數據,來檢測空氣質量,因為用電腦的顯示器作為輸出,所以移動性和便攜性較差。但此時的硬件成本最低,算是空氣檢測儀的最小系統。 使用簡化版本的軟件代碼如下: // 定義使用nano的A0端,連接灰塵傳感器5號線 int dustPin=0; float dustVal=0; // 定義使用nano的Digital pin 2端,連接灰塵傳感器3號線 int ledPower=2; intdelayTime=280; intdelayTime2=40; float offTime=9680; void setup(){ Serial.begin(9600); pinMode(ledPower,OUTPUT); pinMode(dustPin,INPUT); } void loop(){ // ledPower isany digital pin on the arduino connected to Pin 3 on the sensor digitalWrite(ledPower,LOW); delayMicroseconds(delayTime); dustVal=analogRead(dustPin); delayMicroseconds(delayTime2); digitalWrite(ledPower,HIGH); delayMicroseconds(offTime); delay(1000); if(dustVal>36.455) Serial.println((float(dustVal/1024)-0.0356)*120000*0.035); } file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image007.jpg 測試得到的數據和空氣質量對照: 3000 + = 很差 1050-3000 = 差 300-1050 = 一般 150-300 = 好 75-150 = 很好 0-75 = 非常好 3.6.2、I2C接口的LCD準備為了能讓空氣檢測儀脫離電腦連線獨立工作,我們還要再加上一個LCD1602液晶屏。 1602 LCD液晶屏(焊好排線的1602屏那個寶價約7.5元,沒焊排線的約4.9元) file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image009.gif 1602液晶屏帶ic端,ic端把上述連線封裝了,導出用到了總線技術顯示,簡化為4個接口,正接正極5v,負接和負極,sda接nano板子的sda管腳即A4管腳,見前面電路圖sda管腳,scl管腳接nano板子的scl管腳即A5管腳。Scl是時鐘,sda是數據,總線技術是把很多數據量按時鐘順序,分批次傳給nano板子。因為時間片很快,人感覺不到延遲。這樣管腳占用就少了很多。 按上圖連接線路后,1602的模塊測試代碼如下; #include<Wire.h> //#include<LiquidCrystal_I2C.h> //引用I2C庫 #include "LiquidCrystal_I2C.h" //設置LCD1602設備地址,這里的地址是0x3F,一般是0x20,或者0x27,具體看模塊手冊 LiquidCrystal_I2Clcd(0x27,16,2); voidsetup() { lcd.init(); // 初始化LCD lcd.backlight(); //設置LCD背景等亮 } void loop() { lcd.setCursor(0,0); //設置顯示指針 lcd.print("LCD1602 iic Test"); //輸出字符到LCD1602上 lcd.setCursor(0,1); lcd.print(" by L.L."); delay(1000); } 對于有些I2C接口的硬件來說,可以用以下代碼查到對應的I2C硬件地址,下列程序可以把I2C接口的硬件地址打印到串口監視器里: #include<Wire.h> voidsetup(){ Wire.begin(); Serial.begin(9600); Serial.println("\nI2CScanner"); } voidloop(){ byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; address++){ // The i2c_scanner uses the return valueof // the Write.endTransmisstion to seeif // a device did acknowledge to theaddress. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0){ Serial.print("I2C device found ataddress 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; }else if (error == 4){ Serial.print("Unknow error ataddress 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devicesfound\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for nextscan }
|