第 11 回 センサー

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

ここで、外部入力として、アナログ入力を受け付けることを考えます。

11-1. Arduinoのアナログ入力

C言語版

Arduino では、初期設定で、アナログポート A0 から A5 までが設定されて いるため、 analogRead(ポート番号)で、アナログ入力値を読み 込むことが出来ます。 これは、0から1023までの値で、 int 型の変数で受けます。

なお、作成したトレーニングキットでは、 A0 から A3 まではディジタル出 力ポートとして使う前提で設計してあるので、 本講義ではA4とA5をアナログ入力ポートとして使うこととします。

アナログ入力ポートとはA/Dコンバータが内蔵されていて、電圧値を読み込 みます。 A/Dコンバータは電圧値を瞬時に数値化できるのではなく、 電圧値が得られる時間は分解能に応じて長くなります。

例11-1


  int val;
  val=analogRead(A4);

例11-2

A4のアナログ値10bitの上位4bitを7SEGに表示するプログラム


const byte out7seg[]={6,7,8,9,10,12,13,0xff};
const byte pattern[]={
      0b1111110, //0
      0b1010000, //1
      0b1101101, //2
      0b1111001, //3
      0b1010011, //4
      0b0111011, //5
      0b0111111, //6
      0b1110000, //7
      0b1111111, //8
      0b1111011, //9
      0b1110111, //A
      0b0011111, //b
      0b0101110, //C
      0b1011101, //d
      0b0101111, //E
      0b0100111  //F
};
void write7seg(byte x){
  for(byte i=0; out7seg[i]!=0xff; i++){
    digitalWrite(out7seg[i],pattern[x]&1<<i);
  }
}
void setup() {
  for(byte i=0;out7seg[i]!=0xff;i++){
    pinMode(out7seg[i], OUTPUT);
  }
  pinMode(A4,INPUT);
  analogReference(DEFAULT);
}

void loop() {
  byte in = analogRead(A4) >> (10-4);
  write7seg(in);
  delay(1);
}    

例11-3

例11-2に加え、 ボタン1を押すと、そのときのセンサー値を記憶します。 センサー値が記憶値以上になったら、小数点を点け、下回ったら消灯します。 ボタン2を押すと、小数点を点ける、点けないのロジックを反転させます。


const byte out7seg[]={6,7,8,9,10,12,13,0xff};
const byte pattern[]={
      0b1111110, //0
      0b1010000, //1
      0b1101101, //2
      0b1111001, //3
      0b1010011, //4
      0b0111011, //5
      0b0111111, //6
      0b1110000, //7
      0b1111111, //8
      0b1111011, //9
      0b1110111, //A
      0b0011111, //b
      0b0101110, //C
      0b1011101, //d
      0b0101111, //E
      0b0100111 //F
};
const byte button1=4;
const byte button2=5;
const byte dot = 11;
void write7seg(byte x){
  for(byte i=0; out7seg[i]!=0xff; i++){
    digitalWrite(out7seg[i],pattern[x]&1<<i);
  }
}
void setup() {
  for(byte i=0;out7seg[i]!=0xff;i++){
    pinMode(out7seg[i], OUTPUT);
  }
  pinMode(dot, OUTPUT);
  pinMode(button1,INPUT_PULLUP);
  pinMode(button2,INPUT_PULLUP);
  pinMode(A4,INPUT);
  analogReference(DEFAULT);
}

void loop() {
  static bool prev1=HIGH;
  static bool prev2=HIGH;
  static bool now1=HIGH;
  static bool now2=HIGH;
  static int memory = 0;
  static bool higher = true;
  int in = analogRead(A4); 
  write7seg(in >>(10-4));
  now1=digitalRead(button1);
  if(now1==HIGH && prev1==LOW){
    memory = in;
  }
  prev1=now1;
  now2=digitalRead(button2);
  if(now2==HIGH && prev2==LOW){
    higher ^= true;
  }
  prev2=now2;
  digitalWrite(dot, (in >= memory) ^ higher);
  delay(1);
}

光センサー

光センターは光を受けて電気的な性質を変える物質を使用して、光の量など を計測するために使用されます。 電気的性質も様々あり、下記のものがあります。

  1. 抵抗値が変化するCdS
  2. かけた電圧に対して、流れる電流が変化する、光ダイオード、光トラン ジスタ
  3. 光を受けると起電力が生じる太陽電池

CdS

CdSは硫化カドミウムで、光を受けて抵抗値を変える性質を持っています。 抵抗値の変化、電気的な使いやすさなど、最も利用しやすいセンサーのため、 未だに多くの電子工作の教科書でも取り上げられているセンサーです。

但し、非常に有毒なため、特に、破損した場合などの取扱に注意が必要です。 また、廃棄は産業廃棄物として処理する必要があります。 ヨーロッパには2008年以降輸出ができなくなっています。

使用方法としては、10kΩ程度の抵抗と直列に繋いで、電圧をかけると、 繋いだ部分の電圧が変化するので、それをマイコンのアナログ入力に入れる ことで、光の強さを電圧として読み取ることが出来ます。

フォトダイオード

ダイオードのPN接合面に光を当てると起電力が生じ、電圧をかけると電流が 流れるという素子です。 両対数グラフにおいて、照度と流れる電流が直線的に変化します。

I = L α

使用する際は、抵抗とフォトダイオードを直列に繋いで電圧を印加します。 フォトダイオードに流れる電流に応じて、抵抗に電圧降下が生じます。 なお、流れる電流がマイクロアンペアのオーダなので、例えば10[μA] 流れる時に 1[V]の電圧降下を生じさせるには、100[kΩ] の抵抗をつ なぐ必要があります。

光の強さに対して電流が流れるため、精密な測定ができる一方で、光の強さ が指数関数的に増加する時に、流れる電流も指数関数的に増えるので、抵 抗に直列つなぎで計測する場合、計測範囲に注意してください。

フォトトランジスタ

フォトダイオードをバイポーラトランジスタのコレクタとベースに繋いだIC がフォトトランジスタになります。 一定の光を受けるとミリアンペアオーダのコレクタ電流が流れますので、光 の強さの測定というよりは、光によりON, OFF を行うようなものを作るのに 向いています。

但し、コレクタに流せる電流はそれほど大きくないので、電源から抵抗を介 して、コレクタにつなぎ、エミッタを接地します。 そして、コレクタ電圧をマイコンで測定するようにします。 CdSほど自由度はありませんが、安価で、特定の光量でON/OFFするような回 路を作るのに適しています。

太陽電池

太陽電池は光量に応じて起電力を生じる素子です。 一つの素子の起電力は小さいため、多くの素子を直列つなぎとした、面積の 大きな素子として使うのが普通です。 また、普通は、センサーというよりは電池として使用するため、十分な電圧、 電流が得られるような集積度になっています。 大規模な集積度なので、素子としても高価です。

11-2. 実験

実験

半固定抵抗により、可変電圧源を作り、 それを A4 ポートで検出し、得られた10bit の値を0からFまでの値に変換 して LED で表示しなさい。

実験

フォトトランジスタを使用して、明るさを測ります。 フォトトランジスタは、コレクタ、エミッタ間に電圧をかけた状態で光を当て ると、光に応じて電流がコレクタからエミッタに流れます。 そのため、エミッタに抵抗を直列につないでおくと、光が無いときはエミッ タの電圧はほとんど0になり、光が当たった時は抵抗を流れる電流に比例す る電圧になります。

L-51ROPT1D1というフォトトランジスタはon状態で 2mA 流れますので、電圧と して5Vかけたとき、抵抗として、2.5[kΩ]以上を直列につなぐと、飽和 することになります。

  1. フォトトランジスタと1[MΩ] を直列につなぎ、Arduino から5Vを 供給し、抵抗の両端の電圧が光によりどのように変化するかを調べなさい。
  2. フォトトランジスタと抵抗を接続した回路の電圧を Arduino で読み、 7SEG に上位4bitの値を表示するようにしなさい。

回路

実験2回路

演習11-1

明るいか暗いかをキャリブレーションを元に判断する

次の仕様を満たすようなシステムを作りなさい

  1. ボタンを押している間に受光した光の強さの最大値と最小値を記憶し、ボタ ンを離したときに、その値の平均値を閾値とします。
  2. ボタンを押していない間は、閾値より強い光を受けていたらビルドイン LEDを点け、暗い時はLEDを消します。

発展課題

半固定抵抗の角度でモータの回転をコントロールするようにしなさい。

演習11-1


const byte button1=4;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(button1,INPUT_PULLUP);
  pinMode(A4,INPUT);
  analogReference(DEFAULT);
}
void loop() {
  static int thhigh=0;
  static int thlow=0;
  static int thresh=0;
  static bool prev=HIGH;
  int in = analogRead(A4); 
  bool now=digitalRead(button1);
  if(now){  
    if(!prev){
     thresh=(thhigh+thlow)/2.0;
    }
    digitalWrite(LED_BUILTIN,in>thresh);
  }else{
   if(prev){
      digitalWrite(LED_BUILTIN,LOW);
      thhigh=in;
      thlow=in;
   }else{
     if(in>thhigh){
        thhigh=in;
      }
      if(in<thlow){
        thlow=in;
      }     
    } 
  }
  prev=now;
  delay(1);
}

坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科