Wireless・のおと

サイレックスの無線LAN 開発者が語る、無線技術についてや製品開発の秘話、技術者向け情報、新しく興味深い話題、サイレックスが提供するサービスや現状などの話題などを配信していきます。

前の記事:「SX-580 WiFi 電気スタンド製作記(3)」へ

SX-580 WiFi 電気スタンド製作記(4)

2014年10月23日 16:00
YS
前回は busybox httpd 上 CGI を実装し、CGI からの操作で GPIO ポートを操作して LED を点灯/消灯できるところまで製作しました。今回はいよいよ最終回で、HTML の見栄え改良とリレー基盤の製作などを行います。

ユーザーインターフェースの改良
iPhone のディスプレイ物理解像度は 3G 以前のモデルが 320 x 480、いわゆる Retina 液晶になってからは 640 x 960(iPhone4) または 640 x 1136 (iPhone5) です。しかし通常の WEB サイトは PC 用にデザインされているため幅 320 や 640 の液晶でははみ出してしまい、これを防ぐため iPhone のブラウザ(Safari)はデフォルトで画面幅が約 1024 ピクセル相当になるよう縮小して表示する仕様になっています。以前の HTML や CGI のテストでやたら小さく表示されたのはこのためです。今回は電球の画像を 240 x 320 で作り、これを 480 x 640 に拡大したものを「現在の状態」に使用、ON/OFF ボタンには「iPhone 風」の画像を 240 x 240 で作って原画サイズで使うことにしました。

bulb_off.jpgbulb_on.jpg

button_off.jpgbutton_on.jpg


前回は <input type="submit"> を用いてボタンを実装しましたが、今回は画像ボタンを使います。フォームの発行を画像ボタンで行うのは <input type="image" src=URL> で実現できますが、このタイプのボタンは単に「押された」だけでなく「何処が押された」という情報がパラメータ X, Y で付加されます。QUERY_STRING が SW=ON&X=145&Y=137 のようになるわけです。なので前回のスクリプトのように、環境変数 QUERY_STRING に対する単純な文字列一致比較で ON/OFF を判定できなくなります。
これは簡単なパーサ...例えば echo $QUERY_STRING | grep -q "SW=ON" のようなスクリプトで「$QUERY_STRING に SW=ON が含まれるか否か」を判定させることが可能なのですが、実際に grep を使った CGI の試作品を組んでみたところ、ボタンをタップするたびに異なる座標の付いた URL にアクセスするため、これをブラウザが「新しい URL」を判断してしまい、延々とアクセスヒストリーに記録してしまうことがわかりました。これはあまり使い勝手のよいものではありません。そこで今回はあえて from を使わずに、<a href src=URL?パラメータ> というリンクタグを使って CGI に直接パラメータを渡すことにしました。

完成した CGI のソースを示します。CGI ファイル名も「gpiotest.cgi」ではなく「onoff.cgi」にしました。

#!/bin/sh
gpio_path=/sys/class/gpio/gpio56
if [ $QUERY_STRING = "SW=ON" ]; then
        echo 0 > $gpio_path/value
fi
if [ $QUERY_STRING = "SW=OFF" ]; then
        echo 1 > $gpio_path/value
fi
led_state=`cat $gpio_path/value`
echo "Content-type:text/html"
echo
echo "<html><head><title>SX-580-2700DM</title></head><body>"
echo '<div align="center">'
if [ $led_state = "1" ]; then
        echo '<img src="../bulb_off.jpg" alt="OFF"'
else
        echo '<img src="../bulb_on.jpg" alt="ON"'
fi
echo ' width=480 height="640"><br clear="all">'
echo '<table><tr><th>OFF</th><th>ON</th></tr>'
echo '<tr><td><a href="/cgi-bin/onoff.cgi?SW=OFF">'
echo '<img src="../button_off.jpg" alt="OFF" width=240 height=240></a>'
echo '</td><td><a href="/cgi-bin/onoff.cgi?SW=ON">'
echo '<img src="../button_on.jpg"  alt="ON"  width=240 height=240></a>'
echo '</td></tr></table>'
echo '</div></body></html>'

onoff.cgi を用いた iPhone の画面キャプチャを示します。白地に電球とボタンが2つの簡潔明瞭なものです。凝ろうと思えば背景画像を入れたり 3D レンダリング画像に差し替えたり、予算と時間次第で幾らでもハッタリが効くところです(笑)。

iphone-cgi-gui.jpg
改良CGI画面(表示)


リレー基盤の製作

リレー基盤の回路図を示します。昔懐かしい「はじめての電子工作」みたいですね。特に説明することもないごく基本的な回路ですが、リレー駆動が PNP トランジスタになっているのは SX-580 GPIO LED の点灯が負論理なのに合わせたものです。

relay_schematic.jpg リレー基盤の回路図(表示)

リレーは DC 3V 駆動の OMRON G6RL-14-ASI-DC3、AC 側は 10A 250VAC とけっこうパワフルです。とはいえ電気掃除機なんかをつないだら接点がぶっ飛び兼ねないのでヒューズを入れた方が良いのですが、今回は省略しています。リレーの駆動コイル側にはフライホイール・ダイオード、接点側にはフィルムコンデンサ(0.1uF)と抵抗(100 Ω)直列のスパークキラー、これも「はじめての電子工作」でお馴染みの回路ですね。

基盤を含め部品は近所の Radioshack で買ってきましたが(まだ部品棚があるんですよ...尊敬すべき創業精神!)、あとで不足に気づいた部品は Digi-Key で追加購入しています。AC ケーブルは Target で購入しました。20pin のフラットケーブルとヘッダはたまたま社内にあったものを使っています。

Radioshak-parts.jpg Radioshack で買ってきた部品たち (表示)

完成した基盤の写真を示します。これも説明が要るようなものではありませんが、注意事項は OMRON G6RL の足ピッチが 2.54mm 間隔じゃないところ。幅方向は 7.62mm なのですが長さ方向が 18.9mm, 22.1mm, 25.3mm で蛇の目基盤にスッポリ入ってくれません。今回は基盤穴を削って差し込み、半田を多めに流して固定しました。スルーホールは 2.54 ピッチが当たり前だと思っていたからチェックしてなかったなぁ...同じ OMRON 製リレーでも定格 5A の G6B シリーズなら 2.54 ピッチのようです。

relay_board1.jpg リレー基盤全体像 (表示)

relay_board2.jpg リレー基盤部品面 (表示)

relay_board3.jpg リレー基盤配線面 (表示)


リレー基盤を SX-580 に接続し、gpio56 に 0/1 を送ってみます。LED の点滅とともに「カチッ」とう電磁式リレー特有の音がして AC 回路が ON/OFF されるはずです。AC 側に卓上灯のような軽負荷を接続して、iPhone から ON/OFF 制御してみてください。


インテグレーション
さて、ここからが最終のインテグレーション作業になります。まず現状では HTML ファイル群が /root 下に置かれており、あまり見栄えの良いものではありません。また gpio56 の初期化や httpd の起動も自動化する必要があります。これを開発環境 sx580sdk/snapshot に遡ってインテグレートしてみます。

HTML ファイル群を何処に置くかはシステムによって異なりますが、Linux では /usr/share/www に置くことが多いようです。ターゲット上の / 原型は開発環境上では sx580sdk/snapshot/staging/skeleton ですので、

mkdir sx580sdk/snapshot/staging/skeleton/usr/share/www
mkdir sx580sdk/snapshot/staging/skeleton/usr/share/www/cgi-bin

というディレクトリを作り、

sx580sdk/snapshot/staging/skeleton/usr/share/www/bulb_on.jpg
sx580sdk/snapshot/staging/skeleton/usr/share/www/bulb_off.jpg
sx580sdk/snapshot/staging/skeleton/usr/share/www/button_on.jpg
sx580sdk/snapshot/staging/skeleton/usr/share/www/button_off.jpg
sx580sdk/snapshot/staging/skeleton/usr/share/www/cgi-bin/onoff.cgi

のファイルを置きます。busybox httpd はコマンドライン引数の -h でホームディレクトリを指定するので、httpd の起動を

httpd -h /usr/share/www

とすれば /usr/share/www 下で WEB サーバが動作するようになります。初期化スクリプト sx580sdk/snapshot/staging/skeleton/etc/init.d/rcW の末尾に gpio56 の初期化とあわせて httpd の起動コードを追加します。

#
# Initialize GPIO for AC control, start HTTP server
#
echo 56 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio56/direction
echo 1 > /sys/class/gpio/gpio56/value

httpd -h /usr/share/www

exit 0

さて、これによって HTTP と CGI は自動起動するようになったはずですが、http://192.168.99.1/cgi-bin/onoff.cgi という URL を明示的に打ち込まなければ接続できないのは少々不親切です。もちろん一回接続してブックマークを作っておけば良いのですが、最初の一回も IP アドレスさえ入力すれば自動的に CGI へ飛ばすようにしておいたほうが親切です。そこで、/usr/share/www/index.html に次のような HTML を置いてデフォルトで CGI に飛ばすことにします。

<html>
<head>
<meta http-equiv="refresh" content="1;url=/cgi-bin/onoff.cgi">
</head>
<body>
<script type="text/javascript">
<!--
document.location.replace("/cgi-bin/onoff.cgi");
//-->
</script>
<a href="/cgi-bin/onoff.cgi">Click here</a>
</body>
</html>

document.location.replace("/cgi-bin/onoff.cgi"); は JavaScript のコマンドで、ページロード後に /cgi-bin/onoff.cgi にジャンプすることの指示。もしブラウザが JavaScript に対応していなかったり(今どきそんなブラウザは珍しいと思いますが)、セキュリティ等の理由で JavaScript 実行が禁止されていた場合のために HTML の head 部分にメタタグ <meta http-equiv="refresh" content="1;url=/cgi-bin/onoff.cgi"> を埋め込み、1秒後に /cgi-bin/onoff.cgi をリロードすることを指示しています。万が一 JavaScript もメタタグも効かなかった場合(今日では殆どあり得ないとは思いますが)に備え、<a href="/cgi-bin/onoff.cgi"> を使い「手動で」CGI に飛ばすリンクを埋め込んでいます。


WPA2-PSK セキュリティの設定
さて、今までは SX-580 SDK にデフォルトで用意されていた hostapd.conf を使い、SSID="SX-IMAPP-SDK"、セキュリティなしの AP として動作させていました。最後にこれを WPA2-PSK セキュリティに設定したいと思います。hostapd.conf には大量のオプション設定がありますが、WPA2-PSK 設定には4行を追加するだけで充分です。

#
# This file is a sample configuration file of hostapd.
#
interface=ath0
# bridge=br0
driver=ar6000
ssid=SX-580 Light Stand
channel_num=11
ignore_broadcast_ssid=0
auth_algs=1
ctrl_interface=/var/run/hostapd
wpa=2
wpa_passphrase=lightstand
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP

ssid= はわかりやすければ何でもいいです。今回はあえて空白文字を入れた "SX-580 Light Stand" を設定しています。
wpa=2 は WPA の動作モードを指定し、1:WPA1 のみ、2:WPA2 のみ、3:WPA1/2 混在を示します。WPA1 はもはや過去の規格になりつつありますので、今回は 2 で「WPA2 のみ」を指定しています。
wpa_passphrase= はパスフレーズを指定します。8~64 文字の長さで指定してください。今回はわかりやすく?「lightstand」を指定しています(セキュリティ上、わかりやすいパスワードは好ましくはありませんが)。
wpa_key_mgmt= には "WPA-PSK" を指定します。"WPA-EAP" を指定するといわゆるエンタープライズセキュリティモードになりますが、説明は割愛します。
wpa_pairwise= は使用する暗号モードを "CCMP":CCMP-AES のみ、"TKIP":TKIP のみ、"TKIP CCMP":TKIP/CCMP 混在モードを示します。TKIP も過去の規格になりつつありますので、今回は CCMP のみを指定しています。

なお WPA/WPA2 ではユニキャストに用いる Pairwise Cipher とマルチキャストに用いる Group Cipher の暗号アルゴリズムを違えることもできますが、hostapd では wpa_pairwise の設定によって Group Cipher は自動的に選択されます(TKIP ないし CCMP 単体の場合は同じアルゴリズムが、CCMP/TKIP 混在の場合は TKIP が使用されます)。

hostapd.conf に上記の変更を施して hostapd を再起動すれば、SSID が変わって WPA2-PSK モードで動作するようになるはずです。iPhone を接続してパスフレーズを入力し、接続できることを確認してください。

iphone-wpa.jpg WPA2-PSK へのログイン (表示)

例によって例のごとく、hostapd.conf の「雛型」は開発環境上で sx580sdk/snapshot/staging/skeleton/etc の下にありますので、ターゲット上で動作確認できたらその変更を開発環境のほうに反映しておきます。

最後に、上記全ての変更を反映したファームウェアを作成して SX-580SDK に書き込み、リレー基盤を接続、AC 出力に卓上灯を接続した様子を示します。

sx580-stand.jpg 電気スタンド稼動中 (表示)


まとめ
全四回にわたって続けてきた製作記、如何でしたでしょうか。技術的には「WiFi インターフェースを AP モードに設定しステーション (iPhone) を接続する」「CGI 入りの HTTP を稼動させる」「CGI から GPIO の 0/1 操作を行う」「GPIO からリレーを駆動する」、個々の要素はとても基本的なもので、決して難しいことではありません。ですが、それらを統合して「iPhone から操作する電気スタンドを作る」という目的を達成するためには、1つ1つの要素を順番に解決し(※註)、そしてインテグレートしてゆかなければなりません。いわば「ものづくり」の基本ですね。

(※註) 今回は「DHCP を動作させなければ、hostapd だけでは iPhone の WiFi は接続完了にならない」「BUSYBOX HTTP で CGI を動作させる方法」「Perl を使わず(Shell スクリプトだけで) HTTP POST の引数をどう解釈させるか」といったあたりが課題事項でした。

「iPhone で操作する電気スタンド」を社内で披露したところ、結構好評でした。SX-580 の仕様上、こういう事が出来るのは「あたりまえ」なのですが(※註)、自分のスマートフォンを繋いで画面をタップするとライトが点いたり消えたりするという、「実際に触れる」「目で見てわかる」というのは、プレゼンテーションとして大きな効果があるようです。これもまた「ものづくり」の基本かも知れません。

(※註) 技術的には GPIO 1 ビットの操作ですから、基盤上 LED の点滅と何も変わりません。単に GPIO の外側にリレー回路を付加しただけ、とも言えます。しかし技術プレゼンテーションとしては、勇ましい電磁石リレーの駆動音(笑)と共に卓上灯が点滅するというのは大きなインパクトがあります。

今回製作した電気スタンドは ON/OFF だけの基本的なものですが、AC 側の回路を工夫すれば光量調整のような実装も可能です。たとえ ON/OFF だけでも、「点灯時間(消費電力)の表示」「タイマー機能の追加」といった機能追加もできます。また今回は HTTP サーバに固定 IP アドレス(192.168.99.1)を使用しましたが、SX-580 上の DNS サーバ機能を使って「適当に URL を打ち込んでも常に SX-580 HTTP サーバに接続させる(DNS redirect)」機能を実装してみるのも面白いでしょう。

次の記事:「ワイヤレス・のおとメディア小論(1)」へ

最新の記事

カテゴリ

バックナンバー