iPhoneからArduinoを動かしたいとき、iPhoneには自作の外部ハードウェアをほとんどつなげられないことが障壁になります。そこで頼りになるのがご存知Node.js。iPhoneからNode.jsへはWebSocketを使い、Node.jsからArduinoへはnode-serialportを使います。今回はArduinoも無線の先におきたかったので、Node.js→シリアル通信→XBee→Arduinoといった形をとっています。最終的にiPhoneからArduinoのLED点滅パターンを変えてみます。
全体の流れ
- iPhone
Node.jsの提供するWebSocketサーバに接続。制御コマンド(アルファベット1文字+数字1文字)を送る。制御コマンドはアルファベット1文字+数字1文字で、自分で勝手にきめたもの。 - Node.js
WebSocketサーバを立てて、iPhoneからのコマンドを受信。node-serialportを通してXBeeモジュールに送る。 - XBee
透過モード。Node.jsが投げた文字をそのままもう一方のXBeeモジュールへ投げるだけ。 - Arduino
XBeeモジュールとはシリアル通信で接続。読み取ったコマンドをもとに、LEDを光らせる。
Arduino側
XBeeで作るワイヤレスセンサーネットワークを参考に、ArduinoとXBeeモジュールとをシリアルで接続しています。XBeeのパケットからコマンドをよみとり、それに合わせてLEDの点滅パターンを変えています。
Node.js側
var express = require('express') , app = express() , server = require('http').createServer(app) , io = require('socket.io').listen(server); server.listen(3000); app.configure(function(){ app.use(express.static('static')); app.use(express.logger()); app.use(express.bodyParser()); }); app.get('/', function(req, res){ // index.html に、iPhoneで表示するボタンやスライダーを配置 res.sendfile(__dirname + '/index.html'); }); // シリアルポートの準備 var serialport = require('serialport'); var SerialPort = serialport.SerialPort; var sp = new SerialPort('/dev/tty.usbserial-AE01CQBA', { parser: serialport.parsers.readline('\r\n') }); io.sockets.on('connection', function(socket){ // iPhoneからWebSocketのパケットが来たら…… socket.on('value', function(data) { // 書き込みデータをつくって var xbeewrite = [data.state.charCodeAt(0), Math.pow(2,data.value)-1]; // XBeeに送信 sp.write(xbeewrite); }); });
WebSocketサーバ+Webサーバ。Webサーバは、WebSocketを送るためのインタフェースを出すだけ。ボタンやスライダーで、iPhoneから制御しやすくするためです。
WebSocketを受け取ったあとは、node-serialportのWriteを使ってXBeeへ送ります。配列に入れているのは、write関数の実装によるもの。.lengthを参照できるものでないとダメなので、文字列or配列ならOKだけど、整数や数値1つはダメ。1バイトだけ送るときも[かっこ]でくくって配列にしないとダメなのです。