DeviceMotion Event/WebSocketを使ってiPod touchでArduinoを操作する

WebSocketとDeviceMotion Eventで遊ぶ - DiaryExceptionで、iOS 4.2.1にしたiPod touchでWebSocketとDeviceMotion Eventが使えることが分かったので、HTML/JSを用いたアプリケーション(Webアプリケーション)から離れて、iPod touchからArduinoを操作するアプリケーションを考えた。

3章に分けて解説する。

設計

iPod touch (Webページ) <-WebSocket通信-> WebSocketサーバ <-TCP通信-> Arduino の、各要素間通信でやり取りするデータは、JSON形式によって記述する。

iPod touchSafariで表示するWebページにはボールがあり、色をフォームで赤/緑から選択する。ボールの位置は、iPod touchの傾き:DeviceMotion Eventから決定する。Webページはボールの情報(色と位置)をWebSocket通信によりWebSocketサーバに送り、WebSocketサーバはArduinoTCP通信でボールの情報を送る。

ArduinoTCP通信のためにEthernet Shieldを接続し、WebSocketサーバから受け取ったボールの情報を可視化するためのマトリックスLEDを接続する。マトリックスLEDには8x8LEDを搭載し赤/緑の色が表示可能なBU5004-RGを用いる。LEDドライバにはMAX7219を2つ(赤用/緑用)を用いる。

実装

Webサーバ兼WebSocketサーバはTornadoで書いた。Webページは"http://192.168.254.23:8888/"で参照し、WebSocketサーバには"ws://192.168.254.23:8888/ball"で参照する。

上記コードはIPアドレス:"192.168.254.23"を持つPCで実行しておく。

WebSocketサーバは、Webページを読み込んだiPod touchからJSON形式のデータを受け取り、受け取ったデータをそのまま、Ethernet Shieldを積んだArduinoTCPパケットとして送信する。ArduinoIPアドレスとリスンポートは"192.168.254.100:9999"とした。

ArduinoTCPパケットを受信するために、Ethernet library(Arduino開発環境に標準搭載)を用いた。WebSocketサーバから受け取ったJSON形式のデータを処理するためにaJson libraryを用いた。また、MAX7219によるマトリックスLED点灯制御のためにMatrix library(Arduino開発環境に標準搭載)を用いた。

複数個のマトリックスLEDとMAX7219の配線、Arduinoとの配線はMatrix & Sprite Arduino Libraries, for a many-LED display!等を参考にすれば分り易い。

WebSocketサーバから受け取るデータには、ボールの色と位置が含まれる。ボール色はマトリックスLEDの点灯色とし、ボール位置から点灯させるLEDを決定する。iPod touchのボールの位置はX方向で0から300、Y方向で0から336の値を取る。マトリックスはX/Y方向8個配置されており、0から7の値を取るので、組み込み関数のmapを用いて調整する。

JSON形式のデータはaJson libraryによりparse、aJsonObjectから値を取り出す。

ArduinoEthernet Shieldを載せ、マトリックスLEDを接続し、LANケーブルを繋いでおく。上記コードはArduino開発環境でコンパイルして、Arduinoにuploadしておく。

WebページはDeviceMotion Event/WebSocketを用いるため、HTML5で書く。WebページがiPod touchSafariによって読み込まれた段階で、WebSocketサーバとの通信を確立し、DeviceMotion EventによりiPod touchの傾きを計測する。1秒毎にボールの位置を更新し、WebSocketサーバにJSON形式でボールの色と位置を含むデータを送る。

Webサーバを兼ねているWebSocketサーバのコードと同じディレクトリに、上記HTMLファイルを置いておく。

実演

$ ls
balls_canvas.html   balls_websocket.py
$ python balls_websocket.py
(Web/WebSocketサーバ待機中)

iPod touchSafariでWebページを読み込み、iPod touchを傾けるとWebページ内のボールが動く。ボールの位置と色に合わせて、Arduinoに接続されたマトリックスLEDのドットが動く(点灯するLEDが変化する)。

1秒毎の位置更新で、ボールの動きに滑らかさが欠けているが、あまり細かい時間で位置を更新するとArduinoの処理が追いつかず沈黙してしまうので、1秒とした。

おまけ

Arduinoのコードの中に書いてあるが、MAX7219とマトリックスLEDとの配線を間違えている。

ユニバーサル基板でちまちま2時間くらいかけて半田付けして、こうもスパゲッティになってしまうと直す気にもなれず、ソフトウェア(コード)の方をハードの仕様に合わせた。こういう柔軟性は、ソフトウェアの強みだろう。