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つの設定ができます。
-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でした。
コメント