ESP32のADC特性測定

概要

ESP32と電源の自動計測環境とが構築できたので、ADCの特性を計測してみたいと思います。

手元環境で計測してみたので、個体差がありますし電源自体もキャリブレーションされているものではありませんのでご注意ください。

ESP32のADCについて

基準電圧

マイコンのADCは基準となる電圧に対して比べることで電圧を測定しています。基準となる電圧はマイコンによって変わっており、電源電圧を採用している場合にはADCの最大値は電源電圧となります。そのため5Vのマイコンに4.8Vを入力して動かした場合には、4.8Vが最大値になってしまいます。入力電圧が変わると、測定値も変わるので少し処理しにくいです。

ESP32の場合には内部で電源電圧から1.1Vの基準電圧を作成し、その電圧を比べることで電圧測定をおこなっています。ただし、そのままだと1.1Vまでの電圧しか測定できないので、測定する電圧を減衰器やアッテネーターという装置で小さくしてから測定しています。

減衰減衰率減衰比
ADC_0db10.042361111
ADC_2_5db0.749894209約1 : 1.34
ADC_6db0.501187234約1 : 2
ADC_11db0.281838293約1 : 3.6

ESP32には3つの減衰器が内蔵されており、減衰器なしと合わせて4種類の測定レンジがあります。通常は11db減衰させる1:3.6の減衰器を利用します。これを利用することで3.6Vの電圧が1Vまで小さくすることができます。

キャリブレーション

ESP32は1.1Vの基準電圧を内蔵していますが、個体差があります。

Analog to Digital Converter (ADC) Calibration Driver - ESP32 - — ESP-IDF Programming Guide latest documentation

上記によると1000 mV ~ 1200 mVの範囲にあり、現在出荷されているESP32は出荷時に基準電圧を測定して、内部に保存してくれています。実験に利用したものは1150mVぐらいでしたので、若干高めの基準電圧でしたので、補正をしないと実際より低く電圧が測定されているはずです。

ADC VRef calibration: 1149 mV
ADC readings stored in efuse BLK3:
    ADC1 Low reading  (150 mV): 306
    ADC1 High reading (850 mV): 3153
    ADC2 Low reading  (150 mV): 389
    ADC2 High reading (850 mV): 3206

こちらは私が利用したESP32のデータではないですが、上記のように150mVと850mVの電圧を測定しているチップもあるようです。

Analog to Digital Converter (ADC) - ESP32 - — ESP-IDF Programming Guide v4.4.6 documentation

最新版のドキュメントではなくなっていましたが、上記にて解説されていました。基準電圧と150mVと850mVの電圧を利用して補正することで精度をたかめる仕組みがESP32にはあるようでした。

https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf

ただし、上記をみてみると補正後の電圧で計測可能な範囲が上記となっています。なんと3.3Vまで計測することができません。この数値はどんどん保守的になってきていて減っています。昔はもう少し範囲が広かったのですが、たぶん精度が悪いじゃないかとクレームが入って保守的な変更したのだと思われます。

このレンジを超えるとかなり精度が悪化する可能性があるので注意してください。

実験装置

ESP32

上記のスケッチを動かしているDevKitになります。無印ESP32なのであまり精度は高くないように思えます。

電源

上記の電源をPythonで自動制御しながら計測しました。

実験手順

  1. ESP32のアッテネータを設定
  2. 電源を0ボルトからADC値が4095を超える値まで上げていく
  3. ESP32のADC値を補正前のものと、補正後のものを両方取得する

上記をWindows上のPythonで自動計測しました。

実験結果① 50mV単位での計測

11db減衰(3.3V?までの特性)

デフォルトの状態で測定したものになります。50mV単位で計測しています。青が外部電源電圧で、オレンジが補正された測定電圧、灰色が測定したADCの値を電圧相当に変換したものになります。

まずオレンジの補正後のものは比較的きれいなデータが取れていますが、電圧が200mV以下と3200mV以上のデータは信用できそうにありません。ADCのデータをみると0VのときにADCは0のままですが、補正後の数値は107mVでした。オフセットとしてこれぐらいの電圧が補正されているのかもしれません。そして、3200mVぐらいで3139mVぐらいの最高値にはりついています。

灰色のデータをみると、200mV弱までは電圧を測定できておらず、2800mVぐらいまでは線形で増加していますが、それ以上のところで急激にADC値が上昇しています。この辺の動きがあまり好ましくなく、ESP32のADC性能はわるいとよく言われています。

補正前と補正後の差分だけを比較したグラフです。2.5Vぐらいまではオフセットの差ですが、それ以上は急激に差がでています。

6db減衰(2.0V?までの特性)

6db減衰に変更したデータです。オレンジの線はさきほどと同じような動きですが、灰色のADC値はほぼ線形になってきています。つまり11dbの減衰器の特性がどうやらよくなさそうですね。

2.5db減衰(1.3V?までの特性)

こちらもほぼ傾向としてはかわりません。

減衰器なし(1.0V?までの特性)

こちらも同じです。

実験結果② 1mV単位での計測

11db減衰のデフォルト値で、1mV単位で計測をしてみました。こちらのデータはかなりノイズが入っています。

0V周辺です。ADCは150mVぐらいまではあまり反応していないと思われます。オフセットが142mVありましたのでそれ前後まではおそらく測定できない低電圧になります。

高電圧帯です。3179mVぐらいでADCの値が最高になっていました。

疑問点

ESP32のADCは最大値が4095です。そのときの電圧を3.3Vとして各種計算をよくしていたと思います。そして減衰器を使ったときに最大電圧がよくわかりません。

減衰減衰後0.9V減衰後0.93V減衰後1V減衰後1.1V
0db10.9000.9301.0001.100
2.5db0.7498941.2001.2401.3341.467
6db0.5011871.7961.8561.9952.195
11db0.2818383.1933.3003.5483.903

資料がないので計算をしたのですが、11dbの減衰器を利用すると3.3Vが0.93Vになります。これはESP32で計測できる電圧が3.3Vが上限の4095になると想定した場合の逆算です。

しかしながらおそらくこの値ではないと思います。減衰後の0.93VがADC値4095だとすると、減衰器なしの場合には0.93Vまでしか計測できません。キャリブレーション後に950mVまで計測できると書いてありますので、おそらくは減衰後に1Vか1.1Vの間ぐらいがADCの上限値になると思いますが決定的な資料は見つけることができませんでした。

ただ、減衰後に1Vだとすると11db減衰の場合には3.5Vぐらいまで反応することになりますが、今回のチップだと3.2Vぐらいで上限値になっていました。基準電圧の1.1V上限だけれど、減衰値はぴったり上記の値ではなく、少し丸められている数字な可能性があります。

そして基本的には補正後のanalogReadMilliVolts()関数を利用し、補正前の生ADC値を取得するanalogRead()は利用しないほうが無難です。とはいってもanalogReadMilliVolts()は0Vにならない可能性があるのでちょっと使い分けが微妙な気もします。。。

まとめ

あくまで古いDevKitを利用したデータですので個体差がありますし、電源電圧自体もずれている可能性があります。また、2点計測がされている新しめのチップだともう少し精度が高いかもしれません。

自動計測でこんなことができるよという参考程度にしてください。

コメント