はじめての電子工作超入門

第5回 光センサーでArduinoへの入力を試してみる!

2014-07-04 06.19.49

前回までLEDを使った回路を利用してArduinoの基本的な流れをご紹介いたしました。今回から、LEDに加えて、他の電子部品の利用や、それを使ってどんなことができるのか、ということをやっていきたいと思います。

センサーを使ってArduinoに入力信号を送ってみる

これまではArduinoから電流を流してLEDを光らせることをやってきました。これはArduinoからLEDに対して「出力」している状態となります。電流が出力されるピン番号を変えたり、強さを変えたり、タイミングを変えたりして、LEDを様々な光らせ方をしてきました。
では、今度はその強さやタイミングをセンサーからの入力値を使って操作できるようにしてみましょう。ん、その前にセンサーって何でしょうか。耳慣れた言葉ではあるかと思いますが、センサーっていったいどういうものをセンサーと呼ぶのでしょうか?特に電子工作をしていると「○○センサー」という言葉をよく聞くようになります。センサーは電子部品が入力装置として利用する部品のことを示しますが、簡単に説明すると

センサーは人における五感(触覚、知覚、嗅覚、味覚、聴覚)の代わりとなるもの

になります。Arduinoやコンピューターにおいてはこれらのセンサーが人間の五感の代わりとなって周りの状況を把握するのに利用されます。人間は五感(人によっては第六感も備えている人がいますが・・・)ですが、電子部品におけるセンサーは本当に色々な種類があります。その中でも今回は簡単に使える光センサーを利用してみましょう。

 

2014-07-04 17.30.12
光センサー

光センサー(通称CdSセル)は、暗いところにおくとセンサー自体の抵抗値が大きくなり、明るいところに置くと抵抗値が低くなる性質を持っています。その性質を聞いて作品を作るとしてぱっと思い浮かぶのは、”朝明るくなったら何か動く”・”夜暗くなったら何か動く”という感じでしょうか。
何はともあれ実際に触りながら動きを確認してみましょう。

まずは光センサーの性質の「明るさが変わると抵抗値が変わる」というのをチェックするのに下のような回路でLEDの明るさが変わるか試してみましょう。

ar01

//setup - Arduinoを起動した際に最初に呼ばれる処理
void setup() {
//Arduinoに13番ピンを出力用として使うと知らせる
pinMode(13, OUTPUT);
}
//loop - setupの処理が終わった後、このloopの中の処理を電源が切れるまでずっと繰り返す
void loop() {
digitalWrite(13, HIGH); //13番ピンの出力をHIGH=5Vにする
delay(1000); //1000ミリ秒 = 1秒待つ
digitalWrite(13, LOW); //13番ピンの出力をLOW = 0Vにする
delay(1000); //1000ミリ秒 = 1秒待つ
}

光センサーは抵抗器と同じくプラスマイナスの向きはありませんのでそのまま接続できます。明るい場合抵抗値が限りなく低くなってLEDに過分な電流が流れてしまうのを防ぐため、1つ抵抗器を加えておきます。この状態で、最初に書いた点滅を繰り返すプログラムをArudinoで動かしてみましょう。LEDが点滅したら、手で光センサーを覆ったり離したりするとLEDの明るさが変わっているかと思います。

これが基本的な光センサーの性質になります。じゃあ、この場合暗くなったらLEDを光るようにすればすぐ役に立つ道具が作ることができそうですよね!じゃあ、それをやってみましょう。

Arudinoは一旦置いておいて、電子回路だけで組むとどうでしょうか?その場合、さらに部品を使うことや、回路を工夫させることで実現ができます。電流は基本的に流れやすいところ(抵抗値が低いところ)に流れていきます。下記の回路では明るい場所では抵抗値が弱い為、抵抗器側に電流が流れ、逆に暗くなった場合に光センサー側の抵抗値が高くなるのでLEDへの方へ電流が流れてLEDがつくようになります。

ar02

でも、この回路だと光センサーを暗くしてもLEDがそんなに強く光りません。且つArduinoはただの電源出力装置だけになってしまうのでそれでは電池とほとんど変わらなくなってしまうので、Arduinoに光センサーを直接つなげて入力されている値を取り出してみましょう。

Arduinoのアナログ入力

Arduinoのアナログ入力を使って光センサーの値を実際に計測してみましょう。Arduinoのアナログ入力は図の位置(ANALOG INとプリントされている箇所)になります。

ar03

アナログ入力を受けとる為に下記のとおり回路を組み立ててみてください。

ar04

 

これで、まず光センサーの数値を入力する入力回路はできました。次にArduinoのプログラムを確認していきましょう。

int val=0; //入力される値を格納する為の変数
void setup() {
Serial.begin(9800); //モニターに出力するための設定
}
void loop() {
//ANALOG INの0番ピンからデータを受け付ける
val=analogRead(0);
Serial.println(val/4); //入力された値をモニターに出力
delay(100);
}

ここで、また新しい関数が出て来ています。
今回、光センサーからの入力値をPCのディスプレイ上で確認したいので、その場合、setup関数でSerila.begin(9800)を設定しておきます。それによって、loop内でSerial.println()を使って数値や文字列をディスプレイに表示することができます。この方法は今後入力した値を確認する他、Arduino上でデバッグをするのによく利用する方法となります。
次に、アナログピンからの入力値を取得します。今回アナログ入力に関してはsetup関数でピンの指定は必要ありません。さらに値を読み込む関数は

analogRead(ピン番号) – アナログ入力を受ける関数

となっています。今回はanalogReadで取得した値をval変数に入れています。ここで「変数」という単語が出てきますが変数は今後もプログラムを作成する上でとても重要な役割を持っています。変数はプログラムで利用する数値や文字等を始めとした様々なデータを一時的に保管しておくことができる場所(領域)となります。

変数:プログラムで利用する数値などのデータを一時的に保管する領域

そして、val変数に保管したセンサーの数値をSerial.println()関数を使って単純にディスプレイ上に表示してみます。Arduinoではアナログピンで入力される値は0〜1023までの値が入力されます。そのため、プログラムで入力値を利用して何かをする場合は、この数値を考えながらプログラムを書いていきます
実際の動作をディスプレイで確認するには「ツール」-「シリアルモニタ」を選択すると実際に光センサーからの入力値を確認することができます。

ar05

正常にセンサの数字が変わっているでしょうか?

ar06

光センサーの値でLEDの明るさを段階的に切り替える

光センサーの入力が確認できたらそれをもとに、LEDを段階的に操作してみましょう。
光センサーの入力値に対して、今度はアナログ出力でLEDに対して出力を行ってみます。

int val=0; //入力される値を格納する為の変数
void setup() {
Serial.begin(9800); //モニターに出力するための設定
}
void loop() {
//ANALOG INの0番ピンからデータを受け付ける
val=analogRead(0);
Serial.println(val/4); //入力された値をモニターに出力
analogWrite(3,val/4); //入力された値÷4の値をアナログ出力する
delay(100);
}

先ほどのプログラムに1行analogWrite()関数が増えました。

analogWrite([ピン番号],[出力する値]); – アナログ出力をする

アナログ出力も入力同様setup関数に設定は必要ありません。アナログ入力と異なる点を挙げると、入力は0〜1023だったのに対して、出力は0〜255までとなっています。ですので、ここでは光センサーからの入力値を4で割った値を出力に設定しています。

vol5

2014-07-04 16.44.04

※ここで、光センサーを覆ってもあまり明るさが変わらない場合、光センサーの明るい時と暗い時の範囲が狭い可能性があります。その場合は、抵抗器をさらに抵抗値の高いものに変えて試してみてください。

これで、入力・出力の両方を備えたしくみが完成しました。これまでArduinoはUSBに接続しているので、USBから5Vの電源を取って動作していますが、プログラムの書き込みが終わった後にPCがなくても動作させたい場合は、ArduinoにACアダプタジャックがありますので、そこに6〜20V(推奨値は7〜12V)のACアダプタを接続してあげると単体で動かすこともできますので、このままケースにいれて照明等に使われる高輝度のLEDに変えるなどするだけで簡易ブックライトの出来上がりです。

さらに、光センサーの入力段階に応じて明るさを段階的に変えたい場合は、if文を使って段階的に操作してみます。これで、明るい時に完全にLEDを消すことができました。

int val=0; //入力される値を格納する為の変数
int ledVal = 0; //LEDに出力する値の変数
void setup() {
Serial.begin(9800); //モニターに出力するための設定
}
void loop() {
//ANALOG INの0番ピンからデータを受け付ける
val=analogRead(0);
ledVal = val/4; //LED出力用の値を変数に格納
Serial.println(ledVal); //入力された値をモニターに出力
//明るさを4段階に設定する
if(ledVal < 50){
//入力値が50以下の時は消灯
analogWrite(3,0); //出力は0
}
else if(ledVal < 100){
//入力値が50〜100の範囲の時は消灯
analogWrite(3,100); //出力は100
}
else if(ledVal < 150){
//入力値が100〜150の範囲の時は消灯
analogWrite(3,150); //出力は150
}
else if(ledVal < 200){
//入力値が150〜200の範囲の時は消灯
analogWrite(3,200); //出力は200
}
else{
//入力値が200以上の時は最大出力
analogWrite(3,255); //出力は255
}
delay(100);
}

例えば、このしくみを応用して考えてみましょう。例えば、これをLEDではなく圧電ブザーなどに変えると暗く(明るく)なるとブザーが鳴る作品や、一定の角度で回転を制御することができるサーボモーターを使うと暗くなったらモーターが動いてスイッチを押すなどといった作品ができたりしますね。またArduinoではLANのモジュールを利用してインターネットに繋ぐこともできるので明るさを常にインターネットを通してどこかに表示するなどなど、入力は同じ方法でも出力が違えば全然違う作品になります。覚えたことで何ができるか、ということを考えながら作るのもArduinoの楽しみの一つでもありますね。

次回、さらに色々な部品を使いながら作品を作っていきたいと思います!

電子工作マニュアル Vol.3
赤川シホロ

電子工作や新しいデバイスをこよなく愛するエンジニア。日常生活のちょっとしたことを電子工作で作って試して、おもしろく過ごしたいと日々考えています。