MAKER UNO + で始めるSTEM (14) 日の出をキャッチ③
1回目、日が昇るとCdSの抵抗値は下がり、直列に入れた抵抗の分圧された電圧も下がることで、明るさを検知しました。2回目では、LEDボードをアナログ出力(PWM)で明るさを制御しました。この二つを組み合わせます。
●三つのしきい値で判断
- 日が昇る前は、LEDは明るく光る
- 日が昇るとき、LEDは薄暗く光る
- 日が昇りきると、LEDを消灯する
CdSの抵抗値はアナログの値ですが、日が昇り夜明けを迎えることを上記のように三つの状態で考えます。曇りや雨の日では状況が違うので、工夫が必要かもしれません。
●接続
1回目と2回目の接続を合わせます。CdSと直列に入っている抵抗は1kΩです。
●スケッチ
しきい値は下記のように決めました。
- 日が昇る前;4.0V
- 日が昇る途中;2.0~4.0V
- 日が昇りきった;2.0V
電圧の判別はif文で行いました。if文の結果実行する部分が1行で済むときは、下記のように実行されるコードを記述できます。複数になるときは{}で実行文をくくります。
CdSの電圧の読み出しは、waitTime の間隔で3回読み、平均値を戻す関数readA0() を作りました。
constは定数の宣言です。analogOutPin はフラッシュ・メモリの領域に確保されます。メモリを消費したくなければ#define analogOutPin 11でも動きます。
outputValueは変数で、SRAM領域に確保されます。
#defineはコンパイラへの指示なので、waitTime はどのメモリも消費しません。const int waitTime;でも動きます。
const byte analogOutPin = 11;
int outputValue = 0;
#define waitTime 1000
void setup() {
Serial.begin(9600);
Serial.println("\nStart");
}
void loop() {
float VoltAV = readA0();
Serial.print(" AvarageVolt= ");Serial.println(VoltAV);
if (VoltAV > 4.0 ) outputValue = 100;
if (VoltAV > 2.0 && VoltAV <4.0 ) outputValue = 10;
if (VoltAV < 2.0 ) outputValue = 0;
analogWrite(analogOutPin, outputValue);
delay(2000);
}
float readA0() {
float VoltA0 = (float)analogRead(A0)/1023*5.0;
delay(waitTime);
float VoltA1 = (float)analogRead(A0)/1023*5.0;
delay(waitTime);
float VoltA2 = (float)analogRead(A0)/1023*5.0;
return (VoltA0 + VoltA1 + VoltA2 ) /3 ;
}
実行中のシリアルモニタの様子です。LED電球をCdSの上に近づけたり離したりしています。