IoT何をいまさら(106) SAR型ADCの原理回路をArduinoで制御してみる

Joseph Halfmoon

別シリーズでSAR型ADCの原理回路の実験をしました。しかしアナログ部分のみ、SAR(逐次比較)らしいデジタルの2分検索のステートマシンは実装せず、「また後で」などと書いてました。そこで今回はArduinoを使って「2分検索部分」をプログラムしてステートマシンで制御できそ~(でも不安あり)なところをやってみます。

※「IoT何をいまさら」投稿順Indexはこちら

※今回実験に使用のArduino Unoは立派な10 bit ADC搭載なのでわざわざADCを外付けすることはないでしょう。

4ビットSAR型ADCの原理回路

別シリーズでやったのは「4ビット」の回路です。ザックリした動作原理を復習すると以下のとおり。

    1. 4ビットのデジタル出力でR2Rラダーを制御しアナログ比較電圧を出力する(DAC部分。)
    2. 上記の比較電圧と測定すべきアナログ入力電圧をコンパレータで比較して、電圧の大小関係を0、1のデジタルな結果として読み取る
    3. 2分検索の要領で、デジタル出力を上位ビットから決めて行けば所定のビット数だけの繰り返しで「近しい」デジタル値を決定することができる。

今回はArduino Unoを「ステートマシン」として使ったので回路は以下のようになりました。D3からD6が抵抗ラダーの制御用デジタル出力、D7がコンパレータの結果を読み取るデジタル入力です。SAR_ADC_PROTO_Arduino

アナログ的にはフニャフニャ、砂上の楼閣?

別件記事でもアナログ部分の不安定さというか、信号品質の悪さが問題になってましたが、Arduinoに接続したからといってそれが直ることはなく(どちらかというと悪くなる方向?)、ボロボロです。

試みに4ビット16段階の値を出力し、抵抗ラダーの出力(ボルテージフォロワの出力)の波形を観察したものが以下に。結構、不気味な影が見えてます。こんな感じ。

R2Rwave

実際に拡大してみると、階段状の立ち上がり部分で結構きてます。ピコんと。あまりよろしくないです。でも今回は「あくまでデジタル」と割り切って、アナログの問題点には見て見ぬフリ、ともかくステートマシンがそれらしく動けばOKという不甲斐なさ。

実験用のArduinoコード

実験用のコードは、ともかく2分検索らしきことをして、デジタル出力をアナログ入力に追従した値にさせるだけのコードといたしました。いろいろデコレーションしてるとメンドイし。。。

#define COMP (7)
#define BIT0 (3)
#define BIT1 (4)
#define BIT2 (5)
#define BIT3 (6)

int r2r;

int setR2R() {
  if (r2r & 0x8) {
    digitalWrite(BIT3, HIGH);   
  } else {
    digitalWrite(BIT3, LOW);       
  }
  if (r2r & 0x4) {
    digitalWrite(BIT2, HIGH);   
  } else {
    digitalWrite(BIT2, LOW);       
  }
  if (r2r & 0x2) {
    digitalWrite(BIT1, HIGH);   
  } else {
    digitalWrite(BIT1, LOW);       
  }
  if (r2r & 0x1) {
    digitalWrite(BIT0, HIGH);   
  } else {
    digitalWrite(BIT0, LOW);       
  }
  delayMicroseconds(100);
  return digitalRead(COMP);
}

void initR2R() {
  pinMode(BIT3, OUTPUT);
  pinMode(BIT2, OUTPUT);
  pinMode(BIT1, OUTPUT);
  pinMode(BIT0, OUTPUT);
  pinMode(COMP, INPUT);  
}

void setup() {
  initR2R();
  r2r = 0;
}

void loop() {
  r2r = 8;
  if (setR2R()) {
    r2r += 4;  
  } else {
    r2r -= 4;
  }
  if (setR2R()) {
    r2r += 2;  
  } else {
    r2r -= 2;
  }
  if (setR2R()) {
    r2r += 1;  
  } else {
    r2r -= 1;
  }
  if (!setR2R()) {
    r2r -= 1;
  }
  delay(10);
}
実験結果

Digilent Analog Discovery2の「ロジアナ」機能で、デジタル出力の4ビットをBUSとして観察してます。以下一番上のBusというのがデジタル出力の4ビットの値で、8から始めて2分検索しながら、4ステップで出力値にいたるという塩梅です。その下の3,2,1,0はデジタル出力の各ビットです。一番したのDIO4とあるのが、コンパレータの比較結果(デジタル入力)です。アナログ入力値が抵抗ラダーの出力電圧より高いと1、低いと0が見える筈。

アナログ入力4.5V設定

4_5V_HILO

上記のように、4ステップ後15となりました。参照電圧=電源電圧で5Vなので、5V x 15/16 = 4.69Vという換算となります。

アナログ入力4V設定

4V_HILO

こんどは13ね。換算値は4.06V

アナログ入力3V設定。

3V_HILO

換算値3.44V、ちょっとデカイです。

アナログ入力2V設定。2V_HILO

換算値2.19V、3Vと2Vの間の落差デカイです。

アナログ入力1V設定

1V_HILO

換算値0.94V

アナログ入力0V設定0V_HILO

換算値0.31V

もともと4ビットなので「粗い」です(レゾリューションは0.3125V。)しかしま、それより実験結果はもっと悪い。まあ何もしてないのだから当たりまえですかい。そんなに簡単にAD出来たら誰も苦労しない? やっぱりアナログ部分が確固として揺らがない感じにできないとダメでやんすか。

IoT何をいまさら(105) MicroNavRingセンサをArduinoに接続してみる へ戻る

IoT何をいまさら(107) SPI接続のADC、AD7920をArduinoで制御してみる へ進む