PR

ArduinoのADコンバータ、1023?1024?

以前書いたこちらの記事を読み直していて「あれ?」と思った。

というのは、サーミスタの電圧を求める式をこうしていた。

\[ Vth=\frac{Vcc}{1023} \times X \]

「あれ?1023?1024じゃない?」と。

そこで、マニュアル(ATmega328Pのデータシート)を確認(215ページ)。

23.7 ADC Conversion Result
After the conversion is complete (ADIF is high), the conversion result can be found in the ADC result registers (ADCL,
ADCH).
For single ended conversion, the result is:
\[ ADC = \frac{V_{IN} \times 1024}{V_{REF}} \]
where VIN is the voltage on the selected input pin and VREF the selected voltage reference (see Table 23-3 on page 217 and Table 23-4 on page 218). 0x000 represents analog ground, and 0x3FF represents the selected reference voltage minus one LSB.

(上の引用文の中にもあるとおり)ADCはADコンバータの出力値、VINはADコンバータの端子の入力電圧、VREFはADコンバータの参照電圧。ここの式を変形してADCからVINを求めるにはこう。

\[ V_{IN} = \frac{ADC \times V_{REF}}{1024} \]

やはり、ADコンバータからのデータに参照電圧を掛けたものを1024で割ったものが正しい。

また、上の引用文の最後のところ、こうある。

0x000 represents analog ground, 0x3FF represents the selected reference voltage minus one LSB.

0x3FF(つまり、ADCの最大値)は参照電圧から1 LSB減じたものを表す、と。1 LSB分の電圧は参照電圧(VREF)の1/1024なので、これを使ってVINを求める式を作るとこうなる。

\[
V_{IN}=\frac{ADC \times (V_{REF} – \frac{V_{REF}}{1024})}{1023} \\
\]

これをどんどん変形していくと、

\[
1023 \times V_{IN} = ADC \times V_{REF} – \frac{ADC \times V_{REF}}{1024} \\
\]

\[
1023 \times V_{IN} = \frac{1024 \times ADC \times V_{REF} – ADC \times V_{REF}}{1024} \\
\]

\[
1023 \times V_{IN} = \frac{1023 \times ADC \times V_{REF}}{1024} \\
\]

\[
V_{IN} = \frac{ADC \times V_{REF}}{1024}
\]

と、先程の式と同じになる。

先の記事で1023としてしまったのは、多分、どこかのサンプルプログラムを見て、それをそのまま使ったのだろう。1023にしているものもたくさん見つかるので。また、1023が間違いだと指摘している記事も見つけた。

ということで、先の記事は1024に修正した。

それにしても、いらすとや、なんでもあるなぁ。改めて驚いた。

コメント

  1. 「1/1023 vs 1/1024」、注目いただき、どうもです。
    調べれば・・・あちこちで「1/1023」が出現。
    新しい所では、トラ技2021年9月号の別冊付録にも。
    http://igarage.cocolog-nifty.com/blog/2021/08/post-cc3d63.ht…

    • jh4vaj より:

      最新号ですよね。
      2進数の最大値を使いたくなる気持ちもわからなくもないですけどね。