R_Castleのアイコン画像

Arduino Unoのアナログ入力ポートで光センサーを読み取る

R_Castle 2020年01月20日に作成  (2020年01月23日に更新)

今回は、マイコンボードにセンサーを接続して、周囲の状態をプログラム中のデータとして読み取らせてみます。

センサーとは?

一般的に「センサー」と呼ばれる電子部品は、音や光あるいは手で触れるといった様々な自然の現象を電気の信号に置き換える事で、マイコンにその現象の量や変化したタイミングなどを知らせる役目を果たしています。
私たちの身の回りにある電子機器で、センサーを使っていないものは恐らくないのではないかと言える位、沢山のセンサーが日常生活を便利にする働きをしてくれています。

Arduino Unoのアナログ入力ポート

ArduinoUnoの場合、写真の位置にアナログ入力ポートがあり、ポート番号0番から5番まで全部で6本のアナログ信号を読み取らせることが出来ます。
AnalogPort_01.JPG
AnalogPort_02.JPG

このポートから読み取ることが出来るのは電圧の値になっており、基本的には0Vから5Vの範囲を、0から1023の数値に置き換えて読み取っています。
なので、大体の目安は下表の様になります。

No. 入力される電圧 読取値の目安
1 0V
2 1V 204~205
3 2V 409
4 3V 613~614
5 4V 818
6 5V 1023

アナログ入力ポートにセンサーを利用して電圧の信号を入力する訳ですが、今回は光の明るさを読み取る光センサーを使用してみます。最新のデジタル式センサーもありますが、まずは基本的なアナログ回路で構成する光センサー素子「CdSセル」を使用してみます。

CdS光センサー

02_CDS_01.JPG
今回は詳細な説明は避けますが、CdS(硫化カドミウム)セルとはいわゆる半導体と呼ばれる電子部品の一つで、セルに当たる光の強弱で素子が持つ抵抗の値が変化する性質を持っています。一般的には明るくなると抵抗値が小さくなる構造をしていて、暗くなると自動で点灯する照明などのセンサーとして利用されています。
この素子だけでは光の強弱で変化するのは抵抗の値だけなので、簡単な回路に組み込んで光センサーとして使用出来る様にします。

光センサーを使った明るさ検出回路

光センサーから電圧の値をマイコンに取り込む場合、一番簡単な箇所は素子の端子間の電圧を入力すると良いと思います。
02_Tester_01.JPG
02_Tester_02.JPG

電気計測用のテスターを使用すると写真の様に電圧を計測する事ができます。
02_Tester_03.JPG
これと同じ様に、センサーの+(プラス)電圧側をマイコンのアナログ入力ポ―トに入力します。尚、-(マイナス)側はGND端子が共通で接続されていれば特に配線する必要はありません。

ですが、電源に光センサーだけを接続した回路では、どれだけセンサーの抵抗値が変化しても、オームの法則に基づいて電流の値は変化しますが、読み取れる電圧の値は変化する事がありません。これでは計測ができないので、幾つか部品を追加して、明るさで読み取れる電圧が変化する様に改良します。
02_Circuit_01.jpg
改良した接続が出来たら、プログラムを書き込んで実行してみます。

光センサで本体LEDを点滅させるプログラム

/***************************************************************************/ /* サンプルプログラム 「光センサーを読み取る」*/ /* 変数「LED」をデジタルポート13番ピンに設定する */ /* 変数「CDS」に、アナログポート0番ピンの値を読み取ります */ int LED=13; int CDS; /* 13番ピンを出力ポートに設定します */ void setup() { pinMode(LED,OUTPUT); } /* アナログポート0番の値を読み取り、しきい値以上だった時にLEDを消灯します */ void loop() {  CDS = analogRead(0);  digitalWrite(LED,HIGH); // LED点灯  if(CDS>800)  {   digitalWrite(LED,LOW); // LED消灯   delay(1000); //1000mSec待機する。 } } /***************************************************************************/

実際に回路図を組み立てる前に使用する光センサー、Cds単体の抵抗値を測ってみました。
記事を編集している環境の明るさを基準として、明るい状態で約2.2kΩ、指で隠して暗くした状態で約23kΩとなり、10倍の変化をしています。
02_CDS_02.JPG
02_CDS_03.JPG
この光センサーの抵抗と直列に抵抗を追加する事で、電源から加わる電圧を分担する事になります。光が照らされてセンサーの抵抗値が小さくなると抵抗値のバランスが変わって読み取られる電圧の値が変化するので、これを光の変化量と見立ててマイコンに読み取る事が可能となる訳です。

プログラムを実行します。光センサーを指で隠してArduino Unoの上に取り付けられているLEDが点滅するかどうか確認します。
02_Sample_01.JPG
02_Sample_02.JPG
02_Sample_03.JPG
02_Sample_04.JPG

また、抵抗と光センサーのどちらから電源の+と-をつないでいるかでも読み取られる値が変わってきますので気を付けましょう。電子回路の用語では+(プラス)をVinやVccといった表現で表し、-(マイナス)をGND(グランド)等で表現します。

簡単な回路図を描くとこの様になります。

02_Circuit_02.jpg

この様に抵抗の側から+接続=5Vを繋ぎ、光センサー側を-接続=GNDに接続し、マイコンボードのアナログ入力ポートで値を読み取った場合をケース①とします。
5V、GNDを逆に接続した場合についてをケース②として同様に回路図を描いてみます。

02_Circuit_03.jpg

ケース①の場合、センサーに光が当たって素子の抵抗値が小さくなると、読み取り点とGNDの間の電圧は小さくなる方向に変化します。

ケース① センサーが暗い センサーが明るい
合成抵抗R1+Cds 24kΩ(23kΩ+1kΩ) 3.2kΩ(2.2kΩ+1kΩ)
流れる電流 0.21mA 1.56mA
アナログポート電圧(Vcds) 4.79V 3.43V

接続を逆にしたケース②の場合、読み取り点とGNDの間にあるのは抵抗だけになりますが、センサーに光が当たって抵抗値が小さくなると先程とは逆に読み取られる電圧の値が大きくなります。

ケース② センサーが暗い センサーが明るい
合成抵抗R1+Cds 24kΩ(23kΩ+1kΩ) 3.2kΩ(2.2kΩ+1kΩ)
流れる電流 0.21mA 1.56mA
アナログポート電圧(Vr1) 0.21V 1.56V

前者は「暗くなった事を検出する回路」等に向いていますし、後者は「周辺の光の強さを計測する回路」といった使い方に向いていると言えます。
簡単な素子で作った回路で計測した値を自由にプログラム中で扱えるのがマイコン電子回路の面白い所ですが、ちょっとだけ時間をかけて、回路自身の作り方にもひと手間をかけてみると、より効果的な活用法が実現できる様になります。

マイコンの中のデータを確認する方法について

色々なプログラムや電子回路を作っていく様になると、製作途中の段階で接続されているセンサーから読み取っている値や、プログラム中の変数がどうなっているか確認したくなる事があります。本格的な計測を行うのであればマイコンと回路の間に様々な計測器を割り込ませる事になるのですが、とりあえずプログラム中の変数に記録されているデータであれば、プログラム編集のSDKを実行しているコンピュータに通信でデータを送ってモニタリングする事ができます。
Arduino用SDKに「シリアルモニタ」という機能があります。確認したいプログラムにシリアルのデータ通信命令を追加して、画面に表示する事ができます。
02_Serial_01.jpg

基本的なシリアル通信のプログラム

/***************************************************************************/ /* ArduinoUNO 基本的なシリアル通信プログラム */ void setup() {  Serial.begin(9600); //パソコンとのシリアル通信を宣言します。通信レートは9600bpsで設定します。 } void loop() {  int cds; //光センサーの読み取り値を格納するラベル「cds」を宣言。  cds = analogRead(0); //アナログポート0番ピンから光センサーの値を読み取ります  Serial.println(cds); //読み取った値をシリアルポート(=パソコン)に送信  delay(1000); //1秒間待機します。以後、loop()で繰り返します } /***************************************************************************/

通常はプログラム転送用に接続しているUSBケーブルが、シリアル通信ケーブルとして機能します。データを表示したいプログラムにコマンドを追加して、ケーブルをつないだままプログラムを実行します。

先に作った「光センサーの値を読み取るプログラム」を改造して、現在の状態をシリアルモニタに送信するプログラムを作ってみます。
送信するデータは、読み取った値、その値からの判定結果として「明るい」「暗い」の文字データを送信してみます。

明るい/暗いを判定してデータ送信するプログラム

/***************************************************************************/ /* サンプルプログラム 「光センサーを読み取る」*/ /* 変数「LED」をデジタルポート13番ピンに設定する */ /* 変数「CDS」に、アナログポート0番ピンの値を読み取ります */ int LED=13; int CDS; /* 13番ピンを出力ポートに設定します */ void setup() {  pinMode(LED,OUTPUT);  Serial.begin(9600); /*パソコンとのシリアル通信を宣言します。通信レートは9600bpsで設定します。*/ } /* アナログポート0番の値を読み取り、しきい値以上だったら「暗い」、以下だったら「明るい」と送信します */ void loop() {  CDS = analogRead(0);  digitalWrite(LED,HIGH); // LED点灯  if(CDS>800)  {   digitalWrite(LED,LOW); // LED消灯   Serial.print(" 暗い :");   Serial.println(CDS);   delay(1000); } else {   Serial.print("明るい :");   Serial.println(CDS);   delay(1000); } /* Serial.print("送信するデータ”); は改行無し */ /* Serial.println("送信するデータ”); は改行有りになります。 */ } /***************************************************************************/

プログラムを書き込んで、SDKのメニューからシリアルモニターを開いてみましょう。

02_Serial_02.jpg

プログラムを実行してシリアルモニタを開くと、光センサーの読み取り値など送信したデータが表示されます。

高度なプログラムを作成できる様になると、パソコン上で動作する別のソフトウェアにデータを送って表示する事なども可能になりますが、取りあえず今の状態を確認できれば良い、と言った場合にはシリアルモニタが役に立ちますので、使い方は覚えておいていいと思います。

今後も色々なセンサーをご紹介したいと思いますが、そろそろ動くモノについても取り上げたいと思いますので、次回はサーボモーターの制御について書けたらいいなと考えています。

1
1
R_Castle さんが 2020/01/20 に 編集 をしました。 (メッセージ: 初版)
R_Castle さんが 2020/01/22 に 編集 をしました。
R_Castle さんが 2020/01/23 に 編集 をしました。
ログインしてコメントを投稿する