TWELITEでシャッターの開閉状態監視
家建ててしばらくの間は、用がなければガレージのシャッターは閉めて引きこもってることが多かっんだけど、いつの頃からか晴れた日の昼間は相棒さんがシャッター開けて換気するようになった。
そして夕方になるとシャッターを閉めるんだけど、時々閉め忘れて夜になってることがあった。ウチのガレージは室内からも見えるんだけど、外が暗くなるとシャッターが開いてるのかどうかは室内からは意外とよく分からなくて、何とかしたいなーと思っていた。
で、見つけたのがTWELITE。無線通信で使う前提のマイコンで、コイン型電池(CR2032)で年単位で動くとか、マグネットセンサーで扉の開閉を検知できるキットがあるとかで、ちょうど良さげなので。あと、C++の開発環境が提供されてて色々融通が効きそうなので。
と言うわけで、用意したのはまずは開閉センサーPAL。
こんな感じにシャッターのレール部分に両面テープで固定して、シャッターを閉じたときに磁石が来るようにしておく。シャッターのパネルはアルミなので磁石は付かないけど、ブラケットは鉄系だったようで磁石がくっついたので、特に接着とかはせずに完了。イイ感じに開閉センサーPALの磁石検知部の至近距離に磁石が来るようにできた。
次に、開閉状態をLEDで知らせるために、通知PALを室内の見やすい場所に貼り付け。我が家は吹き抜けを中心に色んなとこからガレージが見えるようになってるので、吹き抜けのガレージ窓の上に設置した。
1Fの在宅仕事部屋から見るとこんな感じ。
2Fのリビングから見るとこんな感じ。
まあ実際には、貼り付ける前に何度もプログラムを弄って試行錯誤したり、シャッター側の開閉センサーPALの空きポートに適当なCdSを接続して明るさも検知できるようにしたりしてて、意外と手間取ったんだけど。
というか、そもそもこの2つだけでは成り立ってなかった。
最初は通知PALを親機にしてたんだけど、親機は子機からの通信を受信するために常時CPU回して待機してないといけなくて、そうするとコイン電池では電力をまかないきれなくて、あっという間にLEDが弱よわになっていく…。
うーむ、プログラム書き込み用にTWELITE R3っていうUSBアダプターを使ってるけど、これでUSB給電するか?いやいや、通知PALの場所はあそこがベストだけど、USB電源引っ張ってくる手立てがない。
しょうがないのでUSB接続のMONOSTICKを追加で調達(厳密にはTWELITE CUEとセットのヤツ。CUEはいずれ何かに使おう)。自宅サーバのRaspberry Piに接続して、将来的には外出中もブラウザ越しにシャッターの開閉状態を見えるようにするつもり。
で、改めてロジックを組み直して、しかし自宅サーバがちょっと離れたところにある(ウチの建物の中ではほぼ端から端、しかも壁もたくさん挟んでる状態になってしまった…)ので、結構電波強度が微妙らしく、通信のリトライとかのチューニングに時間が掛かってしまった。
ちなみにTWELITEは青赤の2種類あって赤の方が電波が強いらしいけど、スペック上は青で十分だと思ったので全部青。しかし、壁があるせいか電波強度は結構ギリギリだった。
出来上がったロジックは、開発環境に含まれてたサンプルをベースにして、それぞれこんな感じ。
開閉センサーPAL+光センサー(CdS)
- ベースのプログラム:PAL_MAG.cpp
- サンプルは磁石が近づくときだけ割込みが発生してたけど、磁石が離れるときも割込みが発生するように改良。ただし、単純にsleep()前にpinMode()を両方セットするだけでは安定しなかったので、磁石が近づいてる時は離れる方の割込みを、離れてる時は近づく方の割込みをセットするようにした。
- 光センサー(CdS)の割込みも同様に(プルアップ有で)セットする。
- これで磁石や明るさの変化があった時に起床して、その時の状態(磁石N,S,CdSとついでに電池電圧とタイムスタンプ)を親機に送信できる。
- さらに、前回の状態を記憶しておいて、本当に変化があった時だけ通信するようにして電池を節約することも考えたけど、親機との通信はたまに失敗したりするので、60秒ごとにその時の状態を送信するようにした。
- 親機からの距離が遠いので、通信のリトライ回数は多めにしといた。
通知PAL
- ベースのプログラム:PAL_MAG.cpp(枠組みだけでほぼ面影なしw)
- 60秒ごとに親機に適当なデータ(電池電圧・タイムスタンプ・割込み要因(加速度センサーかどうか)・(前回の)リトライ回数)を送信して、親機からの返信を200ms待機する(sleep()しない)
- 親機から受信した情報に応じてLEDをセットする(赤/緑/青/白×(消灯/点灯/点滅・明るさ)、点滅時の周期/デューティー比)
- 通知PALには加速度センサーもあるので、通知PALをひと振りしたらそのタイミングで親機から情報を取得するようにした。シャッター際で磁石の設置をしてる時などに、60秒待たなくてもLED表示を更新できると便利なので。
- 加速度センサー(MC3630)の使い方がイマイチよく分からなかったけど、初期化時に周波数とサンプル数をセットすると、そのサンプル数に達した時に割込みが発生するようなので、25Hzで25サンプルを指定して1秒ごとに割込みが発生するようにした。
- 加速度センサーからの割込みで起床した時に、
- 加速度センサーの値が閾値以下だった場合は何もせずにスリープする
- 前回の起床時に親機からの通信の受信に失敗してた場合は、親機への送信&受信を実施(これによって受信失敗時は1秒ごとにリトライを繰り返す。ただし10回まで。)
- 受信失敗したとき、サンプルではリセットが掛かるようになってたけど、意外とよく失敗するのでリセットせずに失敗回数をカウントアップしてスリープするようにしておいた
- 加速度センサーのキューが一杯になるとそれ以上データ取得してくれないらしいので、ちゃんとキューをクリアしてるつもりなんだが、何かの拍子に加速度センサー側が止まってしまうことがある。60秒ごとのタイマー割込みで加速度センサーのキューもクリアされて復活するので、ちょっと気持ち悪いけど気にしないことにする。一度設置してしまったら加速度センサーによるオンデマンド通信は必要ないので。
MONOSTICK
- ベースのプログラム:Parent-MONOSTICK.cpp
- 色んな子機からの情報を受信できるようになってるけど、使うのは開閉センサーPAL(MAG)のところと、それをベースに追加した通知PAL(NOTICE PAL)用のところ
- 開閉センサーPALからの通信だったら、
- 磁石の状態だけじゃなく、CdSの状態・電池電圧・タイムスタンプを受信して、ラズパイのLinux側で解釈できるように、受信した情報を電波強度と共に適当なフォーマットでSerial側に文字列で出力する
- 磁石が離れていて(シャッターが開いていて)かつ暗いときはメインフラグ(グローバル変数)立てる
- 電池電圧が閾値以下の場合は子機IDフラグを立てる
- 通知PALからの通信だったら、
- 電池電圧、タイムスタンプなどを受信して電波強度と共にSerial側に文字列で出力する
- 電池電圧が閾値以下の場合は子機IDフラグを立てる
- 親機が覚えてる情報に応じて、通知PAL側にLED表示情報を送信する
- メインフラグが立ってたら(=暗いのにシャッター開いたままなら)白を点滅
- 子機IDフラグが立っていたら(=子機が電池切れなら)IDに応じた色(R=0, G=1, B=2)を点滅
- 明るさは弱め、2秒間隔で一瞬光るように
- 子機側が受信待機してるタイミングと合わないことがあるようなので、リトライの間隔はやや長めにしてみた
そんなこんなで無事に夜でもシャッターの状態を把握できるようになった。めでたしめでたし。
1件のピンバック
ガレージシャッターの開閉監視、その後… | たぽブログ