使用Node.js、Twilio实现手机控制门锁

jopen 11年前

使用Node.js、Twilio实现手机控制门锁

使用Node.js、Twilio实现手机控制门锁

        英文原文:Build Your Own Lockitron With Twilio, Arduino, and Node.js

试想一下,如果你忘了带钥匙,但你带手机了,你就可以打开门锁。或者,你还在往家赶,可你的朋友已经到你家门口,你通过手机远程把家门打开,让朋友先自己进去看会儿电视。这不是科幻,也不需要多先进的设备,而是自己动手开发出来的。

        本文是基于我在波兰的 Makerland 大会上的一次研讨演讲。这篇文章将会指导你如何通过手机控制你家的门锁,而且是在不需要弄坏或改造门锁的情况下实现。我们需要使用一个微控制器(Arduino Uno),一个电机,和 Node.js,用它们来实现通过短信远程开锁和关锁。我是受到了 Twilio-powered Lockitron 的启发。

        步骤1:设备

        部件

        1. 一把门锁

        2. 胶带,纸板

        3. 电机(我使用的是 HS-322HD)

        4. 微控制器(Arduino Uno) + 转接线

        准备

        1. 从 http://arduino.cc/en/Main/Software 下载和安装 Arduino IDE。

        2. 从 http://nodejs.org/获取并安装

        3. 从 https://ngrok.com/download 下载并安装 ngrok (一个内网穿透程序)

        我将使用 Arduino IDE 写代码并上传到往微控制器里。我使用 node.js 脚本语言来和 Arduino 微处理器进行通信,利用 Express web 框架发送请求和相应请求。最后,我们使用 ngrok 将这个 Express web Server 暴露到外网,这样我们就可以通过短信让 Twilio 通信给你的微控制器。

        现在,我们可以开始动手了,将我的微控制器跟门锁链接上。

        步骤2:装配

        我们将使用一个伺服电机控制门锁。它就是一个马达,动力轴需要能旋转 180 度的那种,这样我们才能让门锁转开和闭合。

        这个伺服马达有三根线—火线(红),零线(黑),控制线(通常是黄色或白色)。微处理器上有很多口,将马达的火线连接 5v 电力口,零线接入 GND 地线口,控制线接入 Digital Pin 12 口,如下图:

使用Node.js、Twilio实现手机控制门锁

        就这样,我的马达和微控制器连接到了一起,我们再将它和门锁装配到一起。

        我喜欢用家里常用的东西来开发这些设备,但如果你能连接上一个 3D 打印机,你可以设计和打印出自己的锁扣装置。

        因为是示范,我使用了纸板和胶带来将电机和门锁固定到一起。

        将两个金属棍(或其它坚固的细棍)帮到马达上,用东西垫一下

使用Node.js、Twilio实现手机控制门锁

        使用纸板(或其它比较硬的东西)当做门锁和电机之间的连接填充物:

使用Node.js、Twilio实现手机控制门锁

使用Node.js、Twilio实现手机控制门锁

        用胶带将电机和门锁绑到一起,确保是绑在正确的一面,让电机转动的方向是开锁或关锁的方向:

使用Node.js、Twilio实现手机控制门锁

使用Node.js、Twilio实现手机控制门锁

        最后,我们将电动机轴固定到锁钮上:

使用Node.js、Twilio实现手机控制门锁

        现在我们已经将电机和门锁死死的固定到一起了:

使用Node.js、Twilio实现手机控制门锁

        步骤3:编写控制程序

        电机和微控制器已经连接,Node.js 和 Arduino 等软件也已经安装了,现在我们需要运行下面的命令来安装必要的 node.js 模块。注意,如果你使用的是 Windows,你需要按照 node-serialport Windows 安装指令

npm install serialport twilio express

        Node-Serialport 能够让你轻松的通过 Arduino 微控制器串口跟 Node.js 程序交互。我们将要使用它从 Twilio 里接受短信请求,并传递指令给 Arduino 微控制器让它关锁或开锁。

        Express 是一个简单的 node.js web 框架。而 twilio 模块能让我们轻松的和 Twilio API 交互。

        首先,我们打开 Arduino IDE,建立一个新的 Arduino 开发框架。第一步我们需要打开一个 9600 波特的串口连接,跟伺服马达接通(12 口)。

#include     Servo myservo;int servoPin = 12;int lock = ;int unlock = 180;void setup () {    // initialize serial: Serial.begin (9600);    myservo.attach (servoPin);    myservo.write (lock);  }

        我们告诉微处理器,伺服马达的 0 位置是“锁住”,180 位置是“解锁”。跟据你是如何将马达跟门锁捆绑的,也许需要交换调整这个位置。当微控制器启动时,它会告诉马达移动到“锁住”位置。

        接下来,我们将从串口连接上读取一个字符,来判定是否应该调动马达运行。

void loop () {     // Recieve data from Node and write it to a String while (Serial.available ()) {      char inChar = (char) Serial.read ();      if(inChar == 'V'){ // end character for locking if (myservo.read () >= 90) {         Serial.println ("L");         myservo.write (lock);         delay (3000);       }       else {         Serial.println ("U");         myservo.write (unlock);         delay (3000);       }      }    }    }

        Arduino 用来分析的串口输入是来自 node.js 脚本的输出,下面我们会介绍这个脚本。

        在 Arduino IDE 开发环境外,我们用一个文本编辑器创建一个新文件,叫做 nodelock.js,文件的开头是导入前面我们用 npm 安装的模块:

var twilio = require ('twilio'),     SerialPort = require ("serialport") .SerialPort,     express = require ('express');

        下面我们将建立新 express web serverserialPort 连接

var app = express ();var serialPort = new SerialPort ("/dev/tty.usbmodem1411", {   baudrate: 9600 });

        注意,我们指定了要连接的 USB 端口和波特率。你可能需要根据你的计算机的情况修改这个 USB 端口。你可以在 Arduino->Tools->Port 菜单上找到你的可用的 USB 端口号。

        下面我们要设定 HTTP 相关信息,调用/sms

app.use (express.bodyParser ());    app.post ('/sms', twilio.webhook ('your auth token',   { host:'foo.herokuapp.com', protocol:'https' }), function (req, res){  });

        我们需要告诉 express 服务器通过/sms地址接受 POST 请求,使用bodyParser分析请求内容,获取来自 Twilio 的短信信息。我们使用 twilio 的webhook方法来验证请求来源的可靠性。

        现在,我们有了接收短信的地址,在试一下之前,我们应该检查一下发短信的号码是否是我们用来控制锁的号码。

app.post ('/sms', twilio.webhook ('your auth token', {   host:'foo.herokuapp.com', protocol:'https' }), function (req, res){   if (req.body.From == "+12128675309") {     console.log ("verified number!");   } else {     console.log ("Wrong number!");     sendMessage (res, "Invalid number!");   }    });

        在验证号码的代码段里,我们可以加入一个处理发送和相应 Arduino 微控制器上串口连接的功能。

serialPort.once ('data', function (data) {       if (data.toString () .indexOf ('U') > -1) {              //check if the Arduino returned a U for unlocking                   sendMessage (res, 'Unlocking!');       }       else if (data.toString () .indexOf ('L') > -1) {         sendMessage (res, 'Locking!');       }       else {         sendMessage (res, 'ERROR');       }       console.log ('data received: ' + data);     });       serialPort.write ("V", function (err, results) {       if (err) {         console.log ('err ' + err);       }       console.log ('results ' + results);     });

        这代码看起来很杂乱,但这是相当直接的写法。我们设定了事件处理器从微控制器里接受数据。这个事件处理器会检查 Arduino 微控制器发送的是 “U” 还是 “L” ,我们获取这个值,并用sendMessage函数将信息反馈给用户。

        设定了事件处理器后,我们向 Arduino 微控制器里写入“V”字符,告诉它接收到了短信,它现在应该打开/关闭门锁。

        我们现在往文件中加入sendMessage函数,它有 2 个参数:res 和 message。

function sendMessage (res, message) {   var resp = new twilio.TwimlResponse ();   resp.message (message);   res.type ('text/xml');   res.send (resp.toString ());  }

        调用sendMessage函数会给用户发送 TwiML 响应信息。TwiML 是 XML 的子集,Twilio 用它来传递短消息指令。在我们这里,我们用它告诉 Twilio 响应我发送的 SMS 信息。用户也许会发送“unlock”,程序会通过 Twilio SMS 回复 “Unlocking!”

        我们已经配置了 SMS 处理器,最后只需要打开 SerialPort,启动 Express web server,我们的应用就开发完了:

serialPort.open ( function () {   app.listen (3000);   console.log ('Listening on port 3000');  });

        这就是所有我们需要的代码。现在,如果你上传我们之前写的 Arduino 代码,运行nodelock.js,方法是在终端里执行node nodelock.js,程序就启动了。

        如果你在开发的过程中遇到了错误,可跟这些代码对比一下看是什么问题。

        在创建并登陆你的 Twilio 帐号后,到 Twilio 控制台,点击号码标签,选择你希望用来控制锁的号码。你会看到两个框,语音请求地址(Voice Request URL)和消息请求地址(Messaging Request URL)。我们使用 Messaging Request URL 来传递我们的短信文本信息。

        因为 Twilio 是通过 HTTP 请求通信的,我们需要有一个能从公网上访问的地址,当有消息到达时,Twilio 会将信息传递跟这个地址。于是我们之前安装的 ngrok 就起作用了。

        等你的 node.js 服务器起来,开一个终端窗口,在你安装 ngrok 的目录下输入./ngrok 3000,这里你需要指定一个地址,通过它,外部服务能访问你的本地服务器。在这个地址后面跟上/sms,填入 Twilio Messaging Request URL 栏里,保存设置,试着发送一个短信!你的门锁应该随着短信自动打开或关闭。

        祝大家玩的愉快,编程开心!