找回密码
 立即注册

QQ登录

只需一步,快速开始

点击进入授权页面

只需一步,快速开始

  • QQ空间
  • 回复
  • 收藏

参加活动: 2

组织活动: 0

  • TA的每日心情

    2017-9-1 00:12
  • 签到天数: 65 天

    [LV.6]常住居民II

    本帖最后由 吹口琴的钢铁侠 于 2016-11-3 23:43 编辑

    参赛项目:Ulink

    参赛组员:
    1人——某高三        

    联系方式
          如果想做这个项目,但觉得有困难,请直接联系
         微信号  ====
         QQ群   291715187
    商业用途请用上述联系方式及时联系我。

    想要以此衍生做毕设或参加比赛的同学请注意:


    88x31.png


    还有那些转载到各种个人网站和博客的大哥们:
    既然没更新代码,没更新图片,,至少给我加个转载署名吧???




    由于新浪云的不断更新,许多界面有所变化,操作也有变化,目前需要新浪云实名认证,有些步骤类似,也有些步骤完全不一样了,多百度百度就行了。

    项目介绍:
    用Arduino控制物联网的方案很多,被控端和控制端的连接方式也有很多,比如蓝牙,Wifi,433Mhz模块;如果涉及到互联网和手机的远程控制,也有一些成熟的业界方案,比较普遍的是一些物联网公司比如智能插座,一个公司专门推出一个专门的App,每个App都长得各种各样,有些操作方便,有些麻烦。


    当我有一天看到有人用微博控制Arduino的时候,感觉相当酷炫,但是微博控制的方便性和安全性是不高的,同时微信却有极高的安全性,对于每天使用微信的人来说,操作显然是最方便的。

    整个项目的开发,主要是软件层面,因为控制实现以后,只要把点亮LED的代码改成别的,就可以控制另外的设备了,成功之后才发现,需要的技能其实不少:
    Linux,Arduino,PHP,微信公众平台开发,MySQL
    如果如果你原本只是玩Arduino或硬件的,这时候去看我的代码(虽然我也是自己学的,写的也很短),PHP网络之类的比较难懂,这也是为什么我不能够把我所有的开发流程一下子写出来的原因。即使你有了我的服务器代码,然后再去进行自己的架设,那也不是随便改几个参数就可以的,我也想过直接开发一个 物联网平台,无奈一转眼已经高三。
    换句话说,只要修改相应的代码,其他有关物联网远程控制或数据获取的参赛项目都可以接入本项目,使得操作更加方便


    代码全在Github。https://github.com/llLord/Ulink/tree/master/V2.5
    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
    整个原理是不难理解的。

    捕获.PNG


    控制Arduino
    首先服务器上有一个数据库,数据库里面有几个记录,每个开关都有一个对应的值。
    在微信中,我们对一个公众平台发送类似于“开灯”,“打开热水器”之类的命令,以“开灯”为例公众平台的后台服务器会对这个命令进行判断,如果符合预设的命令,就会进入数据库,找到这个LED对应的记录,把这个记录对应的值改为“1”(值其实是随意的)。
            这里的命令发送方式包括文字消息,语音消息。

    与此同时,Arduino通过W5100扩展板,不断向一个服务器上的页面发送请求,请求中会包含一些诸如请求的开关ID,密码等参数,服务器核实后,就会进入数据库,找到对应的开关的记录,把对应的值“1”反馈给Arduino,Arduino收到反馈后,就会进行判断,如果是“1”,就把对应引脚上的LED点亮。如果是”0“,就把它熄灭。                        Arduino的这个过程是不断的进行的,但由于网络和性能问题,通常会有几秒钟的延迟。
    2.png


    1.png



    Arduino提交物联网数据
    这次首先是Arduino通过一些连接方式,接收到物联网的相关数据,比如温度值”26“,然后向服务器上的一个页面提交请求,请求中包括传感器ID,密码,提交的数据等参数,服务器核实后,就会进入数据库,把传递上来的值,写入相应的传感器记录。          这个过程也是不断的进行的。


    而用户需要这些数据的时候,就可以通过微信发送命令,比如”卧室温度“,后台服务器判断后,就会进入数据库,找到相应的传感器记录,提取温度值,编入预设的反馈消息格式比如“报告主人,卧室温度为26℃。
    0.png

    --------------------------------------------------------------------------鉴于许多朋友可能认为本项目难以上手,所以详细的记录了一遍部属的过程
    实例:
    首先是服务器和微信端,
    服务器端选择新浪云,毕竟这是不买VPS的一种比较好的方案,如果有自己的服务器,那么看了代码就懂了,也就不用看服务器端的部署了:)。
    http://sae.sina.com.cn/,注册并登录,应该有免费云豆吧。
    在管理页面选择创建新应用。
    0.PNG

    数据可以这么填,有些空会影响后面的过程
    1.PNG

    进入该应用的管理页面,并选择左边的代码管理
    2.PNG

    编辑代码
    3.PNG

    编辑器
    4.PNG

    添加文件
    捕获151.PNG

    粘贴下面的代码,注意修改代码,有些值后面会看到
    [PHP] 纯文本查看 复制代码
    <?php  if ($_GET['data'] && ($_GET['token'] == "doubleq")) {//可以改token,这相当于密码,在Arduino端改成相应的值即可
            $con = mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); 
            $data = $_GET['data'];
            mysql_select_db("app_ulink42", $con);//要改成相应的数据库名
    
            $result = mysql_query("SELECT * FROM switch");
            while($arr = mysql_fetch_array($result)){//找到需要的数据的记录,并读出状态值
                    if ($arr['ID'] == 1) {
                            $state = $arr['state'];
                    }
            }
            $dati = date("h:i:sa");//获取时间
            $sql ="UPDATE sensor SET timestamp='$dati',data = '$data'
            WHERE ID = '1'";//更新相应的传感器的值
            if(!mysql_query($sql,$con)){
                die('Error: ' . mysql_error());//如果出错,显示错误
            }
            mysql_close($con);
            echo "{".$state."}";//返回状态值,加“{”是为了帮助Arduino确定数据的位置
    }else{
            echo "Permission Denied";//请求中没有type或data或token或token错误时,显示Permission Denied
    }
    
    ?>


    同样地,把index.php改掉
    [PHP] 纯文本查看 复制代码
    <?php
    
    //错误日志
    function echo_server_log($log){
            file_put_contents("log.txt", $log, FILE_APPEND);
    }
    
    //定义TOKEN
    define ( "TOKEN", "ulink" );
    
    //验证微信公众平台签名
    function checkSignature() {
            $signature = $_GET ['signature'];
            $nonce = $_GET ['nonce'];
            $timestamp = $_GET ['timestamp'];
            $tmpArr = array ($nonce, $timestamp, TOKEN );
            sort ( $tmpArr );
            
            $tmpStr = implode ( $tmpArr );
            $tmpStr = sha1 ( $tmpStr );
            if ($tmpStr == $signature) {
                    return true;
            }else{
                    return false;
            }
    }
    if(false == checkSignature()) {
            exit(0);
    }
    
    //接入时验证接口
    $echostr = $_GET ['echostr'];
    if($echostr) {
            echo $echostr;
            exit(0);
    }
    
    //获取POST数据
    function getPostData() {
            $data = $GLOBALS['HTTP_RAW_POST_DATA'];
            return        $data;
    }
    $PostData = getPostData();
    
    //验错
    if(!$PostData){
            echo_server_log("wrong input! PostData is NULL");
            echo "wrong input!";
            exit(0);
    }
    
    //装入XML
    $xmlObj = simplexml_load_string($PostData, 'SimpleXMLElement', LIBXML_NOCDATA);
    
    //验错
    if(!$xmlObj) {
            echo_server_log("wrong input! xmlObj is NULL\n");
            echo "wrong input!";
            exit(0);
    }
    
    //准备XML
    $fromUserName = $xmlObj->FromUserName;
    $toUserName = $xmlObj->ToUserName;
    $msgType = $xmlObj->MsgType;
    
    
    if($msgType == 'voice') {//判断是否为语音
            $content = $xmlObj->Recognition;
    }elseif($msgType == 'text'){
            $content = $xmlObj->Content;
    }else{
            $retMsg = '只支持文本和语音消息';
    }
    
    if (strstr($content, "温度")) {
            $con = mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); 
            mysql_select_db("app_ulink42", $con);//修改数据库名
    
            $result = mysql_query("SELECT * FROM sensor");
            while($arr = mysql_fetch_array($result)){
              if ($arr['ID'] == 1) {
                      $tempr = $arr['data'];
              }
            }
            mysql_close($con);
    
        $retMsg = "报告大王:"."\n"."主人房间的室温为".$tempr."℃,感谢您对主人的关心";
    }else if (strstr($content, "开灯")) {
            $con = mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); 
    
    
            $dati = date("h:i:sa");
            mysql_select_db("app_ulink42", $con);//修改数据库名
    
            $sql ="UPDATE switch SET timestamp='$dati',state = '1'
            WHERE ID = '1'";//修改开关状态值
    
            if(!mysql_query($sql,$con)){
                die('Error: ' . mysql_error());
            }else{
                    mysql_close($con);
                    $retMsg = "好的主人";
            }
    }else if (strstr($content, "关灯")) {
            $con = mysql_connect(SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); 
    
    
            $dati = date("h:i:sa");
            mysql_select_db("app_ulink42", $con);//修改数据库名
    
            $sql ="UPDATE switch SET timestamp='$dati',state = '0'
            WHERE ID = '1'";//修改开关状态值
    
            if(!mysql_query($sql,$con)){
                die('Error: ' . mysql_error());
            }else{
                    mysql_close($con);
                    $retMsg = "好的主人";
            }        
    }else{
            $retMsg = "暂时不支持该命令";
    }
    
    //装备XML
    $retTmp = "<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[text]]></MsgType>
                    <Content><![CDATA[%s]]></Content>
                    <FuncFlag>0</FuncFlag>
                    </xml>";
    $resultStr = sprintf($retTmp, $fromUserName, $toUserName, time(), $retMsg);
    
    //反馈到微信服务器
    echo $resultStr;
    ?>




    回到应用管理页面,选择左边的MySQL,单击初始化
    34124.PNG

    管理MySQL
    12532.PNG

    新建数据表
    12512512.PNG

    参数如下
    1412512.PNG 同样的方法,建立一个名字为sensor字段数为3的数据表
    参数如下
    125125.PNG
    分别插入一条记录
    12.PNG
    13.PNG

    然后进入http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index,申请测试号,
    填写相应配置
    3253.PNG
    这时候可以用手机端进行测试了,可以发送包含”温度“,”关灯“,”开灯“的文字消息,或者语音消息,都会有相应的反馈。

    还有Arduino端在下面的代码中,我把一个LED接在D7上,用于显示控制的效果,一个DS18B20接在D2上,用来显示上传传感器数据的效果。
    [C] 纯文本查看 复制代码
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <SPI.h>
    #include <Ethernet.h>
    
    
    char state = '0';
    char c;
    byte mac[] = { 
      0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
    IPAddress ip(192,168,0,177);
    
    IPAddress myDns(192,168,0,1);
    
    EthernetClient client;
    
    char server[] = "1.ulink42.sinaapp.com";
    int sensrdata = 0;
    
    unsigned long lastConnectionTime = 0;          
    boolean lastConnected = false;                 
    const unsigned long postingInterval = 200*1000;  
     
    // 定义DS18B20数据口连接arduino的2号IO上
    #define ONE_WIRE_BUS 2
     
    // 初始连接在单总线上的单总线设备
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
     
    void setup(){
      // 设置串口通信波特率
      Serial.begin(9600);
      delay(1000);
      Ethernet.begin(mac, ip, myDns);
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      pinMode(7, OUTPUT);   
      // 初始库
      sensors.begin();
    }
     
    void loop(void){ 
      sensors.requestTemperatures();
      sensrdata = sensors.getTempCByIndex(0); 
    
      if(state == '0'){
        digitalWrite(7, LOW);      
      }else if(state == '1'){
        digitalWrite(7, HIGH);
      }
    
      while(client.available()) {
        c = client.read();
        if (c == '{'){
          state = client.read();
        }
      }
    
      if (!client.connected() && lastConnected) {
        Serial.println("disconnecting.");
        client.stop();
      }
    
      if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
        if (client.connect(server, 80)) {
    
          // send the HTTP PUT request:
          client.print("GET /downup.php?token=doubleq&data=");
          client.print(sensrdata);
          client.println(" HTTP/1.1");
          client.println("Host: 1.ulink42.sinaapp.com");
          client.println("User-Agent: arduino-ethernet");
          client.println("Connection: close");
          client.println();
    
          lastConnectionTime = millis();
        }else {
          Serial.println("connection failed");
          Serial.println("disconnecting.");
          client.stop();
        }
      }
      lastConnected = client.connected();
    }





    番外篇:
    由于这是一个物联网平台,所以只要是可以发起HTTP请求的,都可以接入。
    一个比较合理的方案是,树莓派或PCduino做连接互联网的主要控制器,通过XBee,433Mhz等无线方式来控制小型的Arduino节点,再由Arduino来控制物联网终端,当然,如果你不介意网络扩展板的价格,每个Arduino直接联网也是可以的。

    树莓派
    使用Python,requests库,用更强的性能,可以实现更加更快速的反应。


    PCduino
    暑假参加了一个黑客马拉松,用了PCduino来实现微信的控制,因为PCduino上直接跑了一个Ubuntu,队友用Python直接写了一个WebSocket类型的连接方式,我目前还没有学会这个技术(是没时间呀TAT),使用WebSocket的话,资源消耗会小很多,而响应速度会快很多,失败几率也会大幅下降,但是Arduino应该不能使用WebSocket吧??


    捕获.PNG


    项目验证(见附件)
    [img]file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\929351469\QQ\WinTemp\RichOle\V}M6~Y0)ZOM[7~0DM9]$J{N.jpg[/img]

    [img]file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\929351469\QQ\WinTemp\RichOle\V}M6~Y0)ZOM[7~0DM9]$J{N.jpg[/img]
    实际使用中出现的错误主要是新浪云,使用自己的服务器时很少出现此类故障。
    视频说明     10月7日前发布    (上传速度50KB/s  TAT)













    验证

    验证
    脱单缺基金_(xз」∠)_

    2人打赏

    本帖最后由 shsuming 于 2016-3-13 21:30 编辑

    没有看到开关灯的效果,程序和数据库里面的状态都是正常的,微信发指令的时候,switch值有变化。就是没看到开关灯的效果~LED负——D7,LED正——5V,是这么接的么?
    反正被你的一句话“转眼到高三”刺激到了,哎,老了老了,老了才想到关注一下这个
    本帖最后由 shsuming 于 2016-3-2 13:12 编辑
    sunnyboy 发表于 2015-7-22 20:28
    为什么我做的一直配置失败?请问你当时做的时候有什么注意事项么?

    终于知道为什么了。。。要在第34行 echo $_GET['echostr'];前加header('content-type:text');
    在index.php的构造函数中将原来的exit($_GET['echostr'])改为:
    header('content-type:text');
            echo $_GET['echostr'];
            exit();
    就可以了http://bbs.csdn.net/topics/391022271
    素还真 发表于 2014-9-29 17:53
    这是我照楼主做的效果,原理上应该是大同小异吧,实现了,开灯和关灯的功能,用到的一些硬件,Arduino UN ...

    明明就是照人家的做的,还说什么大同小异?

    要上学了,视频以后补上行吗:)
    脱单缺基金_(xз」∠)_

    1人打赏

    吹口琴的钢铁侠 发表于 2014-9-21 11:50
    要上学了,视频以后补上行吗:)

    可以,不过尽量早点,到时候网络评分的时候会参考视频中的实物效果
    打赏作者鼓励一下!
    本帖最后由 vanjok 于 2014-9-22 16:06 编辑

    坐等十一{:soso_e144:},但是你的微信号加不了真伤心。
    vanjok 发表于 2014-9-22 15:23
    坐等十一,但是你的微信号加不了真伤心。

    前面两个小写L
    脱单缺基金_(xз」∠)_
    本帖最后由 素还真 于 2014-10-16 08:24 编辑
    海神 发表于 2014-9-22 10:15
    可以,不过尽量早点,到时候网络评分的时候会参考视频中的实物效果


    这是我照楼主做的效果,实现了,开灯和关灯的功能,用到的一些硬件,Arduino UNO,W5100模块,能上微信的手机,软件方面, 新浪云,Arduino开发工具,mysql,微信开发平台。希望能对爱好学习的人有所帮助!联系QQ506062608,希望大家一起交流交流
    已有详细更新
    脱单缺基金_(xз」∠)_

    4人打赏

    膜拜楼主啊,高中生!相形惭愧
    发表评论
    高级模式  
    您需要登录后才可以回帖 登录 | 立即注册  
    关闭

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