ネットワーク経由で室温や湿度などを監視するためのネットワークデバイスを設計しました。 Webサーバが動いていて、アクセスすると、Ajaxを使って動的に温度、湿度の変化をグラフに描画していきます。 デバイスの設計においてMCUにNXPのLPC1343を用い、 Webページの製作ではjQueryとYahoo! User Interface Library(YUI)を用いました。
準備中
サーバを置いている部屋の温度管理を目的として、 ネットワーク経由で室温や湿度などを監視するためのネットワークデバイスを設計しました。 Webブラウザ経由で、刻々と変化する温度・室温を観察することができます。 温度・湿度のグラフも動的に描画され、温度・湿度の推移を知ることができます。
設計に当たっては、最新のMCUを使ったみたかったので、
比較的最近発売されたNXPのLPC1343を用いました。
本当は、TIのLM3S9B9xを使いたかったのですが、チップ単体で手に入りそうにありませんでした
(1年以上待っている気がする...)。
図のように、デバイスを置いた場所の室温や湿度をネットワーク上で観察できるようになります。 温度と湿度の値は約2秒ごとに書き換わり、グラフも適宜アニメーションしながら書き変わっていきます。 ここでは、温度と湿度だけですが、若干の変更でセンサを追加できるようになっています。
下はWebブラウザの画面表示をキャプチャしたものです。 キャプチャ時に若干フレームがかけていてすこしカクついていますが、実際はもう少し滑らかに動きます。 グラフ中の要素数が増えると、要素を間引いて半分に減らして、要素追加までの時間を2倍にします。 ある程度グラフ要素追加の間隔が長くなったら、古いデータを削除して新しいデータを挿入する方法に切り替えます。 数値のほうは、グラフの更新間隔とは無関係に2秒程度毎に書き換わっています。
MCUとしてNXPのLPC1343を用いました。 LPC1343はARMのCortexM3コアを用いたMCUで、FLASHメモリを 32KB、SRAMを8KB搭載しています。 LPC1343にはEthernetコントローラの機能が含まれていないので、 EthernetコントローラチップのENC28J60を接続しています。
さらに、Ethernetに接続する際にはユニークなMACアドレスを用いるのが好ましいので、 MACアドレス書き込み済みのEEPROM 24AA02E48 をMCUに接続して、 ここから読み出したMACアドレスを使用しています。
センサとしては、HSM20Gというモジュールを用いました。マルツパーツ館で入手しました。 湿度センサと温度センサ(実際にはサーミスタ)を搭載していて、AD変換器で電圧を計測することで 湿度と温度を読み取れます。
TCP/IPプロトコルスタックにuIPを用いました。 uIPにはサンプルとしてWebサーバのコードが付属するので、 これをベースにWebサーバ機能を実現しました。 Cortex系のMCUにおいては、ソフトウエアインタフェースの統一を目的にCMSISというインタフェース規格(実装?)があり、 配布されています。 今回は、CMSISがどのようなものかを知るために、CMSISを用いつつプログラムを記述しました。
温度・湿度を観察するためのWebページは、Javascriptを使って動的にデータが書き換わるようにしています。 バックグラウンドで温度・湿度データを含むXMLをダウンロードするためにJavascript のライブラリであるjQueryを用い、 グラフの描画のためにYahoo! User Interface Library(YUI)を用いています。 jQuery や YUI は LPC1343 の 32KB のFLASHメモリに格納できないので、 Google Libraries APIを用いたり、Yahooから直接ライブラリをロードするなどして、 MCUにライブラリを置かずにすむようにしました。 これにより、LPC1343の32KBのFLASHにWebページをすべて格納することができました。
製作時に気付いた点をいくつか挙げます。
uIPは基本的に1つパケットを送り、ACKが帰ってくるのを待って、次のパケットを送る動作をします。 このとき、通信相手が delayed acknoledge を使っている場合、大きく遅れてACKが帰ってきます。 このため、通信速度はEthernetチップの限界まで到達せず、ACK待ちの時間で制限されてしまいます。
これは、1つのパケットを送信時に2つに分割して送ることで回避できます (http://www.sics.se/~adam/uip/uip-1.0-refman/a00154.html参照)。 uip_split_output()を使うように指示がありますが、使い方が分かりにくかったのと、プログラム格納用のFLASHメモリの容量不足もあり、 Ethernetチップのドライバのコードに uip_split_output() の内容を埋め込みました。 若干不安がありますが、これによりデバイスからのページのロードが大幅に早くなりました。
コンテンツの末尾に不要な 0x00 を送る問題があります。 コンテンツがHTML等の場合では問題とならないようですが、XMLの場合にはブラウザがエラーを出したり、ブラウザがクラッシュすることがありました。 コンテンツをC言語の文字列のように 0x00 で終端した状態で保持しているのですが、この終端文字まで送信してしまうのが原因です。 若干コードの書き換えが必要です。
CMSISに含まれるヘッダファイル(LPC13xx.hなど)とgccの"-fpack-struct"オプション(構造体をパックする)は共存できないようです。 "-fpack-struct"オプションなしだと動くプログラムが、"-fpack-struct"オプションをつけると動かなくなりました。 uIP のサンプルの Makefile では CFLAGS に "-fpack-struct" オプションを入れているので配慮が必要かもしれません。
TI の StellarisシリーズのMCUでは StellarisWareというまとまった形でドライバライブラリや、Stellarisに移植した各種ミドルウエア(uIP, lwIP, FatFSなど)が 配布されています。 このStellarisWareを使うと、ソフトを書くのがとても楽なのですが、NXPのLPCシリーズにはこういったサポートが無いのでちょっとしんどいです (レジスタをゴリゴリしたい気分の時には丁度いいのですが)。 mbedを使うと大分楽できそうですが、囲い込みすぎなのがちょっと嫌ですね... 斬新な試みで面白いのですが。
ネットワーク経由で室温や湿度などを観測するためのネットワークデバイスを設計しました。 デバイス上でWebサーバを組み込み、Webブラウザ経由で観察できます。 観測のためのWebページをJavascript等を用いた動的なページにしたので、 リアルタイムに刻々と変化する室温・湿度を確認できました。 遠隔からのサーバ管理などに役立つと考えられます。
(2010/8/13 初版)
(2010/8/18 画面キャプチャ動画を追加)
(2010/12/30 写真追加)