google-site-verification: google3bd66dd162ef54c7.html
fc2ブログ

ESP32のアナログポートの特性調査-入力感度特性

◆まえがき
Arduino UNO (NANO) で動かしていたミニオシロをESP32に移植する作業を行っているのですが、アナログポートの挙動が少し変な気がするので詳しく調べてみました。

今のところ気になっているのは、GPIO36(VP)ピンの挙動とAD変換の直線性の2点です。この記事では一番基本になる、AD変換特性についてまとめています。

◆詳しい話の前に、
ESP32のアナログポートにはプログラムで設定が可能なアッテネーターが付いていますが、どういう方式のものが回路のどの位置に入っているのか、良く判らないです。また、ADコンバータの基準電圧がどうなっているか、データーシートを読んでも良く判りません。本来のデーターシートまでたどり着けていないのかも知れません。ひょっとしたら中国語版だけが存在しているものがある?

そんなことで、ネットには「ADCのフルスケールは電源電圧の3.3V」などと書かれちゃったりしますが、いくらなんでもそれは無いだろうと思います。

それと、ADコンバーターのリニアリティが悪いということもあちこちに書かれていますが、ゲインとオフセットをごちゃまぜにして議論されていることが多くて問題点が明確になっていない感じです。

ともかく、ネットだけでは良く判らない事が多いので、自分で測定してみることにしました。

◆測定
簡単な回路とソフトを作って、ADコンバーターというかanalogRead() から帰ってくる値を確認しました。

・回路
測定回路
VINにはUSBの5Vが出ているので、これをVRで分圧して被測定ポート(この図ではD34)に加えました。3.3V以上の電圧を加えることが出来るので、保護抵抗くらい入れておいた方が良いのですが、面倒なので省略しています。

・プログラム
// ESP32 アナログ入力特性測定プログラム

#define TestPin 34 // 測定するピンを指定

void setup() {
Serial.begin(115200);
analogSetAttenuation(ADC_0db); // アッテネーターを設定
// analogSetAttenuation(ADC_2_5db);
// analogSetAttenuation(ADC_6db);
// analogSetAttenuation(ADC_11db);
// pinMode(TestPin, ANALOG);
}

void loop() {
long d = 0;
for (int i = 0; i < 1000; i++) { // 1000回測定して
d += analogRead(TestPin);
}
Serial.println(d / 1000); // 平均値をシリアルに出力
delay(200);
}
測定したいアッテネーターのコメントアウトを外して選択します。
値がばらつくので、1000回測定した結果を平均しています。(1000回足して1000で割っているので完全な切り捨てになっています。四捨五入にするなら500を足してから1000で割る)

・測定の様子
ESP32のアナログポートの特性測定
電圧はテスターで測定しますが、アッテネーターが0dBと-2.5dBは2Vレンジ、-6dBと-11dBは20Vレンジで測定しました。オートレンジで測定すると勝手にレンジの切り替えが行われてしまうので、直線性を確認したい場合などは好ましくありません。(オートレンジのテスターを持っていない負け惜しみではあります)

◆測定結果
入力電圧に対するAnalogRead() の値のグラフです。パラメーターはアッテネーターの設定状態です。

・測定結果全体
ESP32のAnalogRead特性
入力電圧に対してanalogRead() が返す値のグラフです。12ビット分解能なので縦軸はゼロから4095の範囲で変化します。当然ですが、アッテネーターの設定値に応じて傾きが変わっています。

アッテネーターを11dBにした場合、2.5Vあたりにはっきりとした変曲点がありますが、こんなに傾き(感度)が変わるようでは安心して使えないです。この特性が、ネットのあちこちに書かれているリニアリティが悪いという評判に繋がっているのでしょう。アッテネータを11dBで使う場合は、入力電圧は2.5V以下で使った方が良さそうです。

アッテネーターを 0dB, -2.5dB, -6dBで使う場合は極端に直線性が悪いということは無さそうです。但し、オフセットがかなり目立ちますが、その点については後で触れます。

アッテネーターが0dBの状態を見ると、フルスケールは約1.1Vになっています。この値がADCのVrefの値なのかも知れません。なお、CMOSは正確な基準電圧を作るのが難しいらしいので、この1.1Vという値には個体差があると思います。

・ゼロボルト付近の拡大
ESP32のAnalogRead特性(原点付近)
オフセットの発生状況を見るために原点付近を拡大したグラフです。

アッテネーターがー11dBではオフセットというか不感帯が 130mV、他の場合でもオフセットが80mVもあってこれはちょっと残念な結果です。フルスケール1Vで不感帯が80mVということは、ダイナミックレンジは 1/0.08 =12.5倍しかない訳で、ADCの12ビット分解能(4096ステップ)が泣きます。

アッテネーターを 0dB、 -2.5dB, -6dB と変えてもオフセットの量は変わらないので、その発生原因はADCより手前の回路にある気がします。ちなみに、ADCのオフセットが原因なら、アッテネーター値に比例してオフセット量が変化すると思います。

◆まとめ
アッテネーターが -11dbの状態がESP32のデフォルトで、何も指定しないとこの値が使用されます。その時のADCの直線性がこんなに悪いのはかなり残念な結果です。これでは測定と名が付くアプリには使えず、個人的には目安くらいの用途にしか使えないと思います。測定に使うなら、-11dB以外のレンジを使った方が良いでしょう。

約80mVのオフセット(-11dBレンジは130mV)があり、これ以下の電圧では測定結果はゼロになるので注意が必要です。私のオシロではレンジの切り替えをソフトでも行っています。例えばハードのフルスケールが1Vの状態で、下側の10% つまり0.1Vまでの範囲を使うことで縦軸倍率を10倍に拡大しています。ここに80mVもの不感帯があったのではこの考え方は成立しなくなる訳で、困ったものです。

ともかくこの部品の挙動が一つ把握出来ました。こういう特性であることを理解したうえで使っていく、あるいは放棄するしかないんでしょうね。ADCの話はもう一つ記事を書く予定です。

前の記事へ頂いたコメントによるとESP32のADCにはキャリブレーション機能があるらしいです。今回測定を行った物のキャリブレーションがどうなっているのかは不明です。
関連記事

コメントの投稿

管理者にだけ表示を許可する

なるほど

ESP32といえば、M5StackとかM5StickCに載っている
マイコンですよね。
適当に見つけたデータシートを見ると。。。
A/Dの非直線性誤差、DNLが±7LSB、INLが±12LSBと
なってました。

Arduino UNOのATmega328PのA/Dだと、(10bitですが)
絶対精度が2LSB、DNLが0.25LSB、INLが0.5LSB。
   ※なんか桁が違う
誰でも安心して誤差なく使える値です。
ここらあたりから違うんでしょうね。

atten=3が-11dBか

そのデータシートにはこんな文が。
When atten=3 and the measurement result is above 3000 (voltage at approx. 2450 mV), the ADC accuracy
will be worse than described in the table above.

簡単に・・・
「atten=3の時、2450mVを越えると精度が悪くなる」っと。

re:atten=3が-11dBか

ESP32のデーターシートのDNL,INLの値はずいぶんと大きいなーと思っていたのですが、ATmega328Pと比べたことがありませんでした。
こうして比べると、ビット数の違いを考慮してもかなり大きいですね。

データーシートのリンクがすぐに出てこないのですが、ADCのキャリブレーション方法について書いてある資料には、誤差が少ない範囲として、
Atten0 (0dB)は、  100-950mV
Atten1 (-2.5dB)は、100-1250mV
Atten2 (-6dB)は、  150-1750mV
Atten3 (-11dB)は、 150-2450mV
となっていて、下の方もダメと書いてありましたorz

ADCの測定値について

本掲載を拝読させていただきました。
実際に自分でも測定してみたところ、入力のポート毎に特性が違いました。また、WifiをOnさせると使えないADCポートもありましたし、Wifi On/OffでACDの特性も変わっていました。ノイズのせいなのか設定のせいなのか不明です。

一点、掲載内容の中で、-11dBの設定時に非線形になるとありますが、これは、入力する電圧のインピーダンスに影響されていると思われます。外部から出力インピーダンス1kΩ以下で電圧を入れるともっと線形に近いです。
本掲載の回路ですと、おそらく半固定抵抗で電圧を変化させているため電源の出力インピーダンスが電圧が低いほど高くなります。
-11dB入力の時、おそらくADCの入力インピーダンスが低くなると思われ、これが電源出力インピーダンスで入力電圧が下がってしまうのではないでしょうか。同じ理由で、0V付近で120mVを超えないとADCの数値に現れないのではないのでしょうか。私が見る限りここまで高い電圧まで数字が出ないケースはありませんでした。

re:ADCの測定値について

中納言さん、情報ありがとうございます。

ESP32の個体によって特性が違うのかも知れませんね。というのは、

信号源のインピーダンスを気にしておられますが、この記事の測定ではIOピンの電圧を回路図に示すように直接測定しています。これなら信号源のインピーダンスの影響は無いと思うのですが、どうでしょう。

あと、
>本掲載の回路ですと、おそらく半固定抵抗で電圧を変化させているため電源の出力インピーダンスが電圧が低いほど高くなります。
と書かれていますが、この回路ではボリュームが中間点の位置にある時が出力インピーダンスが最大で、ボリュームの位置を上下どちらに動かしても出力インピーダンスは下がると思います。(テブナンの定理で考えると判り易いと思います)
カレンダー
02 | 2024/03 | 04
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。
記事の内容のご利用は読者の自己責任でお願いします。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード