警惕外来入侵!打造联网的门窗监控设备

随着物联网进程的不断加速,许多传统的设备被接入网络,在以前,防盗报警器(图1)主要通过电话网络达到报警效果,比如主人不在家的时候,在家里设置好报警设备,当传感器检测到人员走动或门被开关,就会向主人手机拨打电话或发送短信,这种报警设备主要由一个报警主机和多个检测器组成,成本较高,随着开源硬件的普及,我们可以自己动手打造一款这样的设备。


经过比较后,我选择nodemcu这一款开发板作为主控制器,它使用esp8266无线芯片,具备完全的WIFI协议栈,很轻松的就能接入WIFI网络,另外开源社区还专门为它打造了arduino的开发环境,这样,使用熟悉的arduino就能玩转ESP8266。
其他的硬件(图2)包含了一副门磁开关,一块迷你面包版,和一颗4.7K的电阻。没错,就是这么简单的几个零件就可以达到我们想要的效果。


这是组装完成的图片,是不是很简单呢:


我们本次选用的门磁开关是常闭型,即当两端闭合时导通,从fritzing的电路图(图4)中我们可以看到,D1通过一个4.7K的电阻接到VCC端,而GND通过门磁开关接到D1端,这样,当门磁开关断开即门被打开时,D1端被上拉处于高电平状态,当门被关闭时,D1端接地,处于低电平状态。


然后我们要到物联网云平台申请账号,这样我们才可以将数据上传到云服务器,我们这次使用yeelink平台,然后根据提示操作会得到设备id,传感器id,apikey等几个重要参数,这几个参数会在编程时用到,然后我们需要设置触发动作,这样当上传的数据达到一定值时,就可以使用邮件,微博,yeelink客户端发送报警信息(图5)。


添加传感器时选用数据类型为数据型(图6),当门打开的时候上传数据1,闭合时上传数据0,上传时会自动将0或1转换为ASCII码对应的值,0转换为48,1转换为49。


接下来就是,软件了,我们首先要将ESP8266的第三方库导入Arduino的IDE,单击arduino IDE 的文件,首选项,然后将下面的网址填入第三方开发板管理器网址:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
确认以后就会开始更新了,等待一会就会发现开发板选项中多了许多使用ESP8266芯片的开发板,这样我们就可以开始编程了(图7)。


下面是arduino的程序:
#include

#define ledPin 2 // 定义ledPin连接到GPIO2 /D4
const char* ssid = "xxxxx"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid
const char* password = "xxxxx"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码
const char* host = "www.yeelink.net"; //设置服务器地址
const char* APIKEY = "750a6ad6adda4d01f7278e59bf3eb3a2"; //API KEY

int deviceId = 350364; //设备id
int sensorId=393133; //传感器id

WiFiClient client;
const int tcpPort = 80;
char data[512] ;
int x = 0;
int dat = 0;

int postCount = 0;

void setup() {
WiFi.mode(WIFI_STA); //set work mode: WIFI_AP /WIFI_STA /WIFI_AP_STA
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
pinMode(5, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
delay(10);

// We start by connecting to a WiFi network //开始链结网络
Serial.println("");
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

//dht.begin();
}

void loop() {
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
if (!client.connect(host, tcpPort)) {
Serial.println("connection failed");
return;
}
int n =digitalRead(5); //读取门磁开关状态
if(n==LOW){
delay(100);
if(n==LOW){
postData(deviceId, sensorId, '0'); //如果门磁开关导通,即门闭合,发送数据0
//digitalWrite(8, HIGH);
}}
else{
digitalWrite(ledPin, LOW);
delay(100);
if(n==HIGH){ //如果门磁开关断开,即门打开,发送数据1
postData(deviceId, sensorId, '1');
digitalWrite(ledPin, HIGH);
}
}

unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 2000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
Serial.println("closing connection");
}

void postData(int dId, int sId, int val) { //以POST方式上传数据
// We now create a URI for the request
String url = "/v1.0/device/";
url += String(dId);
url += "/sensor/";
url += String(sId);
url += "/datapoints";
String str = String(val);
String data = "{\"value\":" + str + "}";

// This will send the request to the server
client.print(String("POST ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Accept: */*\r\n" +
"U-ApiKey:" + APIKEY + "\r\n" +
"Content-Length: " + String(str.length()+10) + "\r\n" + //发送数据长度
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Connection: close\r\n\r\n" +
data
);
Serial.println(str);
Serial.println(String(str.length()));
}

程序就这样写完了,大家使用的时候只用修改前面几个自定义的参数就可以了,将程序上传至开发板,然后我们就可以到yeelink查看效果了(图8),图中凸起的部分表示门开着。


设置好出发动作后可以达到报警效果,但是我试了几次,邮件和yeelink客户端都收不到推送消息,只有微博可以(图9),不知道是不是这个平台的原因。


当然,这只是实现的一种方法,主要是借助了开源社区的力量,感谢社区为我们提供了这么多好用的工具,让我们不必从零开始,大家还可以使用别的芯片,其他的物联网平台例如ONENET,机智云,乐联网等,相信大家一定会做的更好。