ESP32のアナログポートの特性調査ー予想外の挙動
◆まえがき
前回の記事に引き続きESP32のアナログポートの特性の話です。ESP32のアナログポートを使って電圧を測定する時に、入力端子にコンデンサ(0.1μF)を接続するとなぜか電圧が上がるという不思議な現象が発生しました。この記事ではその原因について調べて行きます。
・調査の様子

しかし最近こればっかりやっています。
・回路図

SW2を閉じてADCの入力に0.1μFのコンデンサを接続した状態です。
なお、以下にいろいろな問題について書いていますが、根本的にはR1の値が1MΩと大きな値になっているのことが全ての原因です。例えばR1が10kΩだったら無視出来る程度の誤差しか発生しません。ただ、そうは言ってもいつも信号源インピーダンス、つまりR1の値が小さいとは限らないので、一応頭に入れておく必要がある話だと思います。
測定結果を見ると
・V3が上昇している

V2に対してV3が上昇しています。普通ならコンデンサを入れるとノイズが減るけど平均値は変わらない、つまり電圧の変化は無いはずなので、これは変です。ちなみに前の記事のプログラムでは、データーのばらつきを減らすために1000回も測定してソフトで平均値を求めているのですが、そんなことしなくてもコンデンサで平均化しちゃえば良いのでは、という狙いでコンデンサを入れてみました。
とにかくこういう場合は電圧がどうなっているのかオシロで見るに限ります。
◆オシロで見ると、

これはコンデンサ(C1, 0.1μF)を接続していない状態、つまり、前の記事のFig-2の状態でV2を測定しています。
測定する期間だけ電圧が下がっていて、その後は元に戻っています。電圧が下がるのはアナログポートの入力抵抗(Rx)が並列に接続されるためですが、測定が終わるとこの抵抗、というかADCの回路全体が切り離されているようです。回路図で書くと、
・測定回路が切り離される

SW4があって、測定する時だけ接続されるという仕組みになっているようです。
波形写真のように、ADCの動作時間は11msで、その後は300msの待機するという動作の繰り返しになっています。C1があると待機状態の時間が大半なので結局は電圧が高くなる、ということだったようです。ちなみにオシロは上の回路図のV4の位置を見ています。
◆GPIO36の挙動が変
これでV3が上昇する理由が判ったのですが、GPIO36(VP)の場合はそれだけでは説明が付かない現象が発生していました。
テストに使ったプログラムは以下の通りで、単にADCで電圧を測るだけで何もしないプログラムになっています。なお、シリアルに出力したりするとそこで消費される時間が不明確になるので、あえて避けています。
・GPIO36ピンに発生するスパイク

観察場所は上の回路図と同じV4の位置です。入力電圧は0.8Vなのですが、周期的に0.56V付近まで一気に電圧が下がり、そこから指数関数で電圧が回復するという動作を繰り返していました。電圧が下がったタイミングでADCが行われていて、analogRead() の戻り値もその電圧を反映した値が帰ってきていました。なお、周期を1.2ms以下にするとこのような現象は発生しなくなりました。これがどういうメカニズムで切り替わっているのかは不明です。
ちなみに、この状態でコンデンサ(C1)を接続すると(平均)電圧が急増し analogRead の戻り値は0.8Vまで上昇するので、驚くことになります。
・波形拡大

時定数は約80μs程度です。ということは、等価回路で書くと以下の回路、つまりSW5でR36, C36の回路を断続している感じになっているのだと思います。これ以外に、C36に溜まった電荷を抜くためにディスチャージトランジスタあるいは放電抵抗が入っているのだと思います。あくまでも挙動から推定した回路なので実際には違うかも知れません。
・等価回路

SW4はこの記事の最初の方に書いた、ADCを実行する時にONになるスイッチです。
SW5は大きなスパイクを発生させるスイッチで、これが動作する条件が完全に解明できていないのですが、測定間隔が1.3ms以上空くと、次の測定の時にONになる感じで動くようです。たぶんこの回路はGPIO36とGPIO39だけに存在していると思います。
・他のピン(GPIO32)

他のピンでも同様な問題が起きていないか調べましたが、僅かな波形の乱れしかありませんでした。たぶんSW4の先に数ピコのコンデンサが存在する程度だと思います。
◆まとめ
1. ADCの入力抵抗、というかたぶんADコンバーター全体が analogRead の実行時にだけ接続されるようになっているようです。そのために、信号源のインピーダンスが高い場合などではコンデンサを接続すると電圧が変わってくる場合があります。
2. GPIO36(たぶんGPIO39も)は特殊な動きをするので注意が必要で、特に理由が無ければ使わない方が良いと思います。ちなみにこのピンは普通に使えるADCの先頭ピン(ADC1_CH0)なので、アナログ電圧測定の事例によく出て来ます。電池の電圧測定程度なら問題は起きませんが、信号のインピーダンスが上がってくると測定精度が悪くなるので注意が必要です。
3. 2項のような事情から、ESP32-DEVKITの基板のシルクにはGPIO36とGPIO39ではなく、VP, VN と印刷されているような気がします。
参考:ADC36(SENSOR_VP)はモジュール基板上で270pFのコンデンサを通してADC37(SENSOR_CAPP)と接続されています。たぶんこのあたりが変な挙動が起こる原因の一つだと思います。

(ESP32のデーターシートから抜粋)
前回の記事に引き続きESP32のアナログポートの特性の話です。ESP32のアナログポートを使って電圧を測定する時に、入力端子にコンデンサ(0.1μF)を接続するとなぜか電圧が上がるという不思議な現象が発生しました。この記事ではその原因について調べて行きます。
・調査の様子

しかし最近こればっかりやっています。
・回路図

SW2を閉じてADCの入力に0.1μFのコンデンサを接続した状態です。
なお、以下にいろいろな問題について書いていますが、根本的にはR1の値が1MΩと大きな値になっているのことが全ての原因です。例えばR1が10kΩだったら無視出来る程度の誤差しか発生しません。ただ、そうは言ってもいつも信号源インピーダンス、つまりR1の値が小さいとは限らないので、一応頭に入れておく必要がある話だと思います。
測定結果を見ると
・V3が上昇している

V2に対してV3が上昇しています。普通ならコンデンサを入れるとノイズが減るけど平均値は変わらない、つまり電圧の変化は無いはずなので、これは変です。ちなみに前の記事のプログラムでは、データーのばらつきを減らすために1000回も測定してソフトで平均値を求めているのですが、そんなことしなくてもコンデンサで平均化しちゃえば良いのでは、という狙いでコンデンサを入れてみました。
とにかくこういう場合は電圧がどうなっているのかオシロで見るに限ります。
◆オシロで見ると、

これはコンデンサ(C1, 0.1μF)を接続していない状態、つまり、前の記事のFig-2の状態でV2を測定しています。
測定する期間だけ電圧が下がっていて、その後は元に戻っています。電圧が下がるのはアナログポートの入力抵抗(Rx)が並列に接続されるためですが、測定が終わるとこの抵抗、というかADCの回路全体が切り離されているようです。回路図で書くと、
・測定回路が切り離される

SW4があって、測定する時だけ接続されるという仕組みになっているようです。
波形写真のように、ADCの動作時間は11msで、その後は300msの待機するという動作の繰り返しになっています。C1があると待機状態の時間が大半なので結局は電圧が高くなる、ということだったようです。ちなみにオシロは上の回路図のV4の位置を見ています。
◆GPIO36の挙動が変
これでV3が上昇する理由が判ったのですが、GPIO36(VP)の場合はそれだけでは説明が付かない現象が発生していました。
テストに使ったプログラムは以下の通りで、単にADCで電圧を測るだけで何もしないプログラムになっています。なお、シリアルに出力したりするとそこで消費される時間が不明確になるので、あえて避けています。
// ESP32 アナログ入力特性測定プログラムすごく当たり前のプログラムなのですが、これを実行すると、
#define TestPin 36 // 測定するピンを指定
void setup() {
analogSetAttenuation(ADC_2_5db); // コメントアウトで-11dB(デフォルト)
}
void loop() {
int d = analogRead(TestPin);
delay(2); // 1msにするとグリッジが出ない
}
・GPIO36ピンに発生するスパイク

観察場所は上の回路図と同じV4の位置です。入力電圧は0.8Vなのですが、周期的に0.56V付近まで一気に電圧が下がり、そこから指数関数で電圧が回復するという動作を繰り返していました。電圧が下がったタイミングでADCが行われていて、analogRead() の戻り値もその電圧を反映した値が帰ってきていました。なお、周期を1.2ms以下にするとこのような現象は発生しなくなりました。これがどういうメカニズムで切り替わっているのかは不明です。
ちなみに、この状態でコンデンサ(C1)を接続すると(平均)電圧が急増し analogRead の戻り値は0.8Vまで上昇するので、驚くことになります。
・波形拡大

時定数は約80μs程度です。ということは、等価回路で書くと以下の回路、つまりSW5でR36, C36の回路を断続している感じになっているのだと思います。これ以外に、C36に溜まった電荷を抜くためにディスチャージトランジスタあるいは放電抵抗が入っているのだと思います。あくまでも挙動から推定した回路なので実際には違うかも知れません。
・等価回路

SW4はこの記事の最初の方に書いた、ADCを実行する時にONになるスイッチです。
SW5は大きなスパイクを発生させるスイッチで、これが動作する条件が完全に解明できていないのですが、測定間隔が1.3ms以上空くと、次の測定の時にONになる感じで動くようです。たぶんこの回路はGPIO36とGPIO39だけに存在していると思います。
・他のピン(GPIO32)

他のピンでも同様な問題が起きていないか調べましたが、僅かな波形の乱れしかありませんでした。たぶんSW4の先に数ピコのコンデンサが存在する程度だと思います。
◆まとめ
1. ADCの入力抵抗、というかたぶんADコンバーター全体が analogRead の実行時にだけ接続されるようになっているようです。そのために、信号源のインピーダンスが高い場合などではコンデンサを接続すると電圧が変わってくる場合があります。
2. GPIO36(たぶんGPIO39も)は特殊な動きをするので注意が必要で、特に理由が無ければ使わない方が良いと思います。ちなみにこのピンは普通に使えるADCの先頭ピン(ADC1_CH0)なので、アナログ電圧測定の事例によく出て来ます。電池の電圧測定程度なら問題は起きませんが、信号のインピーダンスが上がってくると測定精度が悪くなるので注意が必要です。
3. 2項のような事情から、ESP32-DEVKITの基板のシルクにはGPIO36とGPIO39ではなく、VP, VN と印刷されているような気がします。
参考:ADC36(SENSOR_VP)はモジュール基板上で270pFのコンデンサを通してADC37(SENSOR_CAPP)と接続されています。たぶんこのあたりが変な挙動が起こる原因の一つだと思います。

(ESP32のデーターシートから抜粋)
- 関連記事
-
- ESP32のオープンドレイン出力の特性調査
- ESP32のDAコンバーターの特性調査
- ESP32のアナログポートの特性調査ー予想外の挙動
- ESP32のアナログポートの特性調査-入力抵抗
- ESP32のアナログポートの特性調査-入力感度特性