找回密码
 立即注册

QQ登录

只需一步,快速开始

点击进入授权页面

只需一步,快速开始

  • QQ空间
  • 回复
  • 收藏

参加活动: 0

组织活动: 0

  • TA的每日心情

    2015-9-22 09:41
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    本帖最后由 智能创客 于 2014-10-11 16:31 编辑

    这篇开始,我们就真正做《网关》升级版教程了,采用arduino+zigbee哦。
    arduino简单易学,zigbee自组网(如果不懂c语言,直接用就好,我们已经刷好自组网代码)!

    这次我们的教程是通过以下配件实现《网关》功能,并在手机端点击按钮,使zigbee模块上的灯闪亮(实现是发送真正的命令了{ckxxxxxxxxx}的格式)!
    通过不同的格式命令就可以操作开、关、接收、发送数据!之后《温湿传感器》《zigbee插座》等就可以直接连上了!

    020.jpg
    上面就是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元
    游客,如果您要查看本帖隐藏内容请回复




    第一部份:arduino板刷上代码。

    一、安装CP2102驱动(USB驱动)
    http://pan.baidu.com/s/1o6iDLcm(下载后直接安装或发现有新硬件就更新驱动)。
    201748fxfey6ea688lfujy.jpg

    二、将CP2102连上arduino板底下的插槽的一定要一一对应哦。
    DTR->DTR
    GND->GND
    TX->RXI
    RX->TXO
    VDD3.3->VCC
    201749awwafvgpfveiceye.jpg

    201749jb99e5ukgo7ztv3t.jpg

    201750y2f7vz3lv3qf01ps.jpg

    201751jbggeeq83qzgqe3e.jpg


    三、刷arduino代码
    大家可以直接在这里下载源代码:
    http://pan.baidu.com/s/1i386zPV(包含arduino软件和所有的库)


    201752p1k5z7ykrzh6yrwk.jpg [size=0.83em]
    [color=rgb(153, 153, 153) !important]





    下面我们就贴上代码(都有注释哦)
    [C] 纯文本查看 复制代码
    #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();
      }
     
    }





    201752ctd5e95etrwmsw99.jpg

    201753c7e7kff1kt7adffk.jpg



    四、插上网线,打开串口就可以测试联网是否成功了!
    201754zvvkxpxgglkvpswp.jpg

    201755y3t0r7adrdwaqd5e.jpg



    第二部份:刷zigbee模块代码
    201755bll9h8eqtqt1qmhi.jpg

    一、将zigbee模块插到zigbee开发板上
    201756vcz6m2io12h2z6w2.jpg

    201756u3dj1pz6zstjeeet.jpg


    二、连上SMARTRF04EB下载器。
    将一边有凸出来的一端与(VDD、RES、NC、DC、GND的NC对应就正确了!
    201757agf95k1gff5v50hd.jpg

    三、安装SMARTRF04EB驱动
    http://pan.baidu.com/s/1dDH1ZX3(安装SmartRFStudio后里面包含有驱动)
    提示:如果刷不成功,点击一下SMARTRF04EB上的RESET(凹进去就用笔撮)。
    201758okmjxqkkm6xsku5s.jpg

    四、安装IAR 8.1,软件比较大,安装后看说明破解就好。
    http://pan.baidu.com/s/1c0b69Ra(下载解压里面有安装说明)

    五、下载zigbee自组网代码。
    http://pan.baidu.com/s/1COxT8(最新ZStack-CC2530-2.5.1自组网代码,已经写好了按键、LED灯功能)
    201759jqpq8f0n8vj4p6qv.jpg
    六、点击编译并下载。

    七、插个LED到zigbee开发板的P1.0和-。

    八、安到arduino板上。
    201759tdhz5hvhye5vyqvf.jpg

    201800t55dky1cdmshzkhd.jpg



    第三步:使用手机测试
    201801h9gvtgwguwl2qgmo.jpg


    一、手机打开m.znck007.com手机控制端。
    201802y22faarmp2az4f4p.jpg


    二、新建一个开关。
    201801o0foezjstf2ssofv.jpg

    三、点击开关,如果发现LED灯闪,说明《网关工作正常了》!
    201803lsrjug2lmuoupppp.jpg


    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图文视频教程
    关注@智能创客http://www.znck007.com(打造DIY创客平台)

    152509p7nojdncjbbjnab1.png
    不错,真是需要的
    我要好好学习!

    不错,真是需要的
    看看怎么样.
    想学学突然看到了这么好的贴
    fever1985 发表于 2014-7-7 17:18
    想学学突然看到了这么好的贴

    哈哈,一起加油……
    灰常酷 喜欢额
    恭喜升级!IBoard+zigbee真心不错!{:soso_e179:}
    发表评论
    高级模式  
    您需要登录后才可以回帖 登录 | 立即注册  
    关闭

    推荐主题 上一条 /4 下一条