上篇WIFI作品DIY教程07-《wifi家居网关》家居控制中心zigbee/nrf24l01等完成了家居网关。
温度湿度的场景用的很多,我们之前的教程也写过非常多的实例,
这次我们采用DS18B20获取温度,DHT11获取湿度,然后传给网关和云端保存数据,供我们观察分析等。
我们需要的配件:温湿传感器板、DS18B20、DHT11、nrf24l01(或zigbee等)
第一部分:DS18B20温度传感器介绍
DS18B20是常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。
第二部分:DHT11湿度传感器介绍
第三部分:下载编译源代码
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 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | /* *NRF24l01针脚连接线 * MISO -> 12 * MOSI -> 11 * SCK -> 13 * Configurable: * CE -> 8 * CSN -> 7 */ #include <SPI.h> #include <Mirf.h> #include <nRF24L01.h> #include <MirfHardwareSpiDriver.h> #include <OneWire.h> int sid=1; //模块类型 int nid=2; //模块编号 //声名变量 const unsigned long interval = 60000; unsigned long last_sent; OneWire ds(A5); float celsius=0.0; float fahrenheit=0.0; int DHT11_PIN=4; int humdity=0; int temperature=0; //NRF24l01 unsigned long nrf24l01nowlast; char nrf24l01buff[33]={0}; char nrf24l01Data; int nrf24l01i=0; void setup() { Serial.begin(115200); char client[10]={0}; //client sprintf (client, "clie%d" ,sid); //初始化Mirf,用于NRF24l01收发 Mirf_Init(0,client,sid); ini_dht11(); Serial.println( "zwifi_wengshitu" ); } void loop() { unsigned long now = millis(); if ( now - last_sent >= interval ) { last_sent = now; celsius=0; humdity=0; run_ds18(); if (celsius>0){ run_dht11(); } if (humdity>0){ char celstr[10]={0}; dtostrf(celsius,4,2,celstr); char data[10]={0}; sprintf (data, "%d.%s" ,humdity,celstr); send_data(data); } } } //初始化Mirf 0初始化1为接收2为发送 void Mirf_Init( int txrx, char *server, int channel){ //初始化Mirf,用于NRF24l01收发 if (txrx==0) { Mirf.spi = &MirfHardwareSpi; Mirf.init(); 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(""); } void run_ds18() { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; //float celsius, fahrenheit; if ( !ds.search(addr)) { //Serial.println("No more addresses."); //Serial.println(); ds.reset_search(); delay(250); return ; } //Serial.print("ROM ="); for ( i = 0; i < 8; i++) { //Serial.write(' '); //Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println( "CRC is not valid!" ); return ; } //Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: Serial.print( "Chip = DS18S20" ); // or old DS1820 type_s = 1; break ; case 0x28: Serial.print( "Chip = DS18B20" ); type_s = 0; break ; case 0x22: Serial.print( "Chip = DS1822" ); type_s = 0; break ; default : Serial.print( "Device is not a DS18x20 family device." ); return ; } ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad //Serial.print(" Data = "); //Serial.print(present,HEX); //Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); //Serial.print(data[i], HEX); //Serial.print(" "); } //Serial.print(" CRC="); //Serial.print(OneWire::crc8(data, 8), HEX); //Serial.println(); // convert the data to actual temperature unsigned int raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // count remain gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms // default is 12 bit resolution, 750 ms conversion time } celsius = ( float )raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; Serial.print( " Temperature = " ); Serial.print(celsius); Serial.print( " Celsius, " ); Serial.print(fahrenheit); Serial.println( " Fahrenheit" ); } void ini_dht11() { DDRC|=_BV(DHT11_PIN); PORTC|=_BV(DHT11_PIN); } byte read_dht11_dat() { byte i = 0; byte result = 0; for (i=0;i<8;i++) { while (!(PINC&_BV(DHT11_PIN))); delayMicroseconds(30); if (PINC&_BV(DHT11_PIN)) result|=(1<<(7-i)); while ((PINC&_BV(DHT11_PIN))); } return result; } void run_dht11() { byte dht11_dat[5]; byte dht11_in; byte i; PORTC &= ~_BV(DHT11_PIN); delay(18); PORTC|=_BV(DHT11_PIN); delayMicroseconds(40); DDRC &= ~_BV(DHT11_PIN); delayMicroseconds(40); dht11_in = PINC & _BV(DHT11_PIN); if (dht11_in) { Serial.println( "dht11 start condition 1 not met" ); return ; } delayMicroseconds(80); dht11_in=PINC & _BV(DHT11_PIN); if (!dht11_in) { Serial.println( "dht11 start condition 2 not met" ); return ; } delayMicroseconds(80); for (i=0;i<5;i++) dht11_dat[i]=read_dht11_dat(); DDRC|=_BV(DHT11_PIN); PORTC|=_BV(DHT11_PIN); byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3]; if (dht11_dat[4]!=dht11_check_sum) { Serial.println( "DHT11 checksum error" ); } Serial.print( "Chip = DHT11 Current humdity= " ); Serial.print(dht11_dat[0],DEC); Serial.print( "." ); Serial.print(dht11_dat[1],DEC); Serial.print( "%" ); Serial.print( "temperature = " ); Serial.print(dht11_dat[2],DEC); Serial.print( "." ); Serial.print(dht11_dat[3],DEC); Serial.println( "C" ); humdity=( int )dht11_dat[0]; temperature=( int )dht11_dat[2]; } // void send_data( char *data){ char server[10]={0}; //server 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); Serial.println(); Mirf_Send(1,server,updateData); char client[10]={0}; //client sprintf (client, "clie%d" ,sid); Mirf_Init(1,client,sid); } |
刷写arduino程序选哪个板?
请选择板是Arduino Uno,并记得选对对应的串口。
刷写ardruino源代码时,提示库不存在?
请联系qq610854837下载zwifi资料,软件下载目录里的arduino-1.0.5,里面包含了教程使用的所有库。
将代码进行编译下载到arduino板上。
3、串口运行查看数据是否正常
在arduino软件里,查看串口数据,记得是115200哦,等1分钟,有如上图,说明下载运行成功了!
程序的原理就是获取到二个传感器芯片的温温度,然后组合成字符{ck00x00xnnnn}发送到网关保存数据,供我们以后分析。
第四部分:检测通信和数据库记录
打开:http://192.168.1.1/znck007/mysqltest.php?mode=select
点击查看数据库记录,001,002的记录,说明网关成功保存了记录。30.20.50代表,湿度30%,温度是20.50度。
同时也可以用数据库软件Navicat for MySQL查看数据记录!