【实战】天猫精灵控制门锁


[success]这个东西看起来高大上,其实原理非常简单。我们直接利用一个nodemcu模块和一个物联平台就可以实现这个效果了。[/success]

准备硬件

因为要控制门锁,我们那个门锁是由电机控制的,控制电机的正转反转就可以实现开门和关门的效果。所以我用到了两个模块

首先nodemcu,就是下面这个样子,主要用于连接wifi并与物联网平台进行通信,还有就是控制IO口输出

因为mcu的IO口驱动能力有限,所以就只能用上次信达杯(智能车比赛)剩下的L298N驱动,IO口输入10或01就可以对应输出相反的电压了。

编写程序

硬件准备完毕就可以直接开始写程序了。因为我们是直接与物联网平台连接,所以就可以直接使用别人提供的例程。

我选择的是一个叫贝壳物联的平台。然后找到了相关文档。它这个文档使用nodemcu的编译器烧程序,事先还要往wifi模块烧录固件。我是完全按照这个来的,但是烧录进去后wifi模块串口一直输出错误信息,我找了半天无果后就想用其他的方法来实现。

我偶然在贝壳物联的github上找到了arduino程序,因为arduino是支持直接往esp8266烧录的,我之前也做过了不少笔记。所以我就果断选择使用arduino。这里贴一下下载地址

所以程序这块就只需要在这个例程上稍微修改一下就可以了。

注册设备

程序也有了,下面就是登陆贝壳物联网平台注册设备了。

这里注册设备很简单,只需要添加设备就可以了,然后会获得ID号和APIKEY,这两个后面都用的到。

注册完毕后我们还需要打开天猫精灵app(注意这个需要连接你的天猫精灵),添加智能设备。

具体可以参考这篇文章

烧录程序

注册好设备后我们就可以直接开始烧录程序了。

我们需要在原程序的基础上进行改动,这里我就直接贴出我的代码,我这里要实现的效果就是和天猫精灵说开锁,esp826就输出两个相反的电平,然后L298N就控制电机正反转,实现开关锁的效果。

实际代码:
[highlight lanaguage=”cpp”]

/*
    此文件需安装Arduino esp8266开发环境支持,环境搭建参见:http://www.bigiot.net/talk/237.html
    本程序可以用来控制四路继电器
    ESP8266烧入此程序直接,使用高低电频控制光耦继电器来控制电灯
    我的继电器默认高电频关闭,所以在初始化时都初始化为高电频,play关闭开启,stop关闭关闭,输入1-4打开或关闭对应的引脚
    代码基于https://github.com/bigiot/bigiotArduino/blob/master/examples/ESP8266/kaiguan/kaiguan.ino
    上的代码进行调整,修复了部分bug,解决了断线重连问题,此代码可以直接烧入到nodemcu模块,分享代码希望对大家有帮助
*/

#include <ESP8266WiFi.h>
#include <aJSON.h>

//=============  此处必须修该============
String DEVICEID="xxx"; // 你的设备编号   ==
String  APIKEY = "xxx"; // 设备密码==
//=======================================
unsigned long lastCheckInTime = 0; //记录上次报到时间
const unsigned long postingInterval = 40000; // 每隔40秒向服务器报到一次

const char* ssid     = "xxxx";//无线名称
const char* password = "xxx";//无线密码

const char* host = "www.bigiot.net";
const int httpPort = 8181;

int pins[4] = {D5,D6,D7,D8};
int state[4] = {HIGH,HIGH,HIGH,HIGH};
int arr_len = sizeof(pins)/sizeof(pins[0]);

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  WiFi.begin(ssid, password);
  //默认输出关闭电频
  for(int i=0;i<arr_len;i++){ pinMode(pins[i], OUTPUT); digitalWrite(pins[i], state[i]); } } WiFiClient client; void loop() { while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } // Use WiFiClient class to create TCP connections if (!client.connected()) { if (!client.connect(host, httpPort)) { Serial.println("connection failed"); delay(5000); return; } } if(millis() - lastCheckInTime > postingInterval || lastCheckInTime==0) {
    checkIn();
  }
  
  // Read all the lines of the reply from server and print them to Serial
  if (client.available()) {
    String inputString = client.readStringUntil('
');
    inputString.trim();
    Serial.println(inputString);
    int len = inputString.length()+1;
    if(inputString.startsWith("{") && inputString.endsWith("}")){
      char jsonString[len];
      inputString.toCharArray(jsonString,len);
      aJsonObject *msg = aJson.parse(jsonString);
      processMessage(msg);
      aJson.deleteItem(msg);          
    }
  }
}

void processMessage(aJsonObject *msg){
  aJsonObject* method = aJson.getObjectItem(msg, "M");
  aJsonObject* content = aJson.getObjectItem(msg, "C");     
  aJsonObject* client_id = aJson.getObjectItem(msg, "ID");
  if (!method) {
    return;
  }
    String M = method->valuestring;
    if(M == "say"){
      String C = content->valuestring;
      String F_C_ID = client_id->valuestring;
      if(C == "play"){
        digitalWrite(pins[0], HIGH);
        digitalWrite(pins[1], LOW);
        delay(500);
        digitalWrite(pins[0], LOW);
        digitalWrite(pins[1], LOW);
        delay(3000);
        digitalWrite(pins[1], HIGH);
        digitalWrite(pins[0], LOW);
        delay(500);
        digitalWrite(pins[0], LOW);
        digitalWrite(pins[1], LOW);
        sayToClient(F_C_ID,"LED All on!");    
      }else if(C == "stop"){
        digitalWrite(pins[1], HIGH);
        digitalWrite(pins[0], LOW);
        delay(500);
        digitalWrite(pins[0], LOW);
        digitalWrite(pins[1], LOW);
        sayToClient(F_C_ID,"LED All off!");    
      }else{
        int pin = C.toInt();
        if(pin > 0 && pin <= arr_len){
          pin--;
          state[pin] = !state[pin];
          digitalWrite(pins[pin], state[pin]);
        }
        sayToClient(F_C_ID,"LED pin:"+pin); 
      }
    }
}

void checkIn() {
    String msg = "{"M":"checkin","ID":"" + DEVICEID + "","K":"" + APIKEY + ""}
";
    client.print(msg);
    lastCheckInTime = millis(); 
}

void sayToClient(String client_id, String content){
  String msg = "{"M":"say","ID":"" + client_id + "","C":"" + content + ""}
";
  client.print(msg);
  lastCheckInTime = millis();
}

[/highlight]

这里就只需要把wifi名字,密码,id,key改下就好。当然还有开锁的逻辑部分不同用品的用法不同。自己按照要求改就可以了。

实际测试

把程序烧进去后,连接好硬件后我们就可以开始测试了。这里我们需要等待设备上线。然后点击设备对话,发送play和stop,如果平台收到了数据,就说明数据发送成功。

到此一个天猫精灵控制的门锁就做好了。

总结

这个东西总的来说还算很简单的,因为不涉及到服务器,我们只需要把硬件写好就可以了。以后有机会可以自己搭建一个服务器,来实现远程控制效果。

文章作者: 小游
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小游 !
  目录