本帖最后由 智能创客 于 2014-10-11 16:26 编辑
这篇开始,我们就真正做《网关》升级版教程了,采用arduino+zigbee哦。
arduino简单易学,zigbee自组网(如果不懂c语言,直接用就好,我们已经刷好自组网代码)!
这次我们的教程是通过以下配件实现《网关》功能,并在手机端点击按钮,使zigbee模块上的灯闪亮(实现是发送真正的命令了{ckxxxxxxxxx}的格式)!
通过不同的格式命令就可以操作开、关、接收、发送数据!之后《温湿传感器》《zigbee插座》等就可以直接连上了!
上面就是arduino开源网关的配件。
1、SMARTRF04EB(ZIGBEE下载器)35元
2、CP2102(arduino下载器)15元
3、电源供电 10元
4、arduino板(含w5100、zigbee插槽、SD卡座)100元
5、zigbee开发板 30元 (如果只想学zigbee只需要两块开发板和zigbee模块,自组网学习哦)
6、zigbee模块 45元
本帖隐藏的内容一共是235元,实现自己的arduino开源网关吧(自己有arduino和w5100是可以代替我们的arduino板的)。
第一部份:arduino板刷上代码。
一、安装CP2102驱动(USB驱动)
http://pan.baidu.com/s/1o6iDLcm(下载后直接安装或发现有新硬件就更新驱动)。
二、将CP2102连上arduino板底下的插槽的一定要一一对应哦。
DTR->DTR
GND->GND
TX->RXI
RX->TXO
VDD3.3->VCC
三、刷arduino代码
大家可以直接在这里下载源代码:
http://pan.baidu.com/s/1i386zPV(包含arduino软件和所有的库)
下面我们就贴上代码(都有注释哦)
- #include <iBoardRF24Network.h>
- #include <iBoardRF24.h>
- #include <digitalWriteFast.h>
- #include <SPI.h>
- #include <Ethernet.h>
-
-
-
- //请到m.znck007.com申请登陆-》家中环境-》网关,里可以看到!
- #define APIKEY "xxxxxxxxxxxxxxxx" //设置apikey
-
- uint16_t sid=001;//设置sid(设备号)
-
-
-
- //NRF24l01发送接收节点
- const uint16_t this_node = 0;
- const uint16_t other_node = 1;
-
- //NRF24l01收发数据
- struct payload_t
- {
- uint32_t ms;
- uint32_t data;
- char sendchar[20];
- };
-
- //NRF24l01脚针设置
- iBoardRF24 radioSend(3,8,5,6,7,2);
- iBoardRF24Network networkSend(radioSend);
-
- bool ispayload=false;//NRF24l01收发判断
- uint16_t sendChannel=1;//NRF24l01发送频道
- uint32_t sendCount=0;//NRF24l01发送次数
-
- char incomingData[20]={0};//NRF24l01接收到的字符(其它设置发过来)
-
-
-
-
-
- //设置MAC地址,如果有二个请改为不同(随意)
- static byte mymac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
-
- EthernetClient client;//声明网关类
-
- char server[] = "api.znck007.com";//声明API网址
- //char urlBuf[] = "/index.php";
-
- static long timer;//用于规定时间间隔
- unsigned long last_http;//记录http时间,用于http超时判断,目前20秒无响应则重新GET。
- bool ishttpget=false;//标示http是否已经结束
-
-
-
- bool isUpdate=false;//成功则更新服务器数据为正常
- char updateData[20]={0};//更新的字符(服务器通过字符分析指定某个设备)
-
- //串口通信处理(主要用于zigbee通信)
- unsigned long serialnowlast;
- char serialbuff[80]={0};
- char serialData;
- int seriali=0;
-
-
-
- void setup(void)
- {
- //设置串口波特率
- Serial.begin(115200);
- Serial.println("IBOARD_GATEWAY_ZIGBEE/RF24Network");
-
- //NRF24l01初始化
- SPI.begin();
- radioSend.begin();
-
- //获取IP DNS等
- Serial.println("\n[getDHCPandDNS]");
- if (Ethernet.begin(mymac) == 0)
- {
- Serial.print(F("Failed to configure Ethernet using DHCP\n"));
- while(1);
- }
- else
- {
- Serial.print("My IP address: ");
- for (byte thisByte = 0; thisByte < 4; thisByte++) {
- // print the value of each byte of the IP address:
- Serial.print(Ethernet.localIP()[thisByte], DEC);
- Serial.print("."); }
- Serial.println("Ethernet configuration OK");
- }
-
- //连接web服务器
- // if you get a connection, report back via serial:
- if (client.connect(server, 80)) {
- Serial.println("connected");
- client.println("GET /index.php HTTP/1.1");
- client.println("Host: api.znck007.com");
- client.println("Connection: close");
- client.println();
- }
- else {
- // kf you didn't get a connection to the server:
- Serial.println("connection failed");
- client.stop();
- }
-
- //判断web服务器是否正常
- timer=millis();
- while ((!client.available()) && (millis()-timer)<2000);
-
- if (client.available()) {
- char c = client.read();
- Serial.print(c);
- client.stop();
- }
- timer = millis();
-
- //完成setup
- Serial.println("setup success");
-
- }
-
-
- void loop(void)
- {
- // //NRF24l01检测接收数处理
- // //如果使用NRF24l01,请启动这里(并删除ZIGBEE检测接收数据处理)
- // networkSend.begin(/*channel*/ sid, /*node address*/ this_node);
- // // Pump the network regularly
- // networkSend.update();
- //
- // // Is there anything ready for us?
- // timer=millis();
- // //while ((!networkSend.available()) && (millis()-timer)<2000);
- // while(networkSend.available())
- // {
- // // If so, grab it and print it out
- // RF24NetworkHeader header;
- // payload_t payload;
- // memset(payload.sendchar, 0, 20);
- // networkSend.read(header,&payload,sizeof(payload));
- // Serial.print("Received packet #");
- // Serial.print(payload.data);
- // Serial.print(" at ");
- // Serial.print(payload.ms);
- // Serial.print(" getchar ");
- // Serial.println(payload.sendchar);
- //
- // ispayload = true;
- //
- // get_html_body(payload.sendchar,incomingData);
- // Serial.println(incomingData);
- // }
- //
- // if(!ishttpget)
- // {
- // if(ispayload)
- // {
- // ispayload = false;
- //
- // if(strstr(incomingData,"{ck") && strstr(incomingData,"}") )
- // {
- // last_http = millis();
- // ishttpget=true;
- //
- // Serial.println("\n>>> POST");
- // static char buf[20]={0};
- // sprintf(buf,"%s",incomingData);
- //
- // client_post(server,APIKEY,buf);
- // my_result_cb();
- //
- // return;
- // }
- //
- // }
- //
- //
- // }
-
-
- //ZIGBEE检测接收数据处理
- if(!ishttpget)
- {
-
- unsigned long serialnow = millis();//获取现在的时间
- if(serialnow - serialnowlast >= 5000)//如果数据间隔超过5秒而清空字符(为了防止数据错乱)
- {
- serialnowlast = millis();
- memset(serialbuff, 0, 80);
- seriali=0;
- }
-
- bool isSerial=false;
- while( Serial.available() )//如果串口有数据(ZIGBEE或电脑发过来的)
- {
- if(seriali==0)
- {
- Serial.println("Serial->");//打印出来方便调试
- }
- serialData=(char)Serial.read();//读取串口数据
- //Serial.print(serialData);////这里不打印,否则ZIGBEE检测到{ckxxxx}就认为是命令
- serialbuff[seriali]=serialData;////保存到数组
- seriali++;////数组长度+1
- if(serialData=='}' || seriali>=80)//如果发现}而说明命令结束(并少于80个字符,太长会出错)
- {
- isSerial=true;
- break;
- }
- }
-
- //开始处理{ckxxxxx}字符,如POST上传到web服务器
- if(isSerial)
- {
- serialnowlast = millis(); //更新当前时间,不然5秒就超时了
-
- //Serial.println(serialbuff);
- char body[81]={0};
- get_html_body(serialbuff,body);//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
- //Serial.println(body);
-
- Serial.println("-------------------");
-
- //如果命令格式真确则POST到web服务器了
- if(strstr(body,"{ck") && strstr(body,"}") )
- {
- last_http = millis();
- ishttpget=true;
- timer = millis();
-
- Serial.println("\n>>> POST");
- //static char buf[81]={0};
- //sprintf(buf,"%s",body);
-
- client_post(server,APIKEY,body);//POST到网址,APIKEY,字符
- my_result_cb();//接收web服务器返回的字符
-
- }
-
- memset(serialbuff, 0, 80);//清空字符
- seriali=0;//字符长度为0
-
- return;
- }
- }
- //delay(200);
-
- //更新web服务器命令的状态(比如发送成功还是失败还是异常等,NRF24l01用到,ZIGBEE不用这里而是直接发送{ck00xxxxxxupdate}命令就行)
- if( isUpdate )
- {
- isUpdate=false;
-
- last_http = millis();
- ishttpget=true;
-
- Serial.println("\n>>> UPDATE");
-
- static char buf[20]={0};
- sprintf(buf,"%s",updateData);
- //Serial.println(buf);
-
- client_post(server,APIKEY,buf);//POST到网址,APIKEY,字符
- my_result_cb();//接收web服务器返回的字符
- isUpdate=false;
-
- return;
- }
-
- //每2秒钟查看web服务器是有命令数据
- unsigned long now = millis();
- if(now - last_http >= 2000)
- {
- if(!ishttpget || (now - last_http) >= 20000)//20秒超时会执行,为了防卡死问题
- {
- last_http = millis();
- ishttpget=true;
-
-
- Serial.println("\n>>> REQ");
- static char buf[20]={0};
- sprintf(buf,"{ck001000000000}"); //这个字符串代表获取新命令数据
- client_post(server,APIKEY,buf);//POST到网址,APIKEY,字符
- my_result_cb();//接收web服务器返回的字符
-
- timer = millis();
-
- }
-
- }
-
-
- }
-
- //接收web服务器返回的字符
- static void my_result_cb(){
- char eth_buffer[350];
- timer=millis();
- while ((!client.available()) && (millis()-timer)<1000);
-
- if (client.available()) {
-
- for(int j=0;client.available()>0;j++)
- {
- char c = client.read();
- eth_buffer[j]=c;
- Serial.print(c);
- }
- client.stop();
- }
- Serial.println();
-
- char body[81]={0};
- get_html_body(eth_buffer,body);//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
- //Serial.println(body);
-
- sendChannel=get_channel(body);//获取是哪个sid,这是m.znck007.com手机客服端里的sid
-
- // //如果使用NRF24l01,请启动这里
- // if( sendChannel>0 )
- // {
- // networkSend.begin(/*channel*/ sendChannel, /*node address*/ other_node);
- //
- // networkSend.update();
- // Serial.println("");
- // Serial.print("Sending...");
- // if(sendCount>1000000) sendCount=0;
- // payload_t payload = { sendChannel, sendCount++, "{ck000000000000}" };//millis()
- // sprintf(payload.sendchar,"%s",body);
- // RF24NetworkHeader header(/*to node*/ this_node);
- // bool ok = networkSend.write(header,&payload,sizeof(payload));
- // if (ok)
- // {
- // Serial.println("ok.");
- //
- // isUpdate=true;
- // char front[10]={0};
- // memcpy(front,body,9);
- // sprintf(updateData,"%supdate}",front);
- // Serial.println(updateData);
- //
- // }
- // else
- // {
- // Serial.println("failed.");
- // }
- // }
-
- ishttpget=false;
- last_http = millis();
-
-
- networkSend.begin(/*channel*/ sid, /*node address*/ this_node);
- networkSend.update();
-
- }
-
-
- //获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
- void get_html_body(char *p,char *s){
-
- char rechar[81]={0};
- int bufi=0;
-
- bool isend=false;
- int charnum=0;
-
- for(bufi=0;bufi<strlen(p);bufi++){
- //Serial.print(p[bufi]);
-
- if(p[bufi]=='{'){
- isend=true;
- }
- if(p[bufi]=='}' && isend==true){
- isend=false;
- rechar[charnum]=p[bufi];
- break;
- }
- if(isend){
- if(charnum<80)
- {
- rechar[charnum]=p[bufi];//Serial.print(rechar[charnum]);
- charnum++;
- }
- }
-
- }
- Serial.println("");
- //memcpy(s,rechar,17);
- sprintf(s,"%s",rechar);
- }
-
- //获取是哪个sid,这是m.znck007.com手机客服端里的sid
- int get_channel(char *buff){
-
- if( strstr(buff,"{ck") && strstr(buff,"}") && strlen(buff)>10)
- {
- char charChannel[4]={0};
- memcpy(charChannel,buff+3,3);
- Serial.println(charChannel);
- int intChannel=atoi(charChannel);
- Serial.println(intChannel);
- return intChannel;
- }
- else
- {
- return 0;
- }
-
- }
-
- //W5100芯片POST字符数据到web服务器
- int client_post(char *server, char *apikey, char *buf){
-
- if (client.connect(server, 80))
- {
- Serial.println("connecting...");
- // send the HTTP PUT request:
- client.print("POST /index.php");
- client.println(" HTTP/1.1");
- client.println("Host: api.znck007.com");
- client.print("apikey: ");
- client.println(APIKEY);
- client.print("Accept: *");
- client.print("/");
- client.println("*");
- client.print("Content-Length: ");
- // calculate the length of the sensor reading in bytes:
- // 8 bytes for {"value":} + number of digits of the data:
- size_t thisLength = strlen(buf);
- client.println(thisLength);
-
- client.println("Content-Type: application/x-www-form-urlencoded");
- client.println("Connection: close");
- client.println();
-
- client.println(buf);
- client.println();
- }
- else
- {
- // kf you didn't get a connection to the server:
- Serial.println("connection failed");
- Serial.println();
- Serial.println("disconnecting.");
- client.stop();
- }
-
- }
复制代码
四、插上网线,打开串口就可以测试联网是否成功了!
第二部份:刷zigbee模块代码
一、将zigbee模块插到zigbee开发板上
二、连上SMARTRF04EB下载器。
将一边有凸出来的一端与(VDD、RES、NC、DC、GND的NC对应就正确了!
三、安装SMARTRF04EB驱动
http://pan.baidu.com/s/1dDH1ZX3(安装SmartRFStudio后里面包含有驱动)
提示:如果刷不成功,点击一下SMARTRF04EB上的RESET(凹进去就用笔撮)。
四、安装IAR 8.1,软件比较大,安装后看说明破解就好。
http://pan.baidu.com/s/1c0b69Ra(下载解压里面有安装说明)
五、下载zigbee自组网代码。
http://pan.baidu.com/s/1COxT8(最新ZStack-CC2530-2.5.1自组网代码,已经写好了按键、LED灯功能)
六、点击编译并下载。
七、插个LED到zigbee开发板的P1.0和-。
八、安到arduino板上。
第三步:使用手机测试
一、手机打开m.znck007.com手机控制端。
二、新建一个开关。
三、点击开关,如果发现LED灯闪,说明《网关工作正常了》!
OK,《网关》部份已经搞定了,下期我们就来上《温湿传感器》《Zigbee插座》《红外控制》!
因为我们还未使用Wifi,所以都需要与《网关》交互数据哦!
等我们Wifi产品出来就可以单独使用了!
《WIFI作品DIY教程》
WIFI作品DIY教程01-《Z WIFI开发板》介绍和联网等配置教程
《Arduino开源智能家居DIY教程系列》
Arduino开源智能家居《花絮1》zigbee小底板DIY成功
Arduino开源智能家居《认识Zigbee》zigbee功能和自组网介绍
Arduino开源智能家居《zigbee开发板》手机/按键点亮LED
Arduino开源智能家居01《网关》升级版网关正式教程(zigbee)
Arduino开源智能家居02《温湿传感器》什么样温湿度才适居
Arduino开源智能家居03《开发板套件》学习zigbee家居-性价比高
Arduino开源智能家居04《插座开关》手机控制:网扇、空调...
Arduino开源智能家居05《红外线》手机红外线控制电器
《百元智能家居DIY教程系列》
arduino教程【实战篇】01《家居网关》DIY图文视频教程
arduino教程【实战篇】02《温湿度》DIY图文视频教程
arduino教程【实战篇】03《智能插座》DIY图文视频教程
arduino教程【实战篇】04《电灯开关》DIY图文视频教程
arduino教程【实战篇】05《手机红外线》DIY图文视频教程
《智能创客DIY交流论坛》成立了
欢迎大家来提问题、交流、学习,共同建立智能的创客平台!
http://www.znck007.com(注册有机会送板子哇!)
|