はじめに
XBee は ZigBee 規格で通信を行なってくれる小型の無線通信モジュールです。前回(boost::asio::serial_port で ZigBee と会話してみた - 凹みTips)は C++ で ZigBee を扱いましたが、今回は Node.js での値の取得をやってみたいと思います。
出来るようになること
- JavaScript から部屋の温度を無線で取得
環境 / 構成
node-serialport の導入
Node.js 用のアドオンとして node-xbee が公開されていますので、これを使います。
Readme を読んでみると、node-serialport を利用してシリアル通信を行うようです。一つ注意しなくてはならないのは、node-serialport の最新版では動かず、0.7.3 を用いる点です。
npm install serialport@0.7.3 npm install xbee
ただ、0.7.3 の古い node-serialport では、ネイティブモジュールの作成に node-waf を用いており、node-waf は最新の Node.js(0.9.2@2012/10/15現在)では取り除かれてしまいました。そこで node-waf で書いている部分を node-gyp 用に書き換えます。モジュールのディレクトリは以下になります。
$ cd node_modules/serialport
まず、node-gyp 用に binding.gyp を作ります。
serialport_native/binding.gyp
{ 'targets': [ { 'target_name' : 'serialport_native', 'sources' : [ 'serialport_native.cc' ], }, ], }
serialport_native/serialport_native.cc(362行目から)
extern "C" void init (Handle<Object> target) { HandleScope scope; SerialPort::Initialize(target); } NODE_MODULE(serialport_native, init); // <-- ここを追記 }
一個上の階層に上がり、serialport.js の中で Node.js v0.9.x から廃止になった IOWatcher の行を取り除きます。
serialport.js(12行目)
// var IOWatcher = process.binding('io_watcher').IOWatcher; <-- コメントアウト
最後に Makefile を書き換えます。
Makefile
setup : cd serialport_native;node-gyp configure build;cd ..; # <-- node-waf から node-gyp に cp serialport_native/build/Debug/serialport_native.node . # 環境に合わせて Release から Debug に
で、Make すれば OK です。
$ make
温度を取得
node-xbee は node-serialport のアドオン的な位置づけで書かれています。AT コマンドの IS で 1 秒おきに XBee からデータを受け取って温度を表示するコードは以下のようになります。
temp.js
var SerialPort = require("serialport").SerialPort , xbee = require("xbee") ; var serial_xbee = new SerialPort("/dev/tty.usbserial-A501DG57", { parser: xbee.packetParser() }); serial_xbee.on("data", function(data) { // console.log('xbee data received:', data); <-- これで何が入っているか見れます var ain3hi = data.bytes[19]; var ain3lo = data.bytes[20]; var voltage = 1.2 * (ain3hi * 0x0100 + ain3lo) / 0x03ff; var temperature = (voltage - 0.6) * 100; console.log(temperature); }); var atc = new xbee.RemoteATCommand(); atc.setCommand('IS'); atc.destination64 = [0x00,0x13,0xa2,0x00,0x40,0x89,0x9d,0x84]; // XBee のアドレス atc.destination16 = [0xff,0xfe]; setInterval(function() { serial_xbee.write( atc.getBytes() ); }, 1000);
実行
$ node temp 27.859237536656888 27.74193548387097 (以下略)
SerialPort は Ubuntu なら「/dev/ttyUSB0」、Windows なら「COM3」といった形になります(数字は変わります)。Mac の場合は以下のサイトから FTDI のドライバをインストールする必要があります。
温度計算の部分については、 LM 61 という温度センサを用いて温度を測定したのでその電圧 - 温度変換式に準拠した形になっています。
おわりに
これにこの間作成した iRemocon の Node.js モジュール(node-iRemocon つくった - 凹みTips)を組み合わせれば、指定した温度にエアコンを設定してくれる部屋が簡単にできます!
node-xbee の Readme の文みたいな世界にまで出来ると楽しくなりそうですね。
node-xbee の序文(引用)
frontdoor.on("open", function() { if (alarm.state == "on") { alarm.sound(); hounds.release(); } else { lights.switchOn(); voice.speak("Welcome home"); } });