Arduinoのボードのアナログ入力で、
- analogReadで取得した値の誤差が大きい
- 大きい
- 小さい
- 他のアナログ入力チャンネルに影響を受けている感じがする
- 連続して何度か測定すると、一定の値に落ち着く
ような現象が起こる場合、出力インピーダンスの大きい信号源を接続しているためと思われる。
A/D変換では、こちらにあるように、A/D回路にあるサンプルホールドという回路部分のコンデンサを充電してから、その電圧を比較器にて比較しデジタル値に変換する。このコンデンサは小さい容量ながら、サンプルホールド回路内の抵抗と、被測定物のもつ出力インピーダンスがそれぞれ直列に接続されることでRC平滑回路が形成され、充電にはある程度時間がかかる。
なので、通常は信号源インピーダンスは、A/D変換回路の仕様書などで推奨値が記されていて、それ以上のものを接続したいときは、バッファアンプを介してつないだりする必要がある。
対策
とはいうものの、バッファアンプがすぐに用意できなかったり、その場しのぎ的にとりあえず測定はしたいという状況もある。そういった場合に有効なのは、
analogRead(ch); // 捨てる analogRead(ch); // 捨てる int x = analogRead(ch); // 採用
という感じで、同じチャンネルを何回か連続して読み、最後の値を使用するという手だ。
analogRead関数が呼ばれた際には、サンプルホールド回路が接続されコンデンサの充電が始まるが、十分充電される前にコンデンサが測定対象から切り離されて最初のA/D変換が始まってしまう。その後2回目、3回目と接続されるうちにコンデンサの充電が完了して正しい値が得られるようになるということを利用している。
なので、測定対象の出力インピーダンスに応じて必要な回数が変わってくるが、私がArduino Unoで試したところ、約300kΩ程度のときに、3回でほぼ正しい値が得られた。
また、注意が必要なのは、他のチャンネルとの電圧差によっても必要な回数が変わること。なぜなら、サンプルホールド回路のコンデンサは、前回の変換時の電圧を保持しているので、前回と今回との電圧差が大きければ大きいほど、充電(放電)にかかる時間が長くなるからだ。