Arduino 温度,湿度,PM检测
作者:阿圣(Sfan) 发布于:2013-4-26 13:20 Friday 分类:计算机
去年就在x宝上买了一套Arduino 的学习套件.一直没做什么东西.
北京的各种"霾",有了要做一个PM2.5检测小装置的想法.收集各种资料之后.X宝买各种工具和粉尘颗粒传感器.
基本结构: Arduino + enc28j60 + Dht11 + GP2Y1010AU0F + nokia 5110 lcd;
材料: 1.Arduino pro mini 2.ENC28j60以太网模块 3. sharp GP2Y1010AU0F 粉尘传感器 4.DHT11数字温/湿度传感器(这个便宜货精度太差) 5.Nokia 5110 液晶屏模块 6.过线塑料盒 7.各种工具杜帮线.
功能如下:
1.读取当前温度,湿度,可入肺颗粒数.并显示出来.
2.插上网线的话.根据网络环境自动获取IP或设置预设固定IP.并把读取的当前环境数据上传到 yeelink 平台
3.显示当前时间,日期(时间从网络UTC时间服务器读取)
4.可以自己定制相关功能.自己烧写程序
上几张图.
启动状态.右上角一个小图标是网络状态的.
温/湿度显示.
PM2.5 显示
上传到yeelink平台数据显示
Enc28j60 ,Arduino pro min ,nokia 5110
夏普 GP2Y1010AU0F
网络接口 和 电源的接口 电源 5V
粉尘传感器 [GP2Y1010AU0F] 外置 用热熔胶粘在后盖上,可当做整个盒子的支架
DHT11 温/湿度传感器 内嵌在盒子一侧 盒子顶端预留下载接口 (亲,别吐槽焊工 - -" ,电铬铁神马的都是刚买的有木有)
相关代码,库,文档: 写的有点乱
#include <EtherCard.h> #include <dht11.h> #include <Time.h> #include <LCD5110_Graph.h> #define IN #define OUT char VERSION[] ="v1.8"; //enc28j60 int dcPin=10; static byte mymac[]={0x74,0x69,0x2D,0x30,0x31}; static byte myip[]={192,168,80,160}; static byte mymask[]={255,255,255,0}; static byte gwip[]={192,168,80,1}; static byte dnsip[]={8,8,8,8}; byte Ethernet::buffer[270]; boolean getDHCP=true; boolean dnslookup=true; //enc28j60 Stash stash; //dht11 dht11 DHT11; int dht11ReadPin=4; //dht11 //GP2Y1010AU0F int dustPin=0; int ledPower=2; int delayTime=280; int delayTime2=40; float offTime=9680; int dustVal=0; int pm_i=0; float ppm=0; //char s[32]; float voltage = 0; static float dustdensity = 0; float ppmpercf = 0; int pm2_5=0; //GP2Y1010AU0F //yeelink #define N 3 char website[] PROGMEM="api.yeelink.net"; char APIKey[] PROGMEM = "441033961344aab**************"; //API KEY char DeviceID[] PROGMEM = "2463"; const uint16_t SensorID[N] = {3277,3278,3279}; char sensorData[N][30]; uint8_t dataLength[N]; //yeelink uint32_t lastConnectionTime = 0; const uint16_t PostingInterval = 5000; //轮流向服务器发送相应传感器变量 0 <= i <N, uint8_t i=0;// //time boolean timeNeedSet = true; uint16_t timeSetTimer = 0; #define TIME_SET_TIMER 4000 //about TIME_SET_TIMER*5s //nokia 5110 LCD5110 myGLCD(5,6,7,8,9); extern uint8_t SmallFont[]; //extern uint8_t TinyFont[]; extern uint8_t BigNumbers[]; //extern uint8_t arduino_logo[]; uint8_t temperature_ico[] PROGMEM={0x02,0x05,0x7A,0x84,0x84,0x48};// uint8_t net_ico_S[] PROGMEM={0x00,0x03,0x05,0x7D,0x7D,0x05,0x03,0xB8,0xA8,0xE8,0x00,0x00,0x00}; uint8_t net_ico_D[] PROGMEM={0x00,0x03,0x05,0x7D,0x7D,0x05,0x03,0xF8,0x88,0x88,0x70,0x00,0x00}; uint8_t net_ico_err[] PROGMEM={0x00,0xFF,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0xFF,0x00,0x00}; uint8_t net_ico_cls[] PROGMEM={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t cls[] PROGMEM={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t pm2_5_ico[] PROGMEM={0x00,0x00,0x00,0xF0,0xF8,0x8C,0x8C,0x8C,0x88,0xF0,0x70,0x00,0x00,0xD0,0x50,0x70, 0x00,0x00,0x00,0x70,0x50,0xD0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x3F,0x3F,0x01,0x01,0x39,0x3D,0x08,0x3C,0x08,0x3C,0x39,0x01,0x01,0x00,0x01, 0x00,0x01,0x01,0x01,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, 0x1C,0x10,0x1C,0x00,0x5C,0x54,0x7C,0x00,0x40,0x20,0x1C,0x02,0x39,0x04,0x38,0x04, 0x38,0x04,0x05,0x07,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t sysinit[] PROGMEM={0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x8F,0x1F,0x1F,0x3D,0xF9,0xF9,0xF3, 0xF7,0x1C,0xFC,0xFC,0xF8,0xC0,0xF0,0xFC,0xFC,0x1C,0x3C,0x7C,0x7C,0x7C,0xEC,0xEC, 0xCC,0x80,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0x01,0xF8,0xFC,0xFC,0xFC,0x1C,0x0C, 0xFC,0xFC,0xFC,0x00,0xFC,0xFC,0xFC,0x04,0x0C,0xFF,0xFF,0xFF,0xFF,0x0C,0x8C,0x80, 0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x80, 0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03, 0x03,0x03,0x03,0x01,0x01,0x30,0x30,0x3F,0x3F,0x1F,0x0F,0x03,0x00,0x00,0x03,0x03, 0x03,0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03, 0x03,0x03,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x00,0x01,0x03,0x03, 0x03,0x03,0x03,0x03,0x03,0x01,0x03,0x03,0x03,0x03,0x00,0x03,0x03,0x03,0x00,0x03, 0x03,0x03,0x00,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00}; //nokia 5110 void setup() { myGLCD.InitLCD(); myGLCD.setFont(SmallFont); Serial.begin(115200); //myGLCD.drawBitmap(0, 0, arduino_logo, 84, 48); myGLCD.drawLine(0,10,83,10); myGLCD.drawLine(70,0,70,10); myGLCD.print("--:-- --/--",2,2); myGLCD.drawBitmap(0,15, sysinit, 84, 24); myGLCD.print(VERSION,55,15); myGLCD.drawBitmap(71,1, net_ico_err, 13, 8); myGLCD.print("------ By:SFan",0,40); myGLCD.update(); pinMode(ledPower,OUTPUT);//ledPower GP2Y1010AU0F Serial.print("Version:"); Serial.println(VERSION); Serial.println("Ethernet init..."); if(ether.begin(sizeof Ethernet::buffer,mymac,dcPin)==0){ Serial.println("Failed to access Ethernet controller"); } else{ Serial.println("DHCP"); myGLCD.drawBitmap(71,1, net_ico_D, 13, 8); myGLCD.update(); if(!ether.dhcpSetup()){ myGLCD.drawBitmap(71,1, net_ico_S, 13, 8); myGLCD.update(); getDHCP=false; Serial.println("DHCP failed"); ether.staticSetup(myip,gwip); ether.copyIp(ether.dnsip,dnsip); ether.copyIp(ether.mymask,mymask); } ether.printIp("My IP:",ether.myip); // ether.printIp("Netmask:",ether.mymask); ether.printIp("GW IP:",ether.gwip); ether.printIp("Dns:",ether.dnsip); if(!ether.dnsLookup(website)){ myGLCD.drawBitmap(71,1, net_ico_err, 13, 8); myGLCD.update(); dnslookup=false; } ether.printIp("website:",ether.hisip); } } void loop() { ether.packetLoop(ether.packetReceive()); // pmLoop(); if( millis() < lastConnectionTime || millis() - lastConnectionTime > PostingInterval){ Serial.println(i); get_Send_String(i); if(dnslookup){ send_Data(i); }else{ lastConnectionTime=millis(); } i++; if (i == N) i=0; } } static void dht11Read(){ // Serial.println("\n"); int chk = DHT11.read(dht11ReadPin); Serial.print("Read sensor: "); switch (chk) { case DHTLIB_OK: Serial.println("OK"); break; case DHTLIB_ERROR_CHECKSUM: Serial.println("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: Serial.println("Time out error"); break; default: Serial.println("Unknown error"); break; } Serial.print("Humidity (%): "); Serial.println((float)DHT11.humidity, 2); Serial.print("Temperature (oC): "); Serial.println((float)DHT11.temperature-2, 2); myGLCD.drawBitmap(0,15, cls, 84, 25); myGLCD.update(); myGLCD.drawBitmap(35, 30, temperature_ico, 6, 8); myGLCD.setFont(SmallFont); myGLCD.print("%",73,32); myGLCD.setFont(BigNumbers); myGLCD.printNumI(DHT11.temperature-2,5,15); myGLCD.printNumI(DHT11.humidity,45,15); myGLCD.update(); } static void pmData(){ pmLoop(); Serial.println(dustVal); voltage = ppm/pm_i*0.0049; dustdensity = 0.17*voltage-0.1; ppmpercf = (voltage-0.0256)*120000; if (ppmpercf < 0) ppmpercf = 0; if (dustdensity < 0 ) dustdensity = 0; if (dustdensity > 0.5) dustdensity = 0.5; pm_i=0; ppm=0; pm2_5=dustdensity*1000; Serial.print("voltage :"); Serial.println(voltage); Serial.print("dustdensity :"); Serial.println(dustdensity); Serial.print("ppmpercf :"); Serial.println(ppmpercf); myGLCD.drawBitmap(0,15, cls, 84, 25); myGLCD.update(); myGLCD.drawBitmap(8,15, pm2_5_ico, 30, 24); myGLCD.setFont(BigNumbers); myGLCD.printNumI(pm2_5,40,15); myGLCD.update(); } void pmLoop(){ pm_i=pm_i+1; digitalWrite(ledPower,LOW); // power on the LED delayMicroseconds(delayTime); dustVal=analogRead(dustPin); // read the dust value ppm = ppm+dustVal; delayMicroseconds(delayTime2); digitalWrite(ledPower,HIGH); // turn the LED off delayMicroseconds(offTime); } void get_Send_String(uint8_t k){ switch(k){ case 0:{ dht11Read(); dataLength[k]=sprintf(sensorData[k],"{\"value\":%d}",DHT11.temperature-2); break;} case 1:{ dht11Read(); dataLength[k]=sprintf(sensorData[k],"{\"value\":%d}",DHT11.humidity); break;} case 2:{ pmData(); // Serial.println(dustdensity*1000); dataLength[k]=sprintf(sensorData[k],"{\"value\":%d}",pm2_5); } } } void send_Data(uint8_t j) { // Create a Post for yeelink server, // and send request saving sessionID Serial.println(sensorData[j]); Serial.println(SensorID[j]); Serial.println(); Stash::prepare(PSTR("POST /v1.0/device/$F/sensor/$D/datapoints HTTP/1.1" "\r\n" "Host: api.yeelink.net" "\r\n" "U-ApiKey: $F" "\r\n" "Content-Length: $D" "\r\n" "Content-Type: application/x-www-form-urlencoded" "\r\n" "\r\n" "$S" "\r\n"), DeviceID,SensorID[i],APIKey,dataLength[i],sensorData[i]); // ether.tcpSend(); if(timeNeedSet){ setupTime(); } else{ ether.tcpSend(); displayClock(); } lastConnectionTime = millis(); } #define REQEST_TIMEOUT 10000 void setupTime(){ uint8_t session_id; session_id = ether.tcpSend(); uint32_t requestTimer = millis() + REQEST_TIMEOUT; while(millis() < requestTimer){ ether.packetLoop(ether.packetReceive()); char bufx[21]; const char* reply = ether.tcpReply(session_id); if(reply !=0){ for(uint8_t I=0;I<21;I++){ bufx[I]=reply[50+I]; } tmElements_t time1; timeconvert(bufx,&time1); time_t second = makeTime(time1); setTime(second); adjustTime(8*60*60); timeNeedSet=false; break; } } } void displayClock(){ // digital clock display of the time timeSetTimer++; if (timeSetTimer>TIME_SET_TIMER) { timeSetTimer=0; timeNeedSet=true; } myGLCD.setFont(SmallFont); int h=hour(); int m=minute(); int mo=month(); int d=day(); int x=2; if(h<10){ myGLCD.print("0",x,2); x+=6; myGLCD.printNumI(h,x,2); x+=6; }else{ myGLCD.printNumI(h,x,2); x+=12; } myGLCD.print(":",x,2); x+=6; if(m<10){ myGLCD.print("0",x,2); x+=6; myGLCD.printNumI(m,x,2); x+=6; }else{ myGLCD.printNumI(m,x,2); x+=12; } myGLCD.print(" ",x,2); x+=6; if(mo<10){ myGLCD.print("0",x,2); x+=6; myGLCD.printNumI(mo,x,2); x+=6; }else{ myGLCD.printNumI(mo,x,2); x+=12; } myGLCD.print("/",x,2); x+=6; if(d<10){ myGLCD.print("0",x,2); x+=6; myGLCD.printNumI(d,x,2); x+=6; }else{ myGLCD.printNumI(d,x,2); x+=12; } myGLCD.update(); Serial.print(year()); Serial.print("-"); Serial.print(month()); Serial.print("-"); Serial.print(day()); Serial.print(" "); Serial.print(hour()); Serial.print(":"); Serial.print(minute()); } //比较周数,成功返回0-6的数,错误返回7 //p代表周数,取周数前3个字母,如Mon代表周1,以此类推 //改动周几不影响返回的时间值,可以通过改动日期的日数来达到修改时间 //比较月份,成功返回0-11的数,错误返回12 //P 为月份的前三个字母,如Feb代表二月,以此类推 int monthcmp( IN char *p) { char *month[]={ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; int i; for(i=0;i<12;i++){ if(strcmp(p,month[i])==0) break; } if(i==12) { return i; } return i; } //将字串格式的时间转换为结构体,返回距离1970年1月1日0:0:0的秒数,当字符串格式错误或超值时返回0 //BUF 为类似Tue May 15 14:46:02 2007格式的,p为时间结构体 void timeconvert(IN char *buf,OUT tmElements_t *p) { char cmonth[4]; int16_t td,th,tm,ts,ty; sscanf(buf,"%d %s %d %d:%d:%d",&td,cmonth,&ty,&th,&tm,&ts); //sscanf("2012 Aug " ,"%4d %s",&ty,cmonth); p->Year = ty - 1970; p->Month = monthcmp(cmonth) + 1; p->Day = td; p->Hour = th; p->Minute = tm; p->Second = ts; }
libraries.rar (DHT11,ethercard,LCD5110_Graph 相关库)
标签: Arduino
评论:
2015-05-26 16:24
228
voltage = ppm/pm_i*0.0049;
229
dustdensity = 0.17*voltage-0.1;
230
ppmpercf = (voltage-0.0256)*120000;
231
if (ppmpercf < 0)
232
ppmpercf = 0;
233
if (dustdensity < 0 )
234
dustdensity = 0;
235
if (dustdensity > 0.5)
236
dustdensity = 0.5;
237
pm_i=0;
238
ppm=0;
239
pm2_5=dustdensity*1000;
240
Serial.print("voltage :");
241
Serial.println(voltage);
242
Serial.print("dustdensity :");
243
Serial.println(dustdensity);
244
Serial.print("ppmpercf :");
245
Serial.println(ppmpercf);
246
myGLCD.drawBitmap(0,15, cls, 84, 25);
247
myGLCD.update();
248
myGLCD.drawBitmap(8,15, pm2_5_ico, 30, 24);
249
myGLCD.setFont(BigNumbers);
250
myGLCD.printNumI(pm2_5,40,15);
251
myGLCD.update();
252
}
请问这个算法什么意思
2013-05-23 21:29
2016-03-24 15:13