2016年1月1日金曜日

Energiaでお風呂時計(第一回)

完成後、CPUもブレッドボード上へ移動

まぁ、またデジタル時計なんですけど。

使ったCPUはMSP430G2553ですが、開発環境はArduino互換なので、RTCを用意すれば簡単に移植することができます。ただ、nanoを使ったとしても消費電流を押さえるのはシンドいと思います。

■仕様■

  • 表示は4桁7セグメント赤色LED
  • お風呂なので電源は電池
  • 電池は1ヶ月ぐらいもたせたい
  • 時刻と入浴時間を交互に表示

■実装■

省電力で4桁の7セグを動かせる・・・ということで、CPUにはMSP430G2553を選びます。RTCは使わず、G2553に32768hzのXtalを追加して1秒ごとに割り込みを発生させて時計代わりにします。

さすがにLEDを常時点灯していては電池がもたないので、入浴時のみ表示するようにします。入浴中であることを検出するには、
  • 倒立スイッチ、風呂に入ったら時計を立てると点灯→一番簡単
  • PIRセンサーで人の動きを検出→簡単だけどお風呂のお湯で誤動作するかも?
  • 照度センサで明かりを付けたら動作開始
  • ドップラーレーダーで(ry
などいろいろ考えたのですが、ここはAPDS9930という照度・近接センサーを使います。ebayで「gesture sensor」って書いてあったのでAPDS9960みたいなことができるのかと思って買ったら単なる照度・近接センサーだった、というオチ。9960より劇的に安かったんですが、典型的な安物買いの銭失いでした。でも、寝かせて置くのももったいないので、使います。それに携帯電話用のデバイスなので、CDSなどで明るさを検知するよりも電力を消費しません(アナログの達人ならできるのかもしれないけど、動作時の消費電流250μA/待機時90μA,Sleep時2.2μAなんて回路を作るのは私にゃ無理)。

配線にはブレッドボードを使い、7セグLED電池ボックスは秋月です。

大きな声ではいえませんが、電流制限抵抗などは一切入れてません。Vf=1.8vの赤色LEDを使う場合には3.3v - 1.8v = 1.5v、5mAも流せば十分なので1.5 / 0.005 = 300Ωぐらいの抵抗をG2553とLEDのセグメント側の間に入れておくのが正しい使い方です。正しくない使い方をしているので「1」を表示している時と「8」を表示している時で明るさが異なってしまう(各桁を接続している端子に7セグメント分の電流が集中するので「8」のときは容量が足りなくなってしまう)のですが、まぁ自分用なので壊れなければOK。そのうちボード起こしたら抵抗入れるから、それまでがんばれG2553。

G2553への書き込みにはTIのLauchPadを使います。

ソフトはArduino互換のEnergia IDEを使って書きます。くれぐれもバージョン0101E0017と0101E0016は使わないようにお気をつけてください。

以下配線表。各セグメント7本と桁4本、電源、I2Cだけです。時計合わせはそのうち考えます。hourとminuteの間にコロンが点灯する表示器が欲しい(こないだaitendoで買ったら全品不良で点灯しなかった)。


MSP430G2553相手ピン備考
P1_47セグLED 11Seg A
P1_57Seg B
P2_04Seg C
P2_52Seg D
P2_21Seg E
P2_310Seg F
P2_45Seg G
P0_012Dig 1
P0_19Dig 2
P1_28Dig 3
P1_36Dig 4
P1_7APDS9930SDA
P1_6SCL
P2_6XTAL
P2_7XTAL


この他、電池の赤をブレッドボードの赤、黒をブレッドボードの青、G2553のVccとAPDS9930のVCCをブレッドボードの赤、G2553のGndとAPDS9930のGNDをブレッドボードの青、にそれぞれ接続します。


最初のバージョンは19日間動作しました(浴室使用時間は1日平均30分ぐらい)。LED駆動のデューティー比をかなり絞り込んだ現行バージョンは現在12日目ですが、さて。


■ハマり■

他のところに書いたネタもありますが:
  • 別のところ(Energia最新版でI2Cが動かない)に書いたけど最新のEnergiaを使ったらI2Cが動かなくなってしまった。2つ前のビルドをダウンロードしたら何事もなかったかのように動いた。うがあ。
  • 作業中にミスで電源逆接とG2553逆差しで2個トバしてしまった。
  • シリアルポートをGPIOでも使うとSerial.printなどを使った瞬間にリセットがかかる。まぁ当たり前なんですが……ライブラリの中のSerial.printで発症したために「ライブラリを呼ぶとフリーズする」という症状になり、ライブラリの問題か?と誤認してしまったために発見が遅れました。いやはや。
  • 明暗のスレッショルド設定にちょっと苦労しました。最終的にはセンサーからの値をLEDに表示させるプログラムを書いていろんんな向きで値を測定して閾値を決めました。やっぱ現場に行かんとダメやで。
  • 風呂場の明かりをつけているのに時計が消灯してしまうことがあって当初は上記閾値の問題かと思ったのですが、どうやらセンサーがLED電球の高速点滅の「滅」を拾ってしまうようで照明の明るさ/閾値設定とは関係なく発生します。なので、平均値を取るようにしました。ただ、センサーの値は1秒に1回サンプリングしており点灯時の明るさで500-700、消灯時の閾値が60という設定なので、LED電球を消灯してもすぐには時計が消えません。
  • ダイナミック点灯の合間にI2Cでセンサーを取りに行くと一瞬時計表示がチラついてしまいます。なので、時刻と入力時間を切り替えるときに読みに行くように変更しました。RTOS欲しい。
  • 照度に合わせてLEDの明るさを変えていますが、違いがわかりません。手で影を作ると少し暗くなるのでソレと判断できるのですが、あまり暗くすると消灯モードになっちゃいますし。

■ソース■

基本的には以前書いたデジタル時計の使い回しです。ArduinoでLEDのダイナミック点灯させるとだいたいこんな処理になっちゃいます。あと、APDS9930のライブラリはArduino用を使いました(APDS9930 Ambient Light and Proximity sensor)。

なんということもないダイナミック点灯プログラムなのですが、CPUのクロックを点灯中には8Mhz、消灯時には1Mhzに切り替えています。切り替えることでI2Cなどに影響がでないか心配だったのですが、問題ありません。1MhzだとG2553の消費電流は230μAで9930は220μA(スリープはさせていないが通信はごく低頻度なので消費電流はもっと低いはず)なので、まったくLEDを点灯させなければ2000時間程度は動くはずですが、点灯しない時計は意味がないので困ったものです。


0 件のコメント:

コメントを投稿