Arduino

Arduinoを使って光センサーを制御する

過去にArduinoを使ったスイッチの制御方法について説明しました。スイッチはオンとオフ、言い換えると電通しているかしていないかで制御を行っていました。しかし、世の中には2値だけでなく、アナログ値をとるセンサーが山ほどあります。今回はその中でも光センサーを使ってスイッチ代わりの制御を行っていきます。

光センサー

光センサーとは光の有無、あるいはその強度を電圧に変えるセンサーの事です。特徴としては暗闇の中では抵抗値がとても大きく、光にさらされると抵抗値が低くなるため、スイッチの役割として使われます。

今回はCdsセルの光センサーをつかって回路を組んでいきます。

光センサーを使ってLEDの点灯を制御する

今回は光センサーに手をかざすとLEDが消灯する回路を作ります。回路で使う機器・端子は以下の表の通りとなります。

Arduino マイコン搭載の小型コンピュータ
ブレッドボード 抵抗・ジャンパー線などを使って回路を作る基板
LED 順方向に電圧を加えると発光する半導体
ジャンパー線 電気を中継する線
抵抗10kΩ 電圧を下げる端子
抵抗510Ω 電圧を下げる端子
光センサ 光の有無、その強度を電圧に変換する端子

実際に組んでみた回路は以下のようになります。

LEDをつける

Arduinoの13番ピンとブレッドボードの(f,18)をジャンパー線でつなぎ、(f,18)と(f,17)にLEDを設置し、(i,17)と(i,14)に抵抗510Ωを置きます。ArduinoのGNDと(j,14)をジャンパー線でつなぎます。

光センサーをつける

過去にスイッチをつけた方法と同じです。今回もプルダウン抵抗を取り入れています。

Arduinoの5Vとブレッドボードの(j,9)をジャンパー線でつなぎ、(f,9)と(f,7)に光センサーを置きます。ArduinoのA0と(j,7)をジャンパー線でつなぎ、(g,7)と(g,3)に抵抗10kΩを設置します。最後にArduinoのGNDと(j,3)をジャンパー線でつなぎます。

プログラムコード

作成したプログラムコードは以下の通りです。

const int LED = 13;//LEDを9番ピン
const int LT = 0;//光センサーをアナログの0番ピン
const int THLD = 750;//閾値

int val = 0;//光センサーから取得したアナログ値を格納

void setup() {
// put your setup code here, to run once:
pinMode(LED,OUTPUT);//9番ピンを出力モード
}

void loop() {
// put your main code here, to run repeatedly:
val = analogRead(LT);//光センサーの値を読み取る

if(val > THLD)
{
digitalWrite(LED,HIGH);//LEDを点灯する
}else
{
digitalWrite(LED,LOW);//LEDを消灯する
}
delay(50);
}

光センサーは電圧を0~1023までに値に変換することが出来ます。この回路の場合だと0V~5vを0~1023の値で表しています。2.5vは512となります。

光センサーはスイッチ(タクトスイッチ)と違い、2値ではなく幅広い値を得ることができるためリッチなセンサと言えるでしょう。

この値を取得するためにはArduinoのANALOG INにあるA0~A5を使います。そのため以下のプログラムではANALOG INの0番ピンからanalogRead関数を使って値を取得しています。

val = analogRead(LT);//光センサーの値を読み取る

取得した光センサーの値が閾値より大きければLEDを点灯させ、小さければ消灯するように分岐しています。

if(val > THLD)
{
digitalWrite(LED,HIGH);//LEDを点灯する
}else
{
digitalWrite(LED,LOW);//LEDを消灯する
}

実行結果

実行結果は以下の動画のようになります。

光センサーを使ってサーボモータを動かしてみる

今までは光センサーから取得したアナログ値を閾値で判断していたため、結局のところ2値で扱っていました。ここからは光センサーから取得したアナログ値をそのまま使ってサーボモータの回転角を制御する回路とプログラムコードを作成します。

回路で使う機器・端子は以下の表の通りとなります。

Arduino マイコン搭載の小型コンピュータ
ブレッドボード 抵抗・ジャンパー線などを使って回路を作る基板
ジャンパー線 電気を中継する線
抵抗10kΩ 電圧を下げる端子
光センサ 光の有無、その強度を電圧に変換する端子
サーボモータ 位置、速度等を制御するモータ

回路は下図のようになります。

サーボモータをつける

Arduinoの11番ピンとサーボモータの出力線をジャンパー線でつなぎ、GNDとGND線をジャンパー線でつなぎます。またブレッドボードの(h,9)とサーボモータの電源線をジャンパー線でつなぎます。

光センサをつける

Arduinoの5Vとブレッドボードの(j,9)をジャンパー線でつなぎ、(f,9)と(f,7)に光センサーを置きます。ArduinoのA0と(j,7)をジャンパー線でつなぎ、(g,7)と(g,3)に抵抗10kΩを設置します。最後にArduinoのGNDと(j,3)をジャンパー線でつなぎます。

プログラムコード

プログラムコードは以下の通りです。

const int SERV = 11;//サーボモータを11番ピン
const int LT = 0;//光センサーをアナログの0番ピン
const int CAL = 550;//校正値

int val = 512;//光センサーから取得したアナログ値を格納
int old_val = 0;//光センサーから取得した前回のアナログ値を格納

void setup() {
// put your setup code here, to run once:
pinMode(SERV,OUTPUT);//11番ピンを出力モード
}

void loop() {
// put your main code here, to run repeatedly:
val = analogRead(LT);//光センサーの値を読み取る

//アナログ値に変化があった場合
if(val != old_val)
{
rotation(val*0.175);//アナログ値から角度を指示
delay(10);
}
old_val = val;//取得したアナログ値を前回の値として格納
}

//回転角を制御する関数
void rotation(double x){
digitalWrite(SERV,HIGH);
delayMicroseconds((x*10.5)+CAL);
digitalWrite(SERV,LOW);
delay(5);
}

光センサは0~1023のアナログ値を取得します。今回は取得した1024のアナログ値によって角度を決めたいので、例えば0°が0になり、180°は1023となります。よって180/1023=約0.175となり、取得したアナログ値×0.175が指定する角度となります。すなわち、アナログ値が300であれば、300×0.175=52°となります。

rotation(val*0.175);//アナログ値から角度を指示

実行結果

実行結果は以下の通りです。

まとめ

光センサーは0~1023のアナログ値を取得することが出来ますので、タクトスイッチに比べると少しリッチな機能をもったセンサーだと言えます。アナログ値のため、より多くの情報を持ち、きめ細かな条件分岐などによって精密な制御を行うことが出来ます。

アナログ値を取得するセンサーは光センサーの他にもまだまだありますので、どこかで紹介できたらいいなと思います。

参考書籍