美文网首页
esp8266接入米家,小爱同学控制

esp8266接入米家,小爱同学控制

作者: qy_ffa1 | 来源:发表于2022-03-10 20:22 被阅读0次

    第一步 下载程序到esp8266

    /*

    * 智能语言控制控制,支持天猫、小爱、小度、google Assistent同时控制

    * 2021-08-12

    * QQ交流群:566565915

    * 官网https://bemfa.com

    */

    #include <ESP8266WiFi.h>

    #define server_ip "bemfa.com" //巴法云服务器地址默认即可

    #define server_port "8344" //服务器端口,tcp创客云端口8344

    //********************需要修改的部分*******************//

    #define wifi_name  "asus"    //WIFI名称,区分大小写,不要写错

    #define wifi_password  "qy123456"  //WIFI密码

    String UID = "2c74942a07014a37836dbb0ea2db0106";  //用户私钥,可在控制台获取,修改为自己的UID

    String TOPIC = "light002";        //主题名字,可在控制台新建

    const int LED_Pin = D2;              //单片机LED引脚值,D2是NodeMcu引脚命名方式,其他esp8266型号将D2改为自己的引脚

    //**************************************************//

    //最大字节数

    #define MAX_PACKETSIZE 512

    //设置心跳值30s

    #define KEEPALIVEATIME 30*1000

    //tcp客户端相关初始化,默认即可

    WiFiClient TCPclient;

    String TcpClient_Buff = "";//初始化字符串,用于接收服务器发来的数据

    unsigned int TcpClient_BuffIndex = 0;

    unsigned long TcpClient_preTick = 0;

    unsigned long preHeartTick = 0;//心跳

    unsigned long preTCPStartTick = 0;//连接

    bool preTCPConnected = false;

    //相关函数初始化

    //连接WIFI

    void doWiFiTick();

    void startSTA();

    //TCP初始化连接

    void doTCPClientTick();

    void startTCPClient();

    void sendtoTCPServer(String p);

    //led控制函数,具体函数内容见下方

    void turnOnLed();

    void turnOffLed();

    /*

      *发送数据到TCP服务器

    */

    void sendtoTCPServer(String p){

      if (!TCPclient.connected())

      {

        Serial.println("Client is not readly");

        return;

      }

      TCPclient.print(p);

    }

    /*

      *初始化和服务器建立连接

    */

    void startTCPClient(){

      if(TCPclient.connect(server_ip, atoi(server_port))){

        Serial.print("\nConnected to server:");

        Serial.printf("%s:%d\r\n",server_ip,atoi(server_port));

        String tcpTemp="";  //初始化字符串

        tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC+"\r\n"; //构建订阅指令

        sendtoTCPServer(tcpTemp); //发送订阅指令

        tcpTemp="";//清空

        /*

        //如果需要订阅多个主题,可再次发送订阅指令

          tcpTemp = "cmd=1&uid="+UID+"&topic="+主题2+"\r\n"; //构建订阅指令

          sendtoTCPServer(tcpTemp); //发送订阅指令

          tcpTemp="";//清空

        */

        preTCPConnected = true;

        preHeartTick = millis();

        TCPclient.setNoDelay(true);

      }

      else{

        Serial.print("Failed connected to server:");

        Serial.println(server_ip);

        TCPclient.stop();

        preTCPConnected = false;

      }

      preTCPStartTick = millis();

    }

    /*

      *检查数据,发送心跳

    */

    void doTCPClientTick(){

    //检查是否断开,断开后重连

      if(WiFi.status() != WL_CONNECTED) return;

      if (!TCPclient.connected()) {//断开重连

      if(preTCPConnected == true){

        preTCPConnected = false;

        preTCPStartTick = millis();

        Serial.println();

        Serial.println("TCP Client disconnected.");

        TCPclient.stop();

      }

      else if(millis() - preTCPStartTick > 1*1000)//重新连接

        startTCPClient();

      }

      else

      {

        if (TCPclient.available()) {//收数据

          char c =TCPclient.read();

          TcpClient_Buff +=c;

          TcpClient_BuffIndex++;

          TcpClient_preTick = millis();

          if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1){

            TcpClient_BuffIndex = MAX_PACKETSIZE-2;

            TcpClient_preTick = TcpClient_preTick - 200;

          }

          preHeartTick = millis();

        }

        if(millis() - preHeartTick >= KEEPALIVEATIME){//保持心跳

          preHeartTick = millis();

          Serial.println("--Keep alive:");

          sendtoTCPServer("ping\r\n"); //发送心跳,指令需\r\n结尾,详见接入文档介绍

        }

      }

      if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))

      {

        TCPclient.flush();

        Serial.print("Rev string: ");

        TcpClient_Buff.trim(); //去掉首位空格

        Serial.println(TcpClient_Buff); //打印接收到的消息

        String getTopic = "";

        String getMsg = "";

        if(TcpClient_Buff.length() > 15){//注意TcpClient_Buff只是个字符串,在上面开头做了初始化 String TcpClient_Buff = "";

              //此时会收到推送的指令,指令大概为 cmd=2&uid=xxx&topic=light002&msg=off

              int topicIndex = TcpClient_Buff.indexOf("&topic=")+7; //c语言字符串查找,查找&topic=位置,并移动7位,不懂的可百度c语言字符串查找

              int msgIndex = TcpClient_Buff.indexOf("&msg=");//c语言字符串查找,查找&msg=位置

              getTopic = TcpClient_Buff.substring(topicIndex,msgIndex);//c语言字符串截取,截取到topic,不懂的可百度c语言字符串截取

              getMsg = TcpClient_Buff.substring(msgIndex+5);//c语言字符串截取,截取到消息

              Serial.print("topic:------");

              Serial.println(getTopic); //打印截取到的主题值

              Serial.print("msg:--------");

              Serial.println(getMsg);  //打印截取到的消息值

      }

      if(getMsg  == "on"){      //如果是消息==打开

        turnOnLed();

      }else if(getMsg == "off"){ //如果是消息==关闭

          turnOffLed();

        }

      TcpClient_Buff="";

      TcpClient_BuffIndex = 0;

      }

    }

    /*

      *初始化wifi连接

    */

    void startSTA(){

      WiFi.disconnect();

      WiFi.mode(WIFI_STA);

      WiFi.begin(wifi_name, wifi_password);

    }

    /**************************************************************************

                                    WIFI

    ***************************************************************************/

    /*

      WiFiTick

      检查是否需要初始化WiFi

      检查WiFi是否连接上,若连接成功启动TCP Client

      控制指示灯

    */

    void doWiFiTick(){

      static bool startSTAFlag = false;

      static bool taskStarted = false;

      static uint32_t lastWiFiCheckTick = 0;

      if (!startSTAFlag) {

        startSTAFlag = true;

        startSTA();

      }

      //未连接1s重连

      if ( WiFi.status() != WL_CONNECTED ) {

        if (millis() - lastWiFiCheckTick > 1000) {

          lastWiFiCheckTick = millis();

        }

      }

      //连接成功建立

      else {

        if (taskStarted == false) {

          taskStarted = true;

          Serial.print("\r\nGet IP Address: ");

          Serial.println(WiFi.localIP());

          startTCPClient();

        }

      }

    }

    //打开灯泡

    void turnOnLed(){

      Serial.println("Turn ON");

      digitalWrite(LED_Pin,LOW);

    }

    //关闭灯泡

    void turnOffLed(){

      Serial.println("Turn OFF");

        digitalWrite(LED_Pin,HIGH);

    }

    // 初始化,相当于main 函数

    void setup() {

      Serial.begin(115200);

      pinMode(LED_Pin,OUTPUT);

      digitalWrite(LED_Pin,HIGH);

      Serial.println("Beginning...");

    }

    //循环

    void loop() {

      doWiFiTick();

      doTCPClientTick();

    }

    本demo 是利用arduino IDE开发,关于arduino IDE 的ESP8266环境配置可参考:

    需要修改的信息有:

    需要修改的信息有WIF名称,WIFI密码,用户私钥UID,设备主题topic。

    //********************需要修改的部分*******************////WIFI名称,区分大小写,不要写错#define DEFAULT_STASSID  "newhtc"//WIFI密码

    #define DEFAULT_STAPSW   "air123456"//用户私钥,可在控制台获取,修改为自己的UID

    #define UID  "4d9ec352e0376f2110a0c601a2857xxx"//主题名字,可在控制台新建

    #define TOPIC  "light002"//单片机LED引脚值

    const int LED_Pin = D2;

    //**************************************************//

    用户私钥可以巴法云控制台 获取,注册绑定邮箱即可在巴法创客云控制台获取。

    关于主题topic:主题可在控制台  新建,字母+数字自定义组合即可。

    现在支持的设备有:灯泡、插座、风扇、传感器设备。

    关于设备类型,由创建的主题名称决定:

    当主题名字后三位是001时为插座设备。

    当主题名字后三位是002时为灯泡设备。

    当主题名字后三位是003时为风扇设备。

    当主题名字后三位是004时为传感器设备。

    在本demo中主题为light002,故为灯泡设备,详细介绍见巴法云官方接入文档。

    修改好,下载到ESP8266即可。

    测试程序:控制台推送on是开灯。推送off关灯,可打开串口调试助手查看调试。

    第二步 绑定到米家

    打开米家app,底部--我的---其他平台设备---->点击添加--->找打巴法,登录你的巴法云账号,如果巴法云控制台有创建设备,设备就会自动同步过去了。(如果没同步到,再次点击底部的同步设备即可)

    设备成功同步后,就成功接入到了米家,现在就可以使用小爱同学来控制灯了。,比如说:小爱同学,打开台灯,此时esp8266就会收到on的字符串,从而执行打开操作,可打开单片机串口调试助手查看调试信息。

    相关文章

      网友评论

          本文标题:esp8266接入米家,小爱同学控制

          本文链接:https://www.haomeiwen.com/subject/zcrfdrtx.html