アナログ入力とAD変換

  1. アナログ入力とAD変換

    1. 光センサー

       光センサーは光の強さにより、抵抗値が変わる物質(cds)を利用しています。光が殆どないときは、数十Kオームの高抵抗ですが、、室内照明程度の明るさで、数Kオームまで抵抗が低下します。



       このcdsの抵抗変化を電圧として取り出し、PICのAD変換機能を利用すると、光センサーからの電圧により、出力の制御を行うことができます。

    2. センサー回路

       図で楕円で囲まれた抵抗の記号がCDS光センサです。CDSの面への明るさが変わると、図の出力端子の電圧が変化します。

      テスターでcdsの面を室内光をあてた場合と、指で塞いだ場合の抵抗を測定してください。次に、図のように20kΩ程度の抵抗(図では70kですが変更)を直列に接続し、5Vの電圧をかけたときの出力電圧を測定してください。CDSの抵抗を r kΩ(Ω) としたとき、 出力電圧は 5 * ( r / ( r + 20) ) となることを確認してください。

    3. AD変換

       1,0 の2値でなく、電圧値などの物理量がそのまま値となるような信号をアナログ信号といいます。アナログ信号を入力として、それを、ディジタル値に変換する機能を A/D (アナログディジタル)変換といいます。16F873にはこのAD変換機能が組み込まれています。
       AD変換を行うには、setup_adc_ports(AN0)でアナログ信号を入力する端子と、setup_adc(ADC_clock_div_32);で変換用クロックを指定します。ここでは、Aポート0ビットをアナログ入力端子とします。
       setup_adc_ports(AN0);//A0端子をアナログ入力AN0として利用する
       setup_adc(ADC_clock_div_32);//クロックは内部クロックの1/32 
       16F873は6本のアナログ信号端子があります。まず、まず set_adc_channel(0) で読み込む端子(チャンネル)を指定し、少し時間を置いてから read_adc() で変換値を読み込みます。読み込む値は10bitですから、変数は long 型で宣言します。
       long vd;//16ビット整数
       set_adc_channel(0);//0チャンネルを選択
       delay_us(30);//変換時間待つ
       vd=read_adc();//変換結果を読む

    4. AD変換を利用する場合の電源

       PICでAD変換機能を利用する場合、PIC の電源として十分安定化した電源を利用する必要があります。簡単なDCアダプタの場合、AD変換の出力が10以上ばらつきます。良い電源がない場合、電池を利用すると効果的です。

  2. 応用とプログラム

    1. プログラム概要

       #device ADC=10 はAD変換のビット数を指定します(#device=8 とすると8ビットで読み込みます。)読み取りは10ビットになりますから、読み取り関係の変数は long 指定をして16ビット変数にします。先頭でAD変換を設定します。ここでは、アナログは0チャンネル(AN0)のみを利用します。
       setup_adc_ports(AN0);
       setup_adc(ADC_clock_div_32);
       set_adc_channel(0);
      コンパイルで、AN0がエラーになる場合、
      #define AN0 0x0E
      を#include の後に付けてください。
      最初にAD変換の設定を行ったのち、繰り返しに入ります。
      vd0に読み取った後、
       if(vmax0 < vd0) vmax0=vd0;//最大の更新
      で、最大値(vmax0)を更新します。
      繰り返しの中で100回AD変換し、最大と最小と平均値を表示しています。次に読み取り値の平均値を計算するため、vsum0 に読みとり値を加えます。ct で繰り返しを計数し、10回繰り返したら vsum0 を10で割り平均値を求めます。この値を、最大と最小を16段階で表示します。
      df=(vmax0-vmin0)/15;//最大と最小の間を15レベルにする
      dv=(vsum0-vmin0)/df;
      dvが16段階の表示値になります。これを  output_c(dv); でCポートのLEDで表示します。

    2. ソース


      //A0(2ピン)にCDSの電圧を接続する
      //Cポートの下位4ビットにLEDを接続する
      //cds の明るさの変化を15段階にしてポートCのLEDで表示する
      #include <16F873.h>
      #device ADC=10
      #fuses HS,NOWDT,NOLVP,NOPROTECT,NOBROWNOUT
      #use delay(clock = 20000000)
      
      long vd0,df;
      int ct,sw,dv;
      long vmax0,vmin0,vsum0;
      
      void main(){
      
        setup_adc_ports(AN0);
        setup_adc(ADC_clock_div_32);
        
        ct=0;
        vsum0=0;
        vmax0=0;vmin0=10000;
      
        while(1){
      
           set_adc_channel(0);
           delay_us(10);      
           vd0=read_adc();
      
           if(vmax0 < vd0) vmax0=vd0;//最大の更新
           if(vmin0 > vd0) vmin0=vd0;//最小の更新
           vsum0 += vd0;
      
           if (ct==10) {
                   output_toggle(PIN_B0);
                   vsum0=vsum0/10;//平均
                   df=(vmax0-vmin0)/15;//最大と最小の間を15レベルにする
                   dv=(vsum0-vmin0)/df;
                   if(dv>15) dv=15;//15を超えたときは15にする
                   ct=0;
                   output_c(dv);
               }
               //delay_us(10); 
           ct++;
           delay_ms(100);
        }
      
      }
  3. 実験

    1. 回路制作

       電源から20KΩでCDS に接続しCDSの他の端子をグランドに接続します(図では4.7kですが変更、A1に接続するスイッチは不要)。ポートC(下位4ビット)にはLEDを接続します。

    2. 実験

       プログラムをコンパイルし、MicroCodeLoader 経由でPICに書き込み実行してください。PICにはシリアル接続が必要です。
      プログラムを書き込んだら、cds の面を指でふさいで、明るさを変化させます。このとき、LEDの表示が変化することを確認してください。

  4. 拡張・アンケート


    1. 演習:10進表示

       測定結果を10段階にして、その値を7素子数字表示してください。

    2. 表示機能の拡張

      表示にLCD(液晶)や3桁数字表示を用いれば、もっと詳細な明るさを知ることができます。LEDの代わりにもっと明るい照明を利用すれば、暗くなったら自動点灯する灯りとして利用できます。
      (このとき、オンにするレベルLv1とオフにするレベルLV2に差をつけないと、境界の明るさで点灯と消灯を繰り返してしまいます。

    3. アンケート

      CDSによる明るさ取得法は理解できましたか? 1:できた 2:できない
      AD変換法は理解できましたか? 1:できた 2:できない
      プログラムは実行できましたか? 1:できた 2:できない
      数字表示による、10段階表示はできましたか? 1:できた 2:できない