MAKER UNO + で始めるSTEM (12) 日の出をキャッチ①
CdSは硫化カドミウムを使っています。カドミウム自体は有害物質ですが、硫化物だと安定なのかもしれません。光の強弱により、抵抗値が変化する古典的なデバイスです。安価なのも特徴です。たくさんの種類があり、抵抗値は異なります。
アマゾンで入手したCdSをテスタの抵抗レンジで測ります。机の上で2.4kΩでした。同じ場所で照度計の表示は300luxでした。
天井の電気を消すと30.3kΩです。照度計では21luxでした。
もし、光の強度と抵抗値が線形の関係があるとします。あと二つ、明るさを変えてデータを取り、エクセルで散布図を作りました。縦軸が光の強度[lux]、横軸が抵抗値[kΩ]です。暗くなると急に抵抗値が上がる傾向が読み取れます。
両軸とも対数にし、累乗で近似曲線を描きました。
抵抗値がわかれば明るさが導けます。
夕方、曇り空の家の外に照度計をもっていきました。1800luxでした。そうすると、抵抗値は200Ωぐらいだと予測できます。
●電圧は測れる
Arduinoのアナログ・ポートでは0~5Vの電圧が測れます。次の回路のように抵抗R1とCdSのR2で分圧した電圧を測ります。
夜明けごろの薄暗い明るさを1000luxと仮定します。グラフから約1kΩです。晴天時の昼間には10000luxを超えるので、100Ω以下の抵抗値になると推測できます。PCの作業をしている机の上の明るさが300~500luxなので2kΩ前後です。
そうすると、夜明けの明るさは300以下から1000lux以上への変化だと仮定すると、抵抗値R2は1~2kΩに変化します。
R1に1kΩを使うとすれば、
- R1 = R2 = 1kΩ時 分圧出力はVcc=5Vとすれば2.5V
- R1 =1k、 R2 = 2kΩ時 分圧出力はVcc=5Vとすれば3.3V
夜明けの明るさの変化を、ArduinoのA-Dコンバータの出力値で効率よく判断できるように思えます。
●夜明けの観測
少し雲が出ていましたが、冬の夜明け(6:44)前後の明るさを測りました。縦軸はlux、横軸は時刻です。
●実際にスケッチを動かす
CdSは抵抗と同様に極性はないので、無造作につないでかまいません。
直列につないだ抵抗R1を1kΩとしたとき、アナログ・ポートA0の電圧を読むスケッチを動かします。
CdSを手で覆ったときは約4.95V、机の上でそのままの状態(約300lux)で3.75V、LED電球を真上に置いたとき(約8700lux)に1.0Vぐらいでした。
●判断基準
ここまでの実験から、判断すべき電圧がわかりました。
- 夜明け前30分はCdSを手のひらで覆ったときの電圧
- 夜明け前後は机の上の明るさ(300から500lux)ぐらいの電圧
- 十分日が昇ったときの明るさは電球をCdSの真上に持ってきたときの電圧
したがって、特性不明のCdSを入手しても、直列に入る抵抗を選べば、上記の実験で適正な電圧を導けることがわかりました。
●判断するスケッチ
CdSを窓際に置いて、仮に4V以下になったら日が昇ったと判断します。もちろん、曇りや雨の日もあるので、この電圧が正しく夜明けだと判断できるかどうかはもっと実験をすべきでしょう。また、CdSの正面にカラスがとまったとすると、判断を間違えることもあります。
夜明けは約30分程度の間に明るさが増す状態です。1分ごとに測定し、3回とも4V以下なら夜明けと判断するのがよいだろうとスケッチを書きました。実験なので1秒ごとの測定にします。
実行結果です。
読み取りの部分を関数readA0()に変更して、loop()をすっきりさせました。
●判断した結果を外部に伝える
上記のスケッチは、夜明けになると Good morning と表示をしました。この表示のためにはPCをつないだままにしなくてはなりません。そこで、ブザーを鳴らすことに変更します。ブザーはディジタル・ポートの8番につながっています。
このスケッチは正常にコンパイルされ、動作します。テストも正常に動いているように見えます。けれど間違っています。
関数readA0()の戻り値の型が整数なのです。実数の値を期待しているのに整数値が戻ってきます。ただしくはintをfloatに修正します。Serial.print()文では実数が表示されているのに、というバグが出ても気がつかないプログラムですね。関数を呼んだ後に電圧を表示すれば、すぐに気が付いたはずです。
このままではずっとブザーが鳴って煩わしいので、なんとかしないといけません。