作为单片机应用教学,我们着眼于综合知识的集成应用,下面我们通过自制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 }
|