318.PICでA/D変換(PIC16F873)


2003/02/05 【ソフトウエア編TOPに戻る】

今回はPICのA/D変換機能を使ってみましょう。PIC16F84AにはA/D変換機能が付いていませんので、今回もPIC16F873の出番ということになります。世の中にはツワモノがいて、外部に接続したコンデンサの充電時間を計測してPIC16F84AでA/D変換もどきをしてしまう人もいるようですが、ここでは素直に内蔵のA/D変換機能を利用することにします。

A/D変換とは連続的に変化するアナログ電圧量を、ある一定期間ごとに切り取って(サンプリングして)所定のビット数のデジタル値で近似する技術です。外界の事象を電気回路に取り込むためのセンサーの多くは、検知した情報をアナログ量で出力しますが、マイコンはデジタル値しか扱うことができないため、マイコンに取り込むためにA/D変換を行うわけです。PIC16F873では、最大で10BITのA/D変換出力を得ることができます。これは、アナログの基準電圧を5Vとした場合、5/1023 = 約5mVのアナログ電圧の変化をデジタルで取り込むことができるということです。

今回は、アセンブラでのA/D変換プログラムと、CCSのCコンパイラを使ったA/D変換プログラムの両方をご紹介します。ついでに、I2C通信を使って、ひとつのボリュームによって4個のサーボモータを同時に首振りさせるプログラムもご紹介しましょう。


318−1.PIC16F873のA/D変換

PIC16F873などの28ピンデバイスには、5チャンネルのA/D変換用アナログ入力がついています。ただし、PICの内部には1チャンネル分のA/D変換機能しか持っていないので、これらの入力端子からどれかひとつを選択して、A/D変換を実行する形となります。

A/D変換を行う場合に必要となるレジスタには以下の2つがあります。

■ADCON0レジスタの機能

A/D変換の動作設定を行います。

7 6 5 4 3 2 1 0
ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE - ADON

 

ADCS1〜0:A/D変換のクロック選択

ADCS1,0

クロック

0 0 Fosc/2
0 1 Fosc/8
1 0 Fosc/32
1 1 Frc(RC発振)

 

CHS2〜0:A/D変換アナログ入力チャンネル選択

CHS2〜0

アナログチャンネル

0 0 0 CH 0 (RA0/AN0)
0 0 1 CH 1 (RA1/AN1)
0 1 0 CH 2 (RA2/AN2)
0 1 1 CH 3 (RA3/AN3)
1 0 0 CH 4 (RA5/AN4)
1 0 1 CH 5 (RE0/AN5)
1 1 0 CH 6 (RE1/AN6)
1 1 1 CH 7 (RE2/AN7)

CH5〜7はPIC16F873ではサポートしていません。

 

GO/DONE:A/D変換ステータスビット

1 = A/D変換中(このビットをセットするとA/D変換を開始する)

0 = A/D変換中ではない(変換が終了すると自動的にクリアされる)

 

ADON:A/D変換ONビット

1 = A/D変換モジュールを動作させる

0 = A/D変換モジュールを使用しない。消費電流なし。

 

■ADCON1レジスタの機能

A/D変換の基本設定を行います。

7 6 5 4 3 2 1 0
ADFM - - - PCFG3 PCFG2 PCFG1 PCFG0

 

ADFM:A/D結果のフォーマット選択

1 = 右詰 ADRESHの6MSBは「0」とリードされる。

0 = 左詰 ADRESLの6LSBは「0」とリードされる。

A/D変換結果の10BITは、ADRESHとADRESLの2個の8ビットレジスタに格納されます。その時、以下の2種類のフォーマットから格納方法を選択できるということです。

【右詰】:A/D変換結果のLSB8ビット分を取り出し安いフォーマットです。

ADRESH   ADRESL
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
- - - - - - 9 8 7 6 5 4 3 2 1 0

【左詰】:A/D変換結果のMSB8ビット分を取り出しやすいフォーマットです。

ADRESH   ADRESL
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0 - - - - - -

 

PCFG3〜0:A/Dポートの構成選択

PCFG

3-0

AN7

RE2

AN6

RE1

AN5

RE0

AN4

RA5

AN3

RA3

AN2

RA2

AN1

RA1

AN0

RA0

Verf+

Vref-

Chan/

Refs

0 0 0 0  A A A A A A A A VDD VSS 8/0
0 0 0 1 A A A A Vref+ A A A RA3 VSS 7/1
0 0 1 0 D D D A A A A A VDD VSS 5/0
0 0 1 1 D D D A Vref+ A A A RA3 VSS 4/1
0 1 0 0 D D D D A D A A VDD VSS 3/0
0 1 0 1 D D D D Vref+ D A A RA3 VSS 2/1
0 1 1 x D D D D D D D D VDD VSS 0/0
1 0 0 0 A A A A Vref+ Vref- A A RA3 RA2 6/2
1 0 0 1 D D A A A A A A VDD VSS 6/0
1 0 1 0 D D A A Vref+ A A A RA3 VSS 5/1
1 0 1 1 D D A A Vref+ Vref- A A RA3 RA2 4/2
1 1 0 0  D D D A Vref+ Vref- A A RA3 RA2 3/2
1 1 0 1 D D D D Vref+ Vref- A A RA3 RA2 2/2
1 1 1 0 D D D D D D D A VDD VSS 1/0
1 1 1 1 D D D D Vref+ Vref- D A RA3 RA2 1/2

PCFG3〜0にセットするビットによって、RE2〜0,RA5〜0の各端子を通常のPIOとして利用するか、アナログ入力端子として利用するかを、上のパターンから選択します。Vref+Vref-は、電源電圧VDD、電源GND VSS以外をA/D変換の基準電圧にしたい場合に利用するものです。Chan/Refsで示しているものは、それぞれのパターンにおいてのアナログ入力チャンネル数/外部基準電圧入力端子数を示しています。

逆に言うと、端子の用途を上記以外のパターンで構成することは出来ませんので、ハードウエアを組むときには、予めどのパターンにするかを決めておかなければなりません。

ちなみに、AN7〜AN5はPIC16F873ではサポートしていません。

 

PICのA/D変換では、これらのレジスタを使ってA/D変換機能を実行させます。実際の使い方は、この後のアセンブラによるプログラム事例を見て頂くと良く分かります。

【先頭に戻る】


318−2.アセンブラでのA/D変換プログラム例  adtest1.asm

 

このプログラムでは、AN0チャンネルから0V〜5Vのアナログ電圧を入力し、A/D変換結果を左詰フォーマットにして上位8ビットをPORTBに出力することを永遠に繰り返します。AN0チャンネルにボリュームを接続すれば、ボリュームツマミを左右に回転させることによってPORTBに接続された8ビットのLEDの2進数表示が上下します。

ソースコードはここをクリックするとダウンロードできます。adtest1.asm また、実験のハードウエア環境は、PIC学習用ボード簡易型実験用I/Oボードを組み合わせて使用します。

;**********************************************************************
;A/D CONV TEST1                                                              RIKIYA 2001.11.08
;DEVICE : PIC16F873
;CLOCK : 20MHz
;
;**********************************************************************
          list p=16F873
          #include <p16F873.inc>

          __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF

          TCNT          EQU 20H
;**********************************************************************
          ORG           0x000              ; processor reset vector
          GOTO         MAIN              ; go to beginning of program

MAIN   BSF           STATUS,RP0    ;メモリーバンクを1にセット
          CLRF         TRISB             ;TRISBをクリア PORT-Bを出力にセット
          MOVLW      081H               ;Wレジスタに81Hをセット
          MOVWF      OPTION_REG    ;OPTION_REGに81Hをセット PORT-B PULL UPなし
          MOVLW      00EH               ;Wレジスタに0EHをセット
          MOVWF      ADCON1          ;CH0のみAIN REF = VDD 
          MOVLW      001H               ;Wレジスタに01Hをセット
          MOVWF      TRISA             ;TRISAに01Hをセット PORT-A0だけを入力
          BCF           STATUS,RP0    ;メモリーバンクを0にセット
;***********************************************************************
;A/D変換処理を繰り返す
;***********************************************************************
LOOP
          MOVLW      081H                ;Wレジスタに81Hをセット
          MOVWF      ADCON0           ;ADCON0に81Hをセット A/D CH0,Fosc/32,CHARGE
          CALL         ADWAIT            ;20uSの待機
          BSF           ADCON0,GO      ;ADCON GOビットを1にセット 変換開始
WAIT
          BTFSC       ADCON0,GO      ;GOビットが0なら、次の命令をジャンプ
          GOTO        WAIT                 ;ラベルWAITに戻る
          MOVF        ADRESH,W         ;AD変換データを取り込む
          MOVWF      PORTB             ;データをPORT-Bに出力
          CALL         ADWAIT            ;1アクイジション待機
          GOTO        LOOP               ;ラベルLOOPに戻る
;***********************************************************************
;20uSのタイマ
;20MHz 1サイクル 0.2uS
;100サイクルx0.2uS = 20uS
;***********************************************************************
ADWAIT
          MOVLW     020H                 ;1 Wレジスタに20H(32)をセット
          MOVWF     TCNT                ;1 TCNT変数に1AHをセット
          NOP                                 ;1
TLOOP
          DECFSZ    TCNT               ;1x31+2 TCNT-1を行い0になったら次の命令ジャンプ
          GOTO       TLOOP             ;2x31 ラベルTLOOPに戻る
          RETURN                           ;2 戻る

          END

 ソフトの動作については、コメント文が全てです。なので、細かな解説は省略させて頂きますが、ここでは要点だけを説明することにしましょう。

          MOVLW      00EH               ;Wレジスタに0EHをセット
          MOVWF      ADCON1          ;CH0のみAIN REF = VDD 
          MOVLW      001H               ;Wレジスタに01Hをセット
          MOVWF      TRISA             ;TRISAに01Hをセット PORT-A0だけを入力

 

MAINラベルから4行後に上記の記述があります。ここでは、ADCON1レジスタに0EH(0000 1110)を書き込んでいます。ADCON1レジスタの機能は以下のような意味でした。

7 6 5 4 3 2 1 0
ADFM - - - PCFG3 PCFG2 PCFG1 PCFG0
0 0 0 0 1 1 1 0

なので、ここでは「A/D変換結果を左詰で格納し、AN0チャンネルのみをアナログ入力にする」という意味になります。

そしてすぐ後に、PORTAの0ビットだけを入力に設定しています。これは、アナログ入力に指定したビットは、TRISレジスタによって入力端子に設定しなければならないためです。これを忘れると、A/D変換機能は正常に動作しないので注意してください。

 

LOOP
          MOVLW      081H                ;Wレジスタに81Hをセット
          MOVWF      ADCON0           ;ADCON0に81Hをセット A/D CH0,Fosc/32,CHARGE
          CALL         ADWAIT            ;20uSの待機
          BSF           ADCON0,GO      ;ADCON GOビットを1にセット 変換開始
WAIT
          BTFSC       ADCON0,GO      ;GOビットが0なら、次の命令をジャンプ
          GOTO        WAIT                 ;ラベルWAITに戻る

 

次に、実際のA/D変換処理を開始します。先ず始めに、ADCON0レジスタに81H(1000 0001)を書き込んでいます。ADCON0レジスタの機能は以下のような意味でした。

7 6 5 4 3 2 1 0
ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE - ADON
1 0 0 0 0 0 0 1

なので、ここでは「A/D変換クロックをFosc/32にして、A/D変換の動作をONにする」という意味になります。ここで、A/D変換の動作をONにするということは、具体的にはA/D変換入力のサンプルホールド回路に、入力電圧を充電(チャージ)するということです。

アナログ量をデジタル値に変換するには一定の時間が必要です。1ビット当たりの変換時間はTadとして定義されており、例えばデバイスのクロックが20MHzのときにFosc/32の設定にしてあると、Tadは1.6μSになるようです。10ビットのA/D変換では12Tad分の時間が必要になることから、19.2μSの変換時間が必要になるということになります。

例えば、この19.2μSの間に入力されるアナログ電圧が変化してしまうと、サンプリングしたい瞬間の電圧値を正確にデジタルに変換することができません。そこで、A/D変換器には入力電圧を充電して一定に保つためのサンプルホールド回路という部分がありますADONビットをにするということは、この充電を開始するという動作になります。

 

ADCON0レジスタに上記の値をセットした後、ADWAITというラベル部分をCALLして、20μSの時間潰しをしています。これは、サンプルホールド回路に入力電圧が充電される時間を確保しています。この時間が短いと、デジタルに変換される値は、実際の入力電圧よりも常に小さめになります。

 

20μSの待機後、ADCON0レジスタのGOビットにセットして、実際のA/D変換を開始します。

 

A/D変換には先ほどご紹介したように12Tad分の時間が必要なため、

WAIT
          BTFSC       ADCON0,GO      ;GOビットが0なら、次の命令をジャンプ
          GOTO        WAIT                 ;ラベルWAITに戻る

でA/D変換が終了するまで待機しています。ADCON0レジスタのGOビットは、A/D変換が終了すると自動的に0にクリアされるため、GOビットが1の間ループで時間潰しをしています。

 

          MOVF        ADRESH,W         ;AD変換データを取り込む
          MOVWF      PORTB             ;データをPORT-Bに出力
          CALL         ADWAIT            ;1アクイジション待機
          GOTO        LOOP               ;ラベルLOOPに戻る

 

あとは、ADRESHレジスタからA/D変換結果の上位8ビットを取り出し(左詰なので)、ポートBに出力しています。出力後にもう一度ADWAITCALLされているのは、次の入力電圧の充電を開始するまでの間に待機時間を設けなければならないためです。本当は2Tadだけ待てばよいのですが、ここではすでに存在しているサブルーチンを使ってしまっています。その後LOOPラベルに飛んで、再度A/D変換を繰り返します。

 

ADWAITのサブルーチンでは、20μSの待機時間を作り出しています。待機時間の生成については、312.PICの実行速度を予測するのページを参照して下さい。

【先頭に戻る】


318−3.CCS CコンパイラでのA/D変換プログラム例  adtest11.c

次に、adtest1.asmと同じことを、C言語で組んでみましょう。

ソースコードはここをクリックするとダウンロードできます。adtest11.c  また、実験のハードウエア環境は、先ほどと全く同じです。

//////////////////////////////////////////////////
// A/Dテストプログラム                                          //
// PIC16F873                                RIKIYA 2003.01.16 //
//                                                       ADTEST11.C //
// AN0チャンネルからアナログ入力してRBに出力         //
//////////////////////////////////////////////////

#include <16f873.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#device ADC=10                              // 10BIT A/D変換
#use delay(clock = 10000000)             // clock 10MHz
#use fast_io(B)                                 // 固定入力モード

//メイン関数////////////////////////////////////
main(){
long data;
      set_tris_b(0x00);                         // RB 7-0:OUT
      setup_adc_ports(RA0_ANALOG);   // AN0チャンネル有効
      setup_adc(ADC_CLOCK_DIV_32);  // Fosc/32 

      while(1){
            set_adc_channel(0);              // ANチャンネルの選択
            delay_us(20);                      // 充電時間の待機
            data = read_adc();               // A/Dデータの読み込み
            output_b(data >> 2);            // 上位8bitのデータを表示
      }
}

先にご紹介したアセンブラで記述したプログラムと同じ機能が、C言語ではこれだけの記述で実現できます。ソースコード中の記述はCCSのCコンパイラ上の約束ごとばかりで、全てコメント文に記載されている通りですので、ここでの解説は省略させて頂きます。

このように、C言語にすると見た目にも簡単で分かりやすいソースで済んでしまいます。

しかし、PICに流し込むHEXファイルの大きさで見てみると、以下のような開きがあるのも事実です。

アセンブラでのHEXファイル 186バイト
CコンパイラでのHEXファイル 357バイト

どちらが良いかは、開発効率、HEXファイルの容量、実行時間の管理、必要な記述のきめ細かさなどから総合的に判断して選ぶのが良いでしょう。

【先頭に戻る】


318−4.I2C通信を利用した4個のサーボモータの首振り adtest2.c 

 

ここまででご紹介したA/D変換のプログラム例ではちょっとつまらないので、I2C通信との組合せの事例をご紹介しましょう。ただし、C言語だけですが...。

ここでは、マスターとなるPICにボリュームを取り付けてA/D変換を行い、取り込んだデジタル値をI2C経由で4個のスレーブとなるPICに送ります。スレーブでは受け取ったデータに基づいてPWM波形を出力し、サーボモータの首振りを行います。なので、ここでは4個のサーボモータが同時に、同じように首振りをするという動作になります。

以下にマスター用スレーブ用のプログラムを、それぞれご紹介しましょう。

 

■マスター用プログラム

ソースコードはここをクリックするとダウンロードできます。adtest2.c  また、実験のハードウエア環境は、PIC学習用ボード簡易型実験用I/OボードI2Cテストボードを組み合わせて使用します。

//////////////////////////////////////////////////
// A/Dテストプログラム                                           //
// PIC16F873                                 RIKIYA 2003.01.16 //
//                                                            adtest2.C //
// I2Cマスター役となりA/Dからの入力をもとに               //
// スレーブ4個のPWM制御をする                                //
//////////////////////////////////////////////////

#include <16f873.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#device ADC = 10                                      // 10BIT A/D変換
#use delay(clock = 10000000)                       // clock 10MHz
#use fast_io(B)                                          // 固定入力モード
#use i2c(MASTER,SDA=PIN_C4,SCL=PIN_C3,FAST,FORCE_HW)

int add[4] = {0,2,4,6};                                   //スレーブアドレス

//メイン関数////////////////////////////////////
main(){
int i;
long data;

      setup_adc_ports(RA0_ANALOG);             // AN0チャンネル有効
      setup_adc(ADC_CLOCK_DIV_32);            // Fosc/32 
      set_tris_b(0xf0);                                   //RB 7-4:IN 3-0:OUT
      set_tris_c(0x00);                                  //RC 7-0:OUT
      output_float(PIN_C3);                           //I2C pin float
      output_float(PIN_C4);                           //I2C pin float

// 4個のサーボの首振りを繰り返す
      while(1){
            set_adc_channel(0);                       // ANチャンネルの選択
            delay_us(20);                                // 充電時間の待機
            data = read_adc();                         // A/Dデータの読み込み

            for(i=0;i<4;i++){
                  i2c_start();                            //スタートコンディション
                  i2c_write(add[i]);                     //アドレスaddに送信
                  i2c_write(data >> 2);               //データ上位8bitを送信
                  i2c_stop();                             //ストップコンディション
                  delay_ms(3);
            }
      }
}

プログラムの内容としては、先ほどご紹介したadtest11.cと、316.PICでI2C通信のページでご紹介しているI2C通信プログラムを合体させただけですので、細かな説明は省略させて頂きます。

送信したいスレーブのアドレスをadd[4] = {0,2,4,6};で配列変数に格納し、 for文の中のi2c_write(add[i]);で送信しています。i2c_write(data >> 2); で、10ビットデータの上位8ビットだけをデータとして送信しています。

 

■スレーブ用プログラム

ソースコードはここをクリックするとダウンロードできます。picpwm21s.c  

//////////////////////////////////////////////////
// PWMテストプログラム21(2改)                             //
// PIC16F873                                RIKIYA 2003.02.01 //
//                                                        picpwm21s.c //
// I2Cスレーブ役としてマスターからのデータに              //
// 基づいてサーボモータを動かす。                            //
// スレーブアドレスは、PB4〜7ビット                           //
// から読み込むデータで自動設定する                        //
//////////////////////////////////////////////////

#include <16f873.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock = 10000000)                       // clock 10MHz
#use fast_io(B) // 固定入力モード
#use i2c(SLAVE,SDA=PIN_C4,SCL=PIN_C3,ADDRESS=0x00,FAST,FORCE_HW)

void add_set(int add);                                  // プロトタイプ宣言
void ccp1_int(void);                                     // プロトタイプ
void ccp2_int(void);                                     // プロトタイプ

//メイン関数/////////////////////////////////////////
void main (){
int *sspcon = (int *)20;                           //変数*sspconにSSPCONのアドレス20をセット

long data;
      setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
      setup_ccp1(CCP_COMPARE_INT);          // CCP1コンペアマッチ割込み設定
      setup_ccp2(CCP_COMPARE_INT);          // CCP2コンペアマッチ割込み設定
      set_timer1(0x0000);                             // TMR1クリア
      CCP_1 = 3752;                                   // パルス幅 0.4u * 1 * 3752 = 1.5mS
      CCP_2 = 50000;                                 // 周期 0.4u * 1 * 50000 = 20mS

      set_tris_b(0xf0);                                  //RB 7-4:IN 3-0:OUT
      set_tris_c(0x18);                                 //RC 4,3:IN 7-5,2-0:OUT
      output_float(PIN_C3);                          //I2C pin float
      output_float(PIN_C4);                          //I2C pin float
      output_b(0x01);                                  //正常起動確認

// スレーブアドレス設定
      add_set((input_b() >> 3) & 0x0e);

      enable_interrupts(INT_CCP1);               //CCP1コンペアマッチ割込み許可
      enable_interrupts(INT_CCP2);               //CCP2コンペアマッチ割込み許可
      enable_interrupts(GLOBAL);                //全ての割り込みを許可

      while (1) {
            *sspcon = *sspcon & 0xBF;           //OVFのクリア
            data = i2c_read();                        //データ受信
            if(data != 0){
                  CCP_1 = 2500+(data*10);       //パルス幅の設定
                  output_b(data);                     //受信データのモニタ
            }
      }
}

//パルスクリア///////////////////////////////////
#INT_CCP1
void ccp1_int(){
      output_bit(PIN_C2,0);                         // RC3BITを0にする。
}

//パルス出力/////////////////////////////////////
#INT_CCP2
void ccp2_int(){
      if(CCP_1 != 0x0000){                         // CCP_1が0でなければ、
            output_bit(PIN_C2,1);                  // RC3BITを1にする。
      }
      set_timer1(0x0000); // TMR1クリア
}

//アドレス自動設定////////////////////////////////////
void add_set(int add){
int *sspadd = (int *)147;                        // 変数*sspaddにSSPADDのアドレス147をセット
      *sspadd = add;                              // SSPADDレジスタにアドレスをセット
}

このスレーブ側のプログラムは、317.PICでサーボを動かすのページでご紹介したpicpwm2.sの改良版です。基本的には同じですが、以下の点を付け加えています。

 

先ず、*sspconというポインタ変数にアドレス20を設定しています。これにより、sspconレジスタを操作できるようにしています。

int *sspcon = (int *)20;                      //変数*sspconにSSPCONのアドレス20をセット

 

次に、data = i2c_read();でデータ受信を行う前に、*sspcon = *sspcon & 0xBF; を実行しています。これは、sspconのビット6(オーバーフローフラグ)をクリアするための処理です。

 

           *sspcon = *sspcon & 0xBF;           //OVFのクリア
            data = i2c_read();                        //データ受信
            if(data != 0){
                  CCP_1 = 2500+(data*10);       //パルス幅の設定
                  output_b(data);                     //受信データのモニタ
            }

 

高速ループで繰り返しデータの送受信を行う場合、スレーブ側が受信データレジスタから受信データを読み出す前に、マスター側から次のデータが送られてきてしまう場合があります。このときsspconレジスタオーバーフローフラグが立ち、ソフト上で明示的にクリアしてあげるまで正常なデータ受信が再開できません

今回、マスター側からのデータ送信の間隔が早く、スレーブ側の受信準備とうまくタイミングが合わずにオーバーフローを起こしてしまうため、上記のような処理でフラグをクリアしています。

ちなみに、オーバーフロー状態に陥ると、受信データとして自分のスレーブアドレスが取り出されるという現象が起き、それ以降の通信が出来なくなるようです。上記のようにフラグをクリアしてあげると、どんなに早く送受信を繰り返しても、通信動作は保たれることが確認できました。

しかし、たまに取りこぼしを起こすのか、受信データが0になる現象が数秒に1度の割合で起こる場合があります。そため、サーボの首振りがたまにピク付くことがあります。残念ながら原因の追求までには至っていませんが、とりあえず「くさいものにはふたをする」という精神のもと、if(data != 0){ } 文によってピク付きを抑えています。

【先頭に戻る】


318−5.I2C実験風景

 

以下の写真が、I2C通信を使ったA/D変換実験の風景です。

右上の基板がI2Cテストボードでスレーブ用のPICが4個実装されています。右下の基板がPIC学習用ボードで、マスター用のPICとして利用しています。左側の基板が簡易型実験用I/Oボードで、A/D変換入力とPWM出力のコネクタ変換を行っている部分です。

写真の下側にポテンショメータが写っていますが、これを廻すと写真上側のサーボ4個が同じように首振りをします。

【先頭に戻る】


実際問題としてポテンショメータでサーボを制御するという用途にわざわざI2Cを使うということ自体、本当に必要なのか?という点が疑問ではありますが、I2C通信とA/D変換を組み合わせた事例のひとつとしてご紹介してみました。

力弥としては、これをステップとしてI2C通信を使ったギヤードモータのサーボ化に進むのが目的です。351.ギヤードモータのサーボ化1352.ギヤードモータのサーボ化4CH対応のページでご紹介している角度制御を改良し、もっとレスポンス良く精度の高い角度制御にしたいと思っていますので、その取り組みは、また追ってご紹介したいと思います。

 

【ソフトウエア編TOPに戻る】

 


【表紙に戻る】