小滴 发表于 2013-6-3 20:57:18

使用Arduino及乐联网平台搭建家居环境监测调节系统

本帖最后由 小滴 于 2013-6-3 21:13 编辑

使用Arduino及乐联网平台搭建家居环境监测调节系统1.       
功能实现:
    实现了空气温湿度、PM2.5质量浓度的实时监测,本地显示、上传至乐联网,并可以直接自动控制空气净化系统工作,空气质量达标以后,又可以自动断电,节约能源;此外,利用乐联网平台实现了自动推送微博、短信预警、远程控制空气净化器的开关。
    在此过程中,感谢张老师和乐联网刘先生的大力支持,没有两位的帮助,我这个非机电、非软件专业的业余人士不能实现这个系统的搭建。
   P.S.乐联网的自动发送微博、短信功能真的非常便利,安卓APP也很棒~远程控制全靠他了。
网站指南http://www.lewei50.com/dev/doc/95

2.        硬件列表:
(1)        Arduino UNO 板子60左右,不过由于我是纯新手,买的是一个传感器套装,链接如下:
http://item.taobao.com/item.htm?spm=a1z09.5.0.42.eb1p7A&id=20149064414
(2)        夏普GP2Y1010AU0F_粉尘传感器 在新中发地下一层买的,好像45元吧。


(3)        SHT10温湿度传感器 购买地同上 40元。

(4)        LCD12864 5V 蓝屏 带背光 中文字库 ST7920 提供驱动程序
淘宝购入,42元,链接如下:
http://item.taobao.com/item.htm?spm=a1z09.5.0.40.eDhp4p&id=10495880170

(5)        Enc28j60 独立以太网控制器,远程控制的关键部,28元,新中发地下淘得。

(6)        数据系统平台:乐联网http://www.lewei50.com
3.        硬件连接

(1)        夏普GP2Y1010AU0F_粉尘传感器(按图示方式放置,从左到右分别为1~6脚)
Sharp pin 1 (V-LED) => 5V (串联150Ω电阻,pin 1和电阻之间连220μF电容接地);
Sharp pin 2 (LED-GND) => Arduino GND脚;
Sharp pin 3 (LED) => Arduino 数字口pin 2 ;
Sharp pin 4 (S-GND) => Arduino GND 脚;
Sharp pin 5 (Vo) => Arduino 模拟口A0pin;
Sharp pin 6 (Vcc) => 5V;
(2)        SHT10
SHT10 pin s (时钟)=>Arduino 数字口 pin 9;
SHT10 pin d (数据) =>Arduino 数字口 pin 7;
SHT10 pin + => 5V;
SHT10 pin - => Arduino GND脚;
(3)        LCD12864连接,使用了SPI接法,数据传输只需使用pin 3,9,8
pin1 = Arduino GND;
pin2 = 5V;
rs(CS) = Arduino pin 8;
rw(SID)= Arduino pin 9;
en(CLK) =Arduino pin 3;
psb = Arduino GND脚;
(4)        ENC28J60模块的连接。
Vcc => Arduino Vcc;
Reset => Arduino Reset;
Enc-int =>Arduino 数字口pin 2;
GND => Arduino GND;
Sck => Arduino pin 13;
Miso => Arduino pin 12;
Mosi => Arduino pin 11;
Cs => Arduino pin 10.

/* Interface to Sharp GP2Y1010AU0F Particle Sensor Program by Christopher Nafis Written April 2012 http://www.sparkfun.com/datasheets/Sensors/gp2y1010au_e.pdf http://sensorapp.net/?p=479
Sharp pin 1 (V-LED) => 5V (connected to 150ohm resister)
Sharp pin 2 (LED-GND) => Arduino GND pin
Sharp pin 3 (LED) => Arduino pin 2
Sharp pin 4 (S-GND) => Arduino GND pin
Sharp pin 5 (Vo) => Arduino A0pin
Sharp pin 6 (Vcc) => 5V */

/*
LCDArduino
PIN1 = GND
PIN2 = 5V
RS(CS) = 8;
RW(SID)= 9;
EN(CLK) = 3;
PIN15 PSB = GND;
*/   

#include <SD.h>
#include "LCD12864RSPI.h"
#include <SHT1x.h>
#define dataPin7   // DATA
#define clockPin 9   // SCK
#define AR_SIZE( a ) sizeof( a ) / sizeof( a )
SHT1x sht1x(dataPin, clockPin);
float temp_f;
float temp_c;
float humidity;// Read values from the sensor
float dustVal=0;
float voltage=0;
float dustdensity=20;
float tempdustdensity = 0;
float ppmpercf=0;
float offTime=9680;
float sum1=0;
float sum2=0;
float sum3=0;
float aver=0;
int chipSelect = 4;
int dustPin=0;
int i=10;
int ledPower=2;
int delayTime=280;
int delayTime2=40;
int fanPower=6;
char str1; //定义温度值存储数组,4位,其中3位为数字,1位为小数点
char str2;//温度
char str3;//湿度
char str4;//平均灰尘密度
char s; //灰尘粒子
float temp1=0; //定义中间变量,用于将获取的float型温度值转变为unsigned char数组
float temp2=0;
float temp3=0;
double tempa=0;
double tempb=0;
double tempc=0;
unsigned char show1[]={0x70, 0x00,0x6D, 0x00,0x32, 0x00,0x2E, 0x00,0x35, 0x00,0xA3, 0xBA };                  //pm2.5:
unsigned char show2[]={0xCE, 0xC2,0xB6, 0xC8,0xA3, 0xBA};    //温度:
unsigned char show3[]={0xCA, 0xAA,0xB6, 0xC8, 0xA3, 0xBA};//湿度:
unsigned char Str01[]={0xA6, 0xCC,0x67, 0x00,0x2F, 0x00,0x6D, 0x00,0x33, 0x00 };                  //μg/m3
unsigned char Str02[]={0xA1, 0xE6 };                  //℃
unsigned char Str00[]={0x25, 0x00 };                  //%

void setup()
{
Serial.begin(9600);
pinMode(ledPower,OUTPUT);//make the GP2Y work
pinMode(7, OUTPUT);
pinMode(10, OUTPUT);
pinMode(fanPower,OUTPUT);   
digitalWrite(fanPower,LOW); //继电器控制脚
LCDA.Initialise(); // 屏幕初始化
unsigned char opening[]={
0xCF, 0xB5,
0xCD, 0xB3,
0xB3, 0xF5,
0xCA, 0xBC,
0xBB, 0xAF,
0xA3, 0xAE,
   };                  //系统初始化...
unsigned char opening2[]={0xA3, 0xAE};

LCDA.DisplayString(1,0,opening,AR_SIZE(opening));
delay(1000);
   LCDA.DisplayString(1,6,opening2,AR_SIZE(opening2));
delay(1000);
LCDA.DisplayString(1,7,opening2,AR_SIZE(opening2));
delay(5000);
LCDA.CLEAR();
}
void loop()
{
LCDA.DisplayString(0,0,show1,AR_SIZE(show1));//第一行第1格开始,显示文字
LCDA.DisplayString(2,0,show2,AR_SIZE(show2));
LCDA.DisplayString(3,0,show3,AR_SIZE(show3));
sum1=0;
sum2=0;
sum3=0;
for(i=20;i>=0;i--)
{

    digitalWrite(ledPower,LOW); // power on the LED
    delayMicroseconds(delayTime);
    dustVal=analogRead(dustPin);
    voltage = dustVal*0.0049;
    tempdustdensity =(0.172*voltage-0.0999)*2000;//临时灰尘质量浓度
    temp_c = sht1x.readTemperatureC();//读温度值
    temp_f = sht1x.readHumidity();// 读湿度值
    dustdensity=tempdustdensity;
    delayMicroseconds(delayTime2);
    digitalWrite(ledPower,HIGH); // turn the LED off
    delayMicroseconds(offTime);
    sum1=sum1+dustdensity;
    sum2=sum2+temp_c;
    sum3=sum3+temp_f;
    delay(300);
}
    temp1=sum1/20;
    tempa=temp1;
    if(temp1<40)
    {
      digitalWrite(fanPower,LOW); // power off the fan
    }
    if(temp1>40)
    {
      digitalWrite(fanPower,HIGH); // power on the fan
    }
    temp2=sum2/20;
    tempb=temp2;
    temp3=sum3/20;
    tempc=temp3;
    static char tempStr1;
    static char tempStr2;
    static char tempStr3;
    String dataString="";
    floatToString(temp1,tempStr1);
    dtostrf(tempa,4,2,str1);
    dataString += String(tempStr1);
    dataString += ",";
    floatToString(temp2,tempStr2);
    dtostrf(tempb,4,2,str2);
    dataString += String(tempStr2);
    dataString += ",";
    floatToString(temp3,tempStr3);
    dtostrf(tempc,4,2,str3);
    dataString +=String(tempStr3);
    Serial.println(dataString);
    LCDA.DisplayString(1,0,(unsigned char *)str1,sizeof(str1)); //pm2.5
    LCDA.DisplayString(1,3,(unsigned char *)Str01,sizeof(Str01));//pm2.5danwei
    LCDA.DisplayString(2,3,(unsigned char *)str2,sizeof(str2));//wendu   
    LCDA.DisplayString(2,6,(unsigned char *)Str02,sizeof(Str02));//wendu danwei
    LCDA.DisplayString(3,3,(unsigned char *)str3,sizeof(str3));//shidu
    LCDA.DisplayString(3,5,(unsigned char *)Str00,sizeof(Str00));//shidu danwei
    delay(3000);
}
void floatToString(float in,char* out){
uint16_t Tc_100 = in*10;
uint8_t whole, fract;
whole = Tc_100/10 ;// separate off the whole and fractional portions
fract = Tc_100 % 10;
sprintf(out,"%d.%d",whole,fract);
}

小滴 发表于 2013-6-3 21:00:58

远程控制代码:来自乐联网http://www.geek-workshop.com/thread-3099-1-1.html// Simple demo for feeding some random data to Pachube.
// 2011-07-08 <[email protected]> http://opensource.org/licenses/mit-license.php
#include <EtherCard.h>
byte Ethernet::buffer;
// change these settings to match your own setup
#define FEED    "5942"
#define APIKEY"b3249xxxxxxxxxe1b0c"

// ethernet interface mac address, must be unique on the LAN
byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

char website[] PROGMEM = "open.lewei50.com";
const int ledPin = 6;

char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;
char*udpReply="{\"deviceName\":\"01\",\"username\":\"laoliu1982\",\"port\":80,\"api\":\"api\",\"requestType\":\"get\"}";
#define gPB ether.buffer
#define UDP_DP_HIGH 36
#define UDP_DP_LOW 37
#define DSTPORT_HIHG 0x26
#define DSTPORT_LOW 0xe7

int x=1;
int sensorValue = 0;
int sensorPin = A0;
uint32_t timer;
Stash stash;
void setup ()
{
Serial.begin(9600);
Serial.println("\n");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
buttonLabel = "0";
if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))   
Serial.println( "Failed to access Ethernet controller");
else
Serial.println("Ethernet controller initialized");
if (!ether.dhcpSetup())   
Serial.println("DHCP failed");
ether.printIp("IP:", ether.myip);
ether.printIp("GW:", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
if (!ether.dnsLookup(website))   
Serial.println("DNS failed");
ether.printIp("SRV: ", ether.hisip);   
Serial.println("\n webClient setup end");
}
void loop ()
{
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
if(len)
{   
if(gPB==IP_PROTO_UDP_V)   
{      
    if((gPB==DSTPORT_HIHG)&&(gPB==DSTPORT_LOW))
    {         
    Serial.println("---Received an udp 9959 packet---");   
    //ether.sendUdp(udpReply,strlen(udpReply),60000,(gPB + IP_SRC_P),9960);         
ether.leweiUdpReply(udpReply,strlen(udpReply),9960);   
}   
}   
}
if(pos)
{   
Serial.print("len:");
Serial.println(len);   
if(strstr((char *)Ethernet::buffer + pos, "&f=getAllSensors") != 0)   
{
    Serial.println("Received GetAllSensor command");   
    BufferFiller bfill = ether.tcpOffset();   
    bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"   
    "Content-Type: text/html\r\n Pragma: no-cache\r\n\r\n"   
    "{\"successful\":true,\"message\":null,\"data\":[{\"id\":\"1\",\"type\":\"jdq\",\"name\":\"s1\",\"value\":\"$$S\",\"status\":\"ok\"}]}"),buttonLabel);   
ether.httpServerReply(bfill.position());   
}
if(strstr((char *)Ethernet::buffer + pos, "&f=updateSensor&p1=1&p2=0") != 0)   
{   
    Serial.println("Received OFF command");   
    BufferFiller bfill = ether.tcpOffset();   
    bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"   
    "Content-Type: text/html\r\n Pragma: no-cache\r\n\r\n"   
"{\"data\":{\"id\":\"1\",\"type\":\"jdq\",\"name\":\"s1\",\"value\":\"0\",\"status\":\"ok\"},\"successful\":true,\"message\":null}"));
ether.httpServerReply(bfill.position());   
digitalWrite(ledPin, LOW);      
buttonLabel="0";   
}   
if(strstr((char *)Ethernet::buffer + pos, "&f=updateSensor&p1=1&p2=1") != 0)   
{   
Serial.println("Received ON command");
BufferFiller bfill = ether.tcpOffset();
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n Pragma: no-cache\r\n\r\n"
"{\"data\":{\"id\":\"1\",\"type\":\"jdq\",\"name\":\"s1\",\"value\":\"1\",\"status\":\"ok\"},\"successful\":true,\"message\":null}"));   
ether.httpServerReply(bfill.position());   
digitalWrite(ledPin, HIGH);      
buttonLabel="1";
}
}
if (millis() > timer)
{
    //timer = millis() + 10000;
    timer = millis() + 3000;   
sensorValue = analogRead(sensorPin);   
//Serial.println(x);
Serial.println(sensorValue);   
// generate two fake values as payload - by using a separate stash,   
// we can determine the size of the generated message ahead of time
x=x+1;
byte sd = stash.create();   
stash.print("[{\"Name\":\"s1\",\"Value\":");   
//stash.print((word)x);   
stash.print((word)sensorValue);   
stash.print("},{\"Name\":\"T1\",\"Value\":");      
stash.print((word)x);   
stash.println("}]");
stash.save();

// generate the header with payload - note that the stash size is used,
// and that a "stash descriptor" is passed in as argument using "$$H"   

Stash::prepare(PSTR("POST /api/V1/Gateway/UpdateSensors/01 HTTP/1.1\r\n"
"Host: open.lewei50.com\r\n"                  
"Content-Length: $$D\r\n"                  
"userkey: $$F\r\n"                  
"\r\n"                  
"$$H"),stash.size(), PSTR(APIKEY),sd);   
// send the packet - this also releases all stash buffers once done
ether.tcpSend();
}
}

小滴 发表于 2013-6-3 21:04:53

文中想插几个传感器的图没插进去啊:L

chqiyi 发表于 2013-6-3 21:31:16

沙发板凳都木有了,
楼主的好贴,收藏了找时间好好学习:)

chqiyi 发表于 2013-6-3 21:33:21

楼主,线路图模糊不清,能否把所有资料打包提供下载给予学习的机会哈?谢谢!

小滴 发表于 2013-6-3 21:34:51

我可以把我参考过的帖子都发出来,其实基本上在极客工坊就可以搜得到

小滴 发表于 2013-6-3 21:38:36

http://www.howmuchsnow.com/arduino/airquality/grovedust/
http://www.guokr.com/article/434130/
http://sensorapp.net/?p=479
http://www.geek-workshop.com/thread-3829-1-1.html
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=1747
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=3121
http://www.geek-workshop.com/thread-3099-1-1.html
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=2260
http://www.howmuchsnow.com/arduino/airquality/grovedust/

chqiyi 发表于 2013-6-3 22:09:45

谢谢楼主小滴:)

philhoo 发表于 2013-6-3 22:43:35

准备把我的实验放在论坛上呢,你这么快就发表啦!

小滴 发表于 2013-6-4 12:01:09

chqiyi 发表于 2013-6-3 22:09 static/image/common/back.gif
谢谢楼主小滴

不用谢啦···我这么水的···

小滴 发表于 2013-6-4 12:01:29

philhoo 发表于 2013-6-3 22:43 static/image/common/back.gif
准备把我的实验放在论坛上呢,你这么快就发表啦!

您是哪位?

laoliu1982 发表于 2013-6-5 12:38:54

{:soso_e183:}

↗丶う鎻薆ぬ 发表于 2014-1-12 19:34:31

lz,求指导啊

coordinate 发表于 2014-3-1 11:23:27

楼主,图中的u5 sd是什么东西,在材料单里没有啊?

coordinate 发表于 2014-3-1 12:44:56

楼主,那个电路图里的u5 sd是什么东西,为什么材料清单里面没有?
页: [1] 2
查看完整版本: 使用Arduino及乐联网平台搭建家居环境监测调节系统