06
2019
05

WIFI作品DIY教程14-《空气质量》空气PM2.5检测家里雾霾。

上篇WIFI作品DIY教程07-《wifi家居网关》家居控制中心zigbee/nrf24l01等完成了家居网关。



日益严重的空气污染深入了中国各大地,我们在家里也可以检测pm2.5那么也是赶上时代的变化了。


我们需要的配件:粉尘传感器板GP2Y1010AU0Fnrf24l01(或zigbee等)


第一部分:GP2Y101AUOF传感器介绍









空气质量指数  空气质量指数级别
0-50      = 一级  优
51-100  = 二级  良
101-150 = 三极  轻度污染
151-200 = 四级  中度污染
201-300 = 五级  重度污染
>300       = 六级  严重污染

使用GP2Y1010AU0F灰尘传感器检测空气质量
GP2Y1010AU0F灰尘传感器价格较便宜,能检测出室内空气中的灰尘和烟尘含量.

检测原理
其原理如下图,传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。








第二部分:下载编译源代码
1、安装CH340驱动

在drivers目录里找到CH340驱动,然后按说明安装(之前安装了就不用再安装了)。


2、源代码


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
 *NRF24l01针脚连接线
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 * Configurable:
 * CE -> 8
 * CSN -> 7
  
 *ZIGBEE针脚连接线
 TX -> RXD
 RX -> TXD
  
 *GP2Y1050AU灰尘传感器针脚连接线
 GND -> GND
 VCC -> VCC
 NC
 NC
 RXD  -> A1
 TXD  -> A0
*/
#include <SPI.h> //引用SPI库文件
#include <Mirf.h> //引用Mirf库文件
#include <nRF24L01.h> //引用NRF24L01库文件
#include <MirfHardwareSpiDriver.h> //引用Mirf驱动库文件
#include <SoftwareSerial.h> //引用软串口库文件
 
int sid=1;//模块类型
int nid=3;//模块编号
 
//声名变量
const unsigned long interval = 60000;//时间间隔
unsigned long last_sent;//最后发送时间
 
 
SoftwareSerial mySerial(A0, A1); //定义软串口,对应RX,TX
 
float pm25=0.00;//声明pm2.5变量
int incomeByte[6];//声明pm2.5字节
int data;//当前数据
int z=0;//当前字符数
int sum;//数据总和
unsigned long error;//错误
 
 
//NRF24L01
unsigned long nrf24l01nowlast; //NRF24L01检测间隔时间
char nrf24l01buff[33]={0}; //NRF24L01缓存字符
char nrf24l01Data; //NRF24L01单个字符
int nrf24l01i=0; //NRF24L01字符数
 
 
void setup()
{
    Serial.begin(115200); //设置串口波特率115200
 
    //初始化Mirf,用于NRF24L01收发
    char client[10]={0}; //客户端名称
    sprintf(client,"clie%d",sid); //设置客户端名称
    Mirf_Init(0,client,sid); //初始化NRF24L01收发     
         
    mySerial.begin(2400);//设置软串口的波特率
     
    Serial.println("zwifi_pm25");//打印
}
  
void loop()
{
   
  unsigned long now = millis();//获取现在的时间
  if ( now - last_sent >= interval  ) //如果超过时间间隔
  {
    last_sent = now;//保存到最后时间
     
    pm25=0.00;//初始化0
    run_pm25();//调用函数pm2.5获取数据
    if(pm25>0){//如果pm2.5大于0
      char pmstr[10]={0};//声明字符
      dtostrf(pm25,4,2,pmstr);//格式化字符
       
      char data[10]={0};//声明数据字符
      sprintf(data,"%s",pmstr);//格式化字符
      send_data(data);//调用函数发送数据到网关
       
    }
     
  }
   
   
}
 
//初始化Mirf 0初始化1为接收2为发送
void Mirf_Init(int txrx,char *server,int channel){
    //初始化Mirf       
    if(txrx==0)  {
      Mirf.spi = &MirfHardwareSpi;//设置spi
      Mirf.init();//初始Mirf
      Mirf.setRADDR((byte *)server);//设置接收地址
    }
     
    //设置接收模式
    if(txrx==1)  {    
      Mirf.setRADDR((byte *)server);//设置接收地址
    }
     
    //设置发送模式
    if(txrx==2)  {
      Mirf.setTADDR((byte *)server);//设置发送地址
    }
     
    Mirf.payload = sizeof(char);//收发字节
    Mirf.channel = channel;//设置频道
    Mirf.config();//生效配置
}
 
//NRF24l01发送函数
void Mirf_Send(int channel,char *server,char *str){
  Mirf_Init(2,server,channel);//设置发送模式
  int bufi=0;//声明变量
  for(bufi=0;bufi<strlen(str);bufi++){//循环发送
    char words=str[bufi];//发送的字符
    Mirf.send((byte *)&words);//发送命令
    while(Mirf.isSending()){//等待发送完闭
    }
    delay(50);//延时,否则可能出现发送丢失现象
    //Serial.print(words);
  }
  //Serial.println("");
}
 
 
 
//获取pm2.5传感器的数据函数
void run_pm25()
{
    while (mySerial.available()){//如果软串口存在数据
   
       data=mySerial.read();//读取软串口数据
       if(data == 170){//如果数据是170则是开始
         z=0;//当前字符数
         incomeByte[z]=data;//保存到当前字节
       }else{//如果不是开始
         z++;//当前字符数+1
         incomeByte[z]=data;//保存到当前字节
       }
       if(z==6)//如果满6个字符
       {
            sum=incomeByte[1]+ incomeByte[2]+ incomeByte[3] + incomeByte[4];//字节数相加,为了效验数据
         
            if(incomeByte[5]==sum && incomeByte[6]==255 )//效验数据格式
            {
               Serial.print("Data OK! ");
               Serial.print(" | Vo=");
               float vo=(incomeByte[1]*256.0+incomeByte[2])/1024.0*5.00;//计算pm2.5算法
               Serial.print(vo,2);
               Serial.print("V  ");
               float v1=analogRead(A0)/1024.0*5.00;
               Serial.print("/ Ao=");
               Serial.print(v1,2);
               Serial.print("V  | ");
               float c=vo*200;
               pm25=c;//保存pm2.5变量
               Serial.print(c,2);
               Serial.print("ug/m3 | ");
               for(int k=0;k<7;k++)
                {
                  Serial.print(incomeByte[k]);//打印原始数据
                  Serial.print("|");
                 }
                 Serial.println();               
                 break;
             }else{
                 z=0;
                 Serial.flush();
                 data='/0';
                 for(int m=0;m<7;m++){incomeByte[m]=0;}
                 //error++;
                 //Serial.print(" ### This is ");
                 //Serial.print(error);
                 //Serial.println(" Error ###");
             }
             z=0;
       }
    }
}
 
//发送数据到网关的函数
void send_data(char *data){
      
    char server[10]={0};//声明网关接收名称
    sprintf(server,"serv%d",1);//赋值网关接收名称
    //Serial.println(server);//打印
     
    char updateData[33]={0};//声明更新数组
    char front[10]={0};//声明更新前缀
    //memcpy(front,body,9);
    sprintf(front," {ck%03d%03d",sid,nid);//赋值前缀
    sprintf(updateData,"%s%s}",front,data);//生成反馈数组
    Serial.println(updateData);//发送到串口(zigbee会发给网关)
    Serial.println();//换行
     
    Mirf_Send(1,server,updateData);//发送给NRF24L01(NRF24L01会发给网关)
     
    char client[10]={0};//声明客户端
    sprintf(client,"clie%d",sid);//赋值客户端名称
    Mirf_Init(1,client,sid);//设置为接收模式
                 
}




刷写arduino程序选哪个板?
请选择板是Arduino Uno,并记得选对对应的串口。

刷写ardruino源代码时,提示库不存在?
请联系qq610854837下载zwifi资料,软件下载目录里的arduino-1.0.5,里面包含了教程使用的所有库。



将代码进行编译下载到arduino板上。


3、串口运行查看数据是否正常

在arduino软件里,查看串口数据,记得是115200哦,有如上图,说明下载运行成功了!

程序的原理就是获取传感器数据,然后组合成字符{ck00x00xnnnn}发送到网关保存数据,供我们以后分析。



第四部分:检测通信和数据库数据




未写完。


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。