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

Arduino UNO R4 の調査、ADCの入力特性を再調査

◆まえがき
前の記事に Arduino UNO R4 のアナログ入力特性 というのを書いて、UNO R4 のアナログ入力はゼロボルト付近から使えるので素晴らしいと褒めたばかりなのですが、その記事への居酒屋ガレージ日記(JH3DBO)さんからのコメント で「入力に直列に入れた抵抗の値を変えた時の挙動を調べておいた方が良い」とのアドバイスを頂きました。

確かにその通りなので実際に測定してみたところ、予想外の挙動が現れました。そんなことで、状況をこの記事で詳しく解説したいと思います。かなりの長文になりそうですが、Arduino UNO R4 で正確なアナログ電圧の測定をしたい場合は絶対に知っておいた方が良い内容だと思います。

◆UNO R4(RA4M1)のアナログ入力回路のデータシート
調べて行った順に、私の認識などを書いて行きたいと思います。まずは RA4M1 のデーターシートに記載されているADC入力の等価回路を確認しておきます。
ADC入力回路

Cs、Rsの値は下記の表で示されています。
ADC入力特性仕様


ADCのモードによって値は異なるようですが、低消費電力モードの通常精度チャンネルだと、Cs=9pF,  Rs=6.7kΩ となっています。と言うことは、時定数=60ns つまり 16.7MHz のローパスフィルタが入っていることになって、高周波では注意が必要であることが判ります。

この図は後で再度触れますが、実は大きな落とし穴がありました。

◆特性測定
次の図のような回路で測定しました。
・測定回路
UNO T4のアナログ入力のテスト回路
ボードから出ている3.3Vを1kΩから1MΩの抵抗を経由してA0ピンに入力し、信号源の抵抗の影響を調べました。もしA0ピンのリーク電流があれば、抵抗値に比例した値だけ測定される電圧が上昇/降下するはずなのでその量を測定しようという狙いです。なお、C3.3は0.1μFでノイズの影響を減らすために入れています。

・測定プログラム
1000回測定してその平均値を0.1秒間隔でシリアルに流すプログラムです。
 20240211_UnoR4AdcTest_2.ino (UTF-8 BOM付き)

・測定結果
AdcTestResult-2.jpg
表の中身は左から、信号源抵抗(外付けした抵抗)、ADCの値、VxはADCの値から換算した電圧(3.38V*ADC/1024)、等価入力抵抗はVxとR1の値から計算した値です。

等価入力抵抗の値で見ると割と高い値になっています。実は私はこの値を見てUNO R4のアナログポートの入力抵抗はそこそこ高い値になっていると間違った判断をしていました。ちなみにそのツイッター(X)への書き込み ←後で訂正入れときます

左の表(C3.3無し)で見ると0.92Vに向かって吸い込みの電流が流れている感じです。でもC3.3有り(右の表)だと挙動が全然変わっていて想定外の現象が起きている感じです。

分解能10nAのマルチメーターを持っているので、入力バイアス電流の直接測定を試みたのですが、値が安定せずダイナミックな変化がある感じでした。こうなるとオシロの出番です。

・オシロでA0ピンの電圧波形を観察
Rs=1MΩ、C3.3無しの状態で、まずは全体波形。
20240211R0025527.jpg
何と100ms間隔で電圧が下がっていました。電圧が下がっている間に1000回の analogRead() が実行されています。

測定していない期間のうねうねはAC100Vからの誘導。また、この間の電圧が3.3Vでは無く3.0Vになっているのはオシロのプローブの10MΩの影響です(3.3V x 10/11MΩ)。

・測定期間先頭部の拡大
20240211R0025528.jpg
階段状に電圧が下がってます。階段一つが analogRead の1回分で約20μsですが、徐々に電圧が下がっているのが注目点です。

・Rs=100kΩの波形(ACカップルで測定)
100kΩ波形拡大

100kΩにすると状況が判り易くなります。階段部は実は指数カーブで変化していて3.3Vまで上がっていました。(3.3Vx10/10.1MΩなのでほぼ3.3Vになります)よく見ると、A点(2.97V)から始まり、B点(3.08V)で不連続になっています。

測定結果の表で100kΩの時に観察された電圧は2.98Vだったので、A点付近の電圧がADCに測定されている感じです。(この瞬間の電圧がホールドキャパシタに転写されてADCされる?)

指数カーブの部分の時定数は大雑把には7μsというところでしょうか。入力等価回路のCsは9pFでこのコンデンサに直列に入る抵抗は100kΩ+Rsなので106.7kΩ。となると時定数は0.96μsとなって観察されたカーブと一致しません。ピンの入力容量は30pFくらいあるらしいのでその値で計算するともう少し測定結果に近付きますがそれでも完全には合いません。波形のA店からB点の変化はもう少し速そうなのでこの部分の変化なら106.7kΩと9pFの時定数で説明が付くのかも知れません。

以上の検討では指数カーブを構成する時定数がどこの値であるかは残念ながら特定出来ませんでした。但し、数値の変化から何が起こっているのか推定することは出来ます。それを回路図で表現したのが次項です。

◆現象の考察
前項までに観察された現象を説明できる等価回路を考えてみました。
ADC入力回路、動作解説用
Rsouceは信号源のインピーダンス。Cin, Rs, Cs はデーターシートに記載されている値の通りと考えます。大きく違うのがSW-2とプリチャージの電圧源の0.92Vです。

今回の観察結果から想定すると、下記の順で制御が進んでいると考えると辻褄が合いそうです。なお、これはあくまでも推定で。実際にはもっと複雑な内部操作が行われている可能性があります。
 1. analogReadの命令が実行されると、最初にSW-2がONになってCsを0.92Vにプリチャージ。
 2. すぐにSW-2をOFF
 3. SW-1をONにし、RsouceとRs経由でCsを充電。
 4. ADCで電圧測定
 5. SW-1をOFF

最初の手順の1項でCsのプリチャージが行われるため、その後の入力ピンは0.92Vに向かって引っ張られていると考えられます。それでもSW-1をONにする時間が充分に長ければCsは充分に充電されて入力電圧=ADC電圧となるはずですが、実行時間が長くなることを嫌ったのか、十分な待ち時間に設定されていないために(Rsouceの値によっては)まだ安定していない状態の電圧を読むことになってしまい、誤差が発生しているのではないかと想像します。

プリチャージの電圧の0.92Vは測定データーから推定したもので、チップの中にこの電圧源が存在するとは限りません。Csをディスチャージする仕掛けのクセと言うか、回路の都合でたまたまこういう値が見えているのに過ぎないかも知れません。

今回の測定は入力電圧3.3Vで行いましたが、もし0.92Vで測定を行っていたら、Csのコンデンサの電荷移動は無いはずです。つまりその条件では、上記の厄介な問題は発生しないので、極めて優秀なADコンバーターの入力回路という評価になったと思います。

そもそも測定毎にSW-2をONにして放電させる必要は無いと思います。そんなことをしなければ等価的な入力インピーダンスを充分高くすることが出来たはずです。なお、SW-2をONにしてチャージをリセットすれば、ピンを切り替えた後でも同じ状態で測定出来るというメリットはあるので一概に否定することは出来ませんが、それでも失うものが多すぎると思います。

ちなみに、UNO R3 ではピンを切り替えた場合、前のピンの情報(電圧)が残ってしまうので、ダミーリードを行って正しい電圧が得られるまで待つような操作を行います。これはCsを毎回リセットしていないからこういうことが起こる訳です。それでも入力インピーダンスが下がってしまうよりは全然マシです。

◆考察
Arduino UNO R4 のanalogRead()は等価的な入力インピーダンスが小さいため、信号源のインピーダンスは数kΩ以下で使用する必要があるようです。つまり、えらく使いづらいです。また、ADCが動作した時だけ入力インピーダンスが下がるので、接続した相手に大きな影響(電気的なノイズ)を与える可能性がある点も考慮しておいた方が良いです。

おそらくチップ自体はこのような現象を起こさない設定、つまりアナログ入力端子をハイインピーダンスの状態に保つような使い方が出来るのだと思います。でも 残念ながら、Arduino UNO R4 の analogRead 関数ではなぜか前記したような状態になっています。

◆まとめ
長文になってしまって読み難い記事になってしまいました。

はっきり言って、Arduino UNO R4 の analogRead の仕様は、入力インピーダンスが低くて使い難いです。また、測定が実行される時に入力インピーダンスが変わる(下がる)のも相手の回路に影響を与えてしまうので好ましくありません。CPU内蔵のオペアンプを使えば問題は解決出来ますが、あまりスマートな方法では無いと思います。

前の記事で書いたように、このADCはほとんどゼロボルトからきっちり動く優れ物だったのにこんなところでケチが付いてしまうのはもったいないです。ルネサスが付いていると思うのに、どうしてこんなダメな仕様に仕上がってしまったんでしょうね。もし可能なら analogRead の関数を改版して、この問題を直して欲しいと思います。

◆この記事を書くに当たって使用したバージョン等
Arduino IDE : Arduino IDE 2.2.1
Arduino UNO R4 Boards:1.0.5
ボード:UNO R4 MINIMA(互換品)
CPUマーキング:R7FA4M1AB3CFM 222AZ00
カレンダー
01 | 2024/02 | 03
- - - - 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 - -
プロフィール

ラジオペンチ

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

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