動作
analogRead関数の分解能(ビット数)を設定します。
「分解能(ビット数)」とは、analogRead関数が読み取る値の細かさです。
analogRead関数はデフォルトで10ビット(0〜1023の1024段階)の分解能です。これはAVRマイコン搭載ボード(Arduino Uno R3やArduino Nanoなど)との互換性のためです(一番低い性能のボードに合わせています)。
Arduino Uno R4やArduino Zero、Raspberry Pi Picoなどのボードでは、ハードウェア(ADCモジュール)が10ビットより高い分解能に対応しています。ここで説明するanalogReadResolution関数を使用すると、これらのボードのハードウェア性能をフルに活用できます。
例えば、5V動作のArduino Uno R4では、デフォルトの10ビットでは0Vのとき「0」、5Vのとき「1023」という数値で読み取ります。このとき1ステップの電圧は約4.89mV(5V÷1023)です。
analogReadResolution関数で12ビットに変更すると、0Vのとき「0」、5Vのとき「4095」という数値で読み取るようになり、1ステップの電圧は約1.22mV(5V÷4095)になります。同じ電圧範囲を、より細かい数値で読み取ることができます。

analogReadResolution関数で分解能を高くしても、実際にはその精度で読み取れるとは限りません。
例えばArduino Uno R4の最大分解能は14ビットですが、analogReadResolution関数で16ビットに設定すると、analogRead関数の読み取り範囲は0〜65535(16ビット)になるものの、実際の精度は14ビットのままです。具体的には0〜65535(16ビット)の範囲を16386段階(14ビット)で読み取っています。詳しくは補足セクションをご参照ください。
また、Arduino Uno R3などのAVRマイコン搭載ボードでは、この関数自体が使用できません(コンパイルエラーになります)。具体的には「補足」セクションの対応表をご参照ください。
analogReadResolution関数はanalogRead関数の動作にのみ影響します。analogWrite関数の分解能を変更する場合は、analogWriteResolution関数を使用します。
書式
analogReadResolution(bits);| 引数 | bits | 分解能をビット数で指定します。1〜32の整数値を指定します。 ※Arduinoボードがサポートしている分解能より高い分解能を指定できますが、その場合analogRead関数の戻り値はそのボードの最高分解能の精度になります。またボードごとに制約などもあります。詳しくは補足セクションを参照ください。 |
| 戻り値 | なし | |
主な分解能の読み取り値の範囲は次のようになります。
| ビット数 | 読み取り範囲 |
|---|---|
| 8 | 0 〜 255 |
| 10 | 0 〜 1023 |
| 12 | 0 〜 4095 |
| 14 | 0 〜 16383 |
| 16 | 0 〜 65535 |
主な用途
- 10ビットより高い分解能のADCを搭載したボード(Arduino Uno R4など)の性能をフルに活用して、電圧を細かく読み取りたい場合
analogWrite関数と分解能を揃えて、読み取り値をそのまま出力に渡したい場合- 逆に分解能を下げて、値を一定範囲内(0〜255 など)に変更したい場合
使用例
次のコードにより、analogRead関数で読み取る値の分解能を変更することができます。
analogReadResolution(10); // 10ビット(0〜1023)に設定(デフォルト)
analogReadResolution(8); // 8ビット(0〜255)に設定(デフォルトより低く設定)
analogReadResolution(14); // 14ビット(0〜16383)に設定(デフォルトより高く設定)サンプルスケッチ
analogReadResolution関数は一部のボードでは動作しませんので、サンプルスケッチではESP32を使用しています。
33番ピンに接続したボリューム(可変抵抗)の電圧を、2ビットと8ビットの両方の分解能で読み取り、シリアルモニタで比較するスケッチ例です(分解能は違いをわかりやすくするために極端な例にしていますので実用性は微妙ですが…)。同じ電圧でも分解能によって読み取り値の細かさが変わることを確認できます。
シミュレーターの動作を開始すると右下にシリアルモニタが表示されます。ボリュームのつまみを動かすとanalogRead関数で読み取った値が変化します。少しずつ動かしたとき、2ビットと8ビットでは細かさに違いがあることがわかります。
ボタンをクリックするとシミュレーターが動作します。スケッチを変更することもできます。変更した場合、シミュレーションを一度
ボタンをクリックして停止してから再度シミュレーターを開始してください。
トラブルシューティング
コンパイルエラーになる
Arduino Uno R3、Arduino Nano、Arduino MegaなどのAVRマイコン搭載ボードでは、analogReadResolution関数が実装されていないため、コンパイルすると「’analogReadResolution’ was not declared in this scope」というエラーになります。
これらのボードのADコンバーターモジュールは10ビット固定のため、分解能の変更はできません。
これらのボードでどうしても高い分解能が欲しい場合は、外付けのADコンバーターIC(MCP3208など)を使用します(別途対応ボードを用意するよりはコスト削減できます)。
分解能を上げたのに読み取りが細かくならない
分解能をハードウェアの上限より高く設定した場合、超えた分の下位ビットは0で埋められるため、見かけの数値は大きくなりますが、実際の読み取りの細かさは変わりません。
例えば、ADコンバーターモジュールの分解能が12ビットのボードで16ビットに設定すると、読み取り値は16刻み(下位4ビットが常に0)で変化します。
ボードごとのハードウェア分解能は「補足」セクションの対応表で確認してください。
分解能を変更したら電圧の換算値がおかしくなった
読み取り値から電圧に換算する計算式は、分解能に合わせて最大値を変更する必要があります。
分解能をデフォルトの10ビットから14ビットに変更したにもかかわらず1023.0で割ったままにすると、電圧が実際の16倍の値になってしまいます。
14ビットに変更した場合、電圧換算の計算式もそれに合わせて16383.0( = 214 − 1 )で割る必要があります。
// 10ビットの場合
float voltage = value * 5.0 / 1023.0;
// 14ビットの場合
float voltage = value * 5.0 / 16383.0;ESP32で読み取り値の範囲が想定と違う
ESP32のデフォルト分解能は、他のボードと異なり12ビット(0〜4095)です。
10ビットの値(0〜1023)を想定したスケッチをESP32に移植する場合は注意してください。
analogReadResolution(10)を呼び出せば、他のボードと同じ10ビットに揃えることができます。
実践テクニック
analogReadResolution関数を使ったテクニック集です。
analogWrite関数と分解能を揃える
analogReadResolution関数とanalogWriteResolution関数で同じビット数を設定すると、読み取り値をmap関数で変換せずにそのまま出力に渡すことができます。
void setup() {
// analogReadとanalogWriteの分解能を揃える
analogReadResolution(12);
analogWriteResolution(12);
}
void loop() {
int value = analogRead(A0); // 12ビットで読み取り
analogWrite(9, value); // 読み取った値でそのままアナログ制御できる
}高い分解能で読み取るときは平均化する
分解能を上げると、電源やまわりの回路のノイズの影響で下位ビットが揺れやすくなります。
その場合は、次のように複数回読み取って平均をとると、値が安定します。
long sum = 0;
for (int i = 0; i < 16; i++) {
sum += analogRead(A0);
}
int value = sum / 16; // 16回の平均値移植性を考えて16ビット固定で書く
Arduino公式リファレンスでは、分解能をあえて16ビットに設定してスケッチを書くテクニックが紹介されています。
分解能をハードウェアの上限より高く設定した場合、超えた分は0で埋められるため、どのボードでも読み取り値は「0〜65535のスケール」に統一されます(細かさはボードのADコンバーターモジュールに依存します)。
種類の異なるボードでスケッチを共有する場合、より高分解能のADCを搭載したボードに移植しても、スケッチを変更せずにそのまま動作させることができます。
なお、AVRマイコン搭載ボードではanalogReadResolution関数は使用できない点(コンパイルエラーになる点)に注意してください。
どのボードでもハードウェアの分解能で読み取れるようにする
Arduino IDEのスケッチでは、そのスケッチが現在どのボード向けにコンパイルされているか知ることができます。
例えば、次のコードでは、ボード選択でArduino Uno R3などのAVRマイコン搭載ボードが選択されている時だけ、特定のコードを有効にするスケッチです。
void setup() {
// AVRマイコンの場合のみ特定のコードを実行したいときの書き方
#if defined(ARDUINO_ARCH_AVR)
// Arduino Uno R3、Arduino NanoなどのAVRマイコン搭載ボードのみ実行するコードをここに書く
#endif
}#if defined(ARDUINO_ARCH_AVR)の部分は、「もしアーキテクチャ(マイコン種類)がAVRだったら」という意味です。この「もし〜」が成立した場合、#endifまでのコードが実行(コンパイル)されます。
次のスケッチは、この仕組みを利用してボードごとにハードウェア分解能に合わせて読み取れるようにしたものです。このように記述することにより、同じスケッチを異なるボードで使用しても、そのボードに合わせた分解能で制御することができます。
// ボードごとのADC分解能設定(ハードウェア上限に合わせる)
#if defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4(ルネサスマイコン)
#define ADC_BITS 14
#define HAS_ADC_RESOLUTION 1
#elif defined(ARDUINO_ARCH_ESP32) // ESP32
#define ADC_BITS 12 // ESP32: 12bit
#define HAS_ADC_RESOLUTION 1
#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040) // SAMD・Raspberry Pi Pico
#define ADC_BITS 12
#define HAS_ADC_RESOLUTION 1
#else
#define ADC_BITS 10 // Uno R3・Nanoなど(AVRマイコン)
#define HAS_ADC_RESOLUTION 0
#endif
// この段階で、次のように定義されます
// ADC_BITS: 分解能がビット数で定義されます
// HAS_ADC_RESOLUTION: analogReadResolution関数が使えるかどうかが定義されます
// 0 = 使えない、1 = 使える
// 分解能から最大値を自動計算します
// 電圧換算やmap関数で数値変換するときなどに利用できます
const int ADC_MAX = (1 << ADC_BITS) - 1;
void setup() {
// analogReadResolution関数がサポートされている時のみanalogReadResolutinoを実行します
#if HAS_ADC_RESOLUTION
analogReadResolution(ADC_BITS);
#endif
Serial.begin(9600);
}
void loop() {
int value = analogRead(A0); // analogReadで読み取り
Serial.print("analogRead値: ");
Serial.println(value);
delay(500);
}個人でスケッチを作成する場合、このスケッチのように様々なボードに対応する必要性は低いと思いますが、スケッチを公開して多くの人に利用してもらう場合、有効な手段になります。
補足
代表的なボードの分解能一覧
代表的なArduinoボードのADコンバーターモジュールの分解能とデフォルト設定は次のようになっています。ESP32はデフォルトが12ビットである点、AVRマイコン搭載ボードでは関数自体が使用できない点に注意してください。
| ボード | 搭載マイコン | ADC モジュール 分解能 | デフォルト 分解能 |
|---|---|---|---|
| Arduino Uno R3 Arduino Nano Arduino Mega Arduino Microなど | AVRマイコン (ATmega328Pなど) | 10ビット | 10ビット (関数は使用不可のため変更できません) |
| Arduino Uno R4 | ルネサスマイコン (RA4M1) | 最大14ビット | 10ビット |
| Arduino Zero Arduino MKRシリーズ Arduino Nano 33 IoT | SAMD21 | 12ビット | 10ビット |
| Arduino Due | SAM3X8E | 12ビット | 10ビット |
| Arduino GIGA R1 WiFi | STM32H747 | 16ビット | 10ビット |
| ESP32 Devkit-C | ESP32 | 12ビット | 12ビット |
| Raspberry Pi Pico | RP2040 RP2350 | 12ビット | 10ビット |
設定はすべてのアナログピンに共通
analogReadResolution関数の設定は、ピンごとではなくボード全体に対して有効になります。
また、いつでも設定変更することができ、設定した以降のすべてのanalogRead関数の読み取りに適用されます。
設定した分解能とハードウェア分解能の関係
設定したビット数とハードウェア(ADコンバーターモジュール)の分解能が異なる場合、読み取り値は自動的に変換されます。
- 設定ビット数がハードウェアより大きい場合:
超えた分の下位ビットが0で埋められます(数値は大きくなりますが、細かさは変わりません)

- 設定ビット数がハードウェアより小さい場合:
余分な下位ビットが切り捨てられます

Arduinoボード内部動作
Arduinoボードの内部動作は次のようになっています。次のイラストは、例としてArduino Uno R4の内部のようすを示しています。
analogReadResolution関数を呼び出すと、指定したビット数がマイコン内部に保存されます(システムの変数に保存されます)。
その後analogRead関数を呼び出すと、次の処理が行われます。
ADCモジュールがピンの電圧を読み取り、ハードウェアの分解能で数値に変換します。Arduino Uno R4ではanalogReadResolutionの設定値にかかわらず14ビットで読み取ります※注記参照。
ADCの変換結果が、analogReadResolution関数で設定したビット数に合わせて変換されます。設定ビット数がハードウェアの分解能より大きい場合は左にビットシフトされ(空いた下位ビットは0埋め)、小さい場合は右にビットシフトされます(下位ビットは切り捨て)。
変換後の数値がanalogRead関数の戻り値として返されます。
注記:ハードウェアのADCモジュール自体の動作モードが切り替えることができるボードもあります。例えばArduino Uno R4に搭載されているRA4M1のADCは12ビット/14ビットの動作モードを持っており、設定に応じて切り替えられます。

