PR 記事には広告が含まれています
スポンサーリンク
Translate

ESP32のADCでキャリブレーションされた精度の良い電圧値を取得する方法

スポンサーリンク

ESP32のADCで、簡単に正確な電圧を測定できることがわかりました。

スポンサーリンク

analogReadMilliVolts()

2018年以降に製造されたESP32には、製造時にADコンバータのキャリブレーションデータが書き込まれるようになりました。

このキャリブレーションデータを利用することによって、プログラムで電圧値を取得できるようになりました。

34ピンの電圧値を取得する場合のプラグラムは、以下のようになります。

#define AD_PIN 34

void setup() {
  Serial.begin(115200);
  pinMode(AD_PIN, ANALOG);
}

void loop() {
  Serial.printf("%d[mV]\n", analogReadMilliVolts(AD_PIN) );
  delay(500);
}

analogReadMilliVolts()で電圧値を取得し、シリアルモニターに結果を出力します。

ADピンには1000mVを入力しています。結果は995mVでした。

このように、analogReadMilliVolts()を使うことで、簡単に電圧値を得ることができます。

スポンサーリンク

アッテネータによる歪み

ESP32のADコンバータ自体は1.1VまでしかAD変換することができませんが、入力電圧を小さくさせるアッテネータ(減衰器)の機能を合わせて使うことで、より高い電圧までAD変換できるようになっています。

ESP32のアッテネータは以下の4つの設定ができます。

0dB(1.0倍)
-2.5dB(0.75倍)
-6dB(0.5倍)
-11dB(0.28倍):デフォルト

Arduinoではデフォルトで-11dB(0.28倍)に設定されています。そのため、電源電圧までAD変換することができます。

しかし、このデフォルトで設定されている-11dBのアッテネータには問題があります。

-11dBのアッテネータの特性

このグラフは、アッテネータを-11dBに設定したときの、入力電圧とAD値(analogReadした値)との関係をプロットしたものです。過去にAD値から電圧を算出したかったため、横軸AD値、縦軸が入力電圧というグラフなっています。

電圧値とAD値のグラフは直線になるのが理想なのですが、2200mV付近で傾きが変化し、直線ではなくなっています。このため、AD値から実際の電圧値を求めると、誤差が発生してしまいます。

-6dBのアッテネータの特性

こちらは、アッテネータの設定を-6dBに設定したときの、入力電圧とAD値との関係をプロットしたものです。アッテネータによる減衰率が0.28倍から0.5倍になったため、入力電圧の最大が1900mVに下がりました。

先ほどの-11dBのアッテネータのときと違って、グラフが直線になっています。AD値から電圧値を算出する場合、こちらの方が誤差が少なくなります。

これらのことから、測定電圧の範囲は狭くなりますが、アッテネータを-6dBに設定した方が、直線性が良くなり、より正しい電圧値が得られることがわかります。

スポンサーリンク

アッテネータ-6dBでのanalogReadMilliVolts()

それでは、アッテネータを-6dBに設定した時に、analogReadMilliVolts()がどの程度正しいのか実験してみます。

プログラム

#define AD_PIN 34
#define N 2000
void setup() {
  Serial.begin(115200);
  delay(100);
  analogSetAttenuation(ADC_6db);  //ATT -6dB
  pinMode(AD_PIN, ANALOG);
}

void loop() {
  long adMillivoltTemp = 0;
  for ( int i = 0 ; i < N ; i++ )
  {
      adMillivoltTemp += (long)analogReadMilliVolts(AD_PIN);
  }
  float adMillivolt = (float)((double)adMillivoltTemp / (double)N); //mV Average
  Serial.printf("%d[mV]\n", (int)(adMillivolt+0.5) );
}

analogSetAttenuation()でアッテネータの設定を-6dBにします。

analogReadMilliVolts()で電圧値を2000回取得してその平均を求め、四捨五入した結果をシリアルモニターへ出力しています。

測定結果

上のグラフは、入力電圧を0Vから1.9Vまで変化させたときの、測定結果をプロットしたものです。0V付近と1.9V付近を除けば、完璧に直線になっています。

測定誤差

上のグラフは、入力電圧と測定誤差をプロットしたものです。入力電圧が150mV〜1850mVの範囲では、analogReadMilliVoltsの測定誤差は±7mVであることがわかりました。

スポンサーリンク

ESP32のADCのATTは-6dBがいいよ

analogReadMilliVolts()を使うことで、簡単に電圧値を取得することができることがわかりました。

さらに、アッテネータを-6dBに設定することで、AD変換の直線性が良くなり測定精度が向上します。

その場合に精度良く測定できる電圧範囲は、150mV〜1850mVでした。