動作
Arduinoボードのピンの電圧をアナログ値で読み取ります。
「電圧をアナログ値で読み取る」とは、ピンの電圧を連続的な数値(整数)で読み取る、という意味です。
読み取った数値は実際の電圧ではなく、電圧に対応した数値です。例えば、5V動作のArduino Unoシリーズでは、ピンの電圧が最小の0Vのときは0、最大の5Vのときは1023、半分の2.5Vのときは512、などのように、最大電圧を1023、0Vを0とした電圧に比例した値になります。(最大値の数値はボードや設定に異なります。詳細は補足をご参照ください)
この読み取りは、Arduinoボード内部に次ような電圧計が内蔵されているイメージです。読み取ったピンの電圧を対応する整数値に置き換えるようなイメージです。
例えば、0〜5Vの測定範囲でピンの電圧が2.8Vのとき、analogReadで読み取る値は「2.8V」が0〜1023の数値範囲で計算されます( 2.8 ÷ 5 × 1023 = 572.88 → 切り捨てて572 )

analogRead関数が利用できるピンは限られています。
一般的にピン名に「A」が付いているピン(A0〜A5など)が対応しています。具体的に使用できるピンはArduinoボードによって異なりますので「補足:analogReadが使用できるピン」セクションを参照ください。
主な用途
- 温度センサー(アナログ電圧出力タイプ)の電圧値読み取り
- ボリューム(可変抵抗)の回転位置の読み取り
- 圧力センサーやジョイスティックなどのアナログ出力センサーの読み取り
- 電池の電圧の読み取りなど
analogRead関数は、ピンの電圧を連続した数値(アナログ値)として読み取ります。
(「連続した値を読み取る」=「アナログ」)
例えば、スイッチのON/OFFのように電圧が高いか低いかの2つの状態だけを読み取る場合はdigitalRead関数を使います。
書式
int value = analogRead(pin);| 引数 | pin | 電圧を読み取るピンを指定します。 ピン名(A5など)で指定します。 |
| 戻り値 | 0〜1023の整数値(分解能10ビットの場合) 0〜4095の整数値(分解能12ビットの場合) 0〜16383の整数値(分解能14ビットの場合) 0〜65535の整数値(分解能16ビットの場合) 電圧に比例した値が返ります。0Vのとき0、動作電圧のとき最大値になります。(動作電圧が5Vのときは5Vの時に最大値) 戻り値の数値範囲はボードごと、設定ごとに異なります。詳細は「補足:分解能」をご参照ください。 | |
使用例
次のコードにより、指定したピンの電圧をアナログ値で読み取ることができます。
int value = analogRead(A5); // ピン名指定 - A5ピンの電圧値を読み取って変数に代入
int value = analogRead(19); // ピン番号指定 - A5ピン = 19番ピンアナログピンをピン番号で指定することもできます。例えばArduino Unoシリーズでは、analogRead(14)はanalogRead(A0)と同じ動作です。ただし、ボード名に記載されているピン名(A0など)で指定した方がアナログピンであることが明確になり、スケッチの可読性が高くなるため、ピン名指定をおすすめします。
サンプルスケッチ
A0ピンに接続したボリューム(可変抵抗)の電圧を読み取り、読み取った値をシリアルモニタに表示するスケッチです。読み取り数値範囲は0〜1023です(分解能10ビットの場合)。
ボタンをクリックするとシミュレーターが動作します。スケッチを変更することもできます。変更した場合、シミュレーションを一度
ボタンをクリックして停止してから再度シミュレーターを開始してください。
トラブルシューティング
読み取った値が安定しない
alanalogRead関数で読み取った値が安定しないことがあります。代表的な原因として「ピンがどこにも接続されていない」や「電気的ノイズの影響」、「他のアナログピンからの影響」があります。
それぞれの原因と対策を説明します。
ピンがどこにも接続されていない
例えば、次の回路とスケッチでは、シリアルモニタに表示される値が安定しません。(実際に動作させて確認できます。
ボタンをクリックするとシミュレーターが動作します)
スイッチがOFFの場合、A3ピンには電気的にどこにも接続されていない状態になります。どこにも接続されていない金属の電圧(電位)は不安定になります。そのため、analogRead関数で読み取るたびにランダムな数値になってしまいます。
スイッチをONにすると、A3ピンはGNDピンに接続されるため、シリアルモニタに表示される数値は0(0V)になります。
ピンの電圧が安定しない場合、ピンがどこにも接続されていない可能性が高いので、最初に回路を確認してみてください。特にブレッドボードで製作した場合、きちんと接続されていないことがありますのでしっかり接続されているか確認します。また、ジャンパーワイヤーが断線していることもありますで、テスターなどで導通を確認してみてください。
電気的ノイズの影響
回路の接続が問題なく、analogReadで読み取った値が安定していない場合、電気的なノイズの影響を受けている可能性があります。
特に、センサーの配線が長い場合や、モーター(ブラシ付)やリレー(メカニカル)などのノイズ源が近くにある場合は、電気的・磁気的ノイズの影響を受けることが多く、値が不安定になることがあります。
ノイズの影響が考えられる場合は、ハードウェア、ソフトウェアの双方での対策を検討しましょう。
✅ ハードウェアの対策
アナログピンとGNDの間に0.1μF程度のセラミックコンデンサを接続すると、電気的ノイズの影響を低減することができます(高周波数ノイズ低減)。
センサーの配線を短くできない場合、ツイストペア線を使用する(2本の線をねじることで外部からの磁界ノイズを打ち消す)、シールド線を使用するなどの対策を行います。
またモーターが近くにある場合、モーターのプラスとマイナスの電極のなるべく近くに0.1μF程度のセラミックコンデンサを接続します。
✅ ソフトウェアの対策
ソフトウェアで複数回analogReadで読み取った値の平均をとることで、ノイズの影響を軽減できます。
次の関数はpinで指定したピンをcountで指定した回数読み取ってその平均値を計算する例です。
// pinをcount回読み取って平均値を返す
int readAnalogAverage(int pin, int count) {
long sum = 0;
for (int i = 0; i < count; i++) {
sum += analogRead(pin);
}
return sum / count;
}
// 関数使用例(A0ピンを5回読み取って平均を計算する)
int sensor_value = readAnalogAverage(A0, 5);他のアナログピンからの影響
Arduino Uno R3などの代表的なボードでは、複数のアナログピンが1つのADCモジュールを共有しています(ADC = Analog to Digital Converter = アナログ電圧を数値に変換するモジュール)。
例えば、2本のアナログピンにセンサーを接続して、それぞれのピンを連続してanalogReadで読み取ると、ADCモジュールの接続を切り替えるマルチプレクサ(切り替え回路)の特性により、直前に読み取ったアナログピンの電圧が影響を与えることがあります。
この影響を軽減するには、次のようにanalogReadを2回呼び出して、1回目の値を捨てる方法があります。
// A0とA1ピンの電圧値を連続して読み取る
// A0ピンの電圧値読み取り
int a0_value = analogRead(A0);
// A1ピンは2回目の読み取り値を使用する
int a1_value = analogRead(A1); // 1回目:マルチプレクサ切り替え後の回路状態を安定させる
delayMicroseconds(100); // 少しだけ時間待ち(必要に応じて)
a1_value = analogRead(A1); // 2回目:本番の読み取りADCの内部には、電圧値を測定するために一時的に電圧に応じた電荷を貯めておくための小さなコンデンサがあります。このコンデンサに、前回の読み取り時の電荷が貯まった状態のまま次の読み取りを行うと、読み取り値に影響が出ることがあります。
複数のアナログピンで連続して電圧値を読み取る場合、2回読み取ると次のように影響を低減することができます。
- マルチプレクサの切り替え:
analogReadが実行されると、ADCモジュール接続先を読み取りピンに切り替えます。 - 電荷の残留: 前回のピンを読み取ったときの電荷がコンデンサに残っていると、新しいピンの電圧に安定するまで時間がかかることがあります。
- 1回目の読み捨て: 1回目の
analogReadを行うことで、マルチプレクサが目的のピンに切り替わり、コンデンサがそのピンの電圧で充電(または放電)を開始します。 - 2回目の読み取り: 1回目の変換処理の間にコンデンサが十分に新しい電圧に馴染むため、2回目はより正確な値が得られます。
実践テクニック
analogRead関数でデジタル制御を行う際のテクニック集です。
読み取り値を電圧に変換する
読み取り値は電圧に応じた数値で、実際の電圧値ではありません。
例えば5V動作のボードで10ビット分解能の場合、0V〜5Vの電圧値は0〜1023の数値に対応しています。このボードで読み取った値を電圧値に変換する場合、次のように比例計算を行います。
// 5V動作ボード・10ビット分解能のA0ピンの読み取り値を電圧に変換する
float voltage = analogRead(A0) * (5.0 / 1023.0);読み取り値を別の数値範囲に変換する
analogReadの読み取り値を別の数値範囲に変換したいことがあります。
例えば、ボリュームを接続したピンの電圧値を0〜1023の数値で読み取り、0〜255の範囲に変換してanalogWrite関数でLEDの明るさやモーターの速度を制御する、というようなケースです。
このような場合は、map関数を使用すると便利です。
map関数は次のような働きをします。
long converted_value = map(value, 元範囲の最小値, 元範囲の最大値, 変換後範囲の最小値, 変換後範囲の最大値);例えば、元の数値範囲が0〜1023、変換後の数値範囲が0〜255の場合、測定した数値valueを変換するには次のコードとなります。
long converted_value = map(value, 0, 1023, 0, 255);具体例として、A0ピンにボリュームを接続し、ボリューム値により5番ピンに接続したLEDの明るさを調整する場合、次のコードになります。ボリュームの読み取り値範囲は0〜1023、LEDの明るさ制御の数値範囲は0〜255です。つまり0〜1023の数値範囲を0〜255の数値範囲に変換します。
int sensor_value = analogRead(A0); // A0ピンの電圧を0〜1023の範囲で読み取り
int pwm_value = map(sensor_value, 0, 1023, 0, 255); // 0〜1023を0〜255に変換
analogWrite(5, pwm_value); // 5番ピンにアナログ(PWM)出力乱数のシードにする
Arduinoでは乱数を発生するrandom関数が用意されています。
この関数で生成する乱数は特定のアルゴリズムで計算されていますので、毎回同じ結果になります。
具体的には、次のスケッチで生成される乱数は毎回同じです。
void setup() {
Serial.begin(9600); // シリアル開始
while(!Serial) {} // シリアル準備待ち
// 乱数10個生成
for(int i=0; i<10; i++) {
Serial.print(random(100));
}
}
loop() {
} 乱数を使用する場合、毎回同じにならないように乱数を初期化する必要があります。初期化する場合、randomSeed関数の引数に適当な数値を指定します。(乱数の初期化とは、乱数を生成するアルゴリズムで使用する最初の数値を変更することです。最初の数値を元に特定の数式で乱数を発生させますので、最初の数値が異なると、そのあとで計算される(生成される)数値は異なります)
randomSeed(適当な数値);何も接続されていないピンをanalogRead関数で読み取ると、読み取った数値はランダムになります。そこで、randomSeed関数の引数として、このランダムな数値を使用するのが一般的です。
次のように乱数を初期化します。
void setup() {
Serial.begin(9600); // シリアル開始
while(!Serial) {} // シリアル準備待ち
randomSeed(analogRead(A0)); // 乱数を初期化(A0ピンには何も接続しない)
// 乱数10個生成
for(int i=0; i<10; i++) {
Serial.print(random(100));
}
}
loop() {
} 補足
analogReadが使用できるピン
analogRead関数で使用できるピンは、Arduinoボードによって異なります。代表的なボードのアナログ入力対応ピンは次のとおりです。
| ボード | 対応ピン数 | 対応ピン |
|---|---|---|
| Arduino Uno R3 Arduino Uno R4 Arduino Uno Q Arduino Micro Arduino Leonard Arduino Zero | 6 | A0 〜 A5 |
| Arduino MKRシリーズ | 7 | A0 〜 A6 |
| Arduino Nano | 8 | A0 〜 A7 |
| Arduino Mega | 16 | A0 〜 A15 |
| Arduino Due Arduino Giga R1 WiFi | 12 | A0 〜 A11 |
| ESP32 DevKitCシリーズ | 16 | ❶ GPIO 32, 33, 34, 35, 36, 39 ❷ GPIO 0, 2, 4, 12, 13, 14, 15, 25, 26, 27 (❷のピンはWi-Fi機能と併用不可) |
| ESP8266 | 1 | A0 |
| Raspberry Pi Pico | 3 | GP 26, 27, 28 |
分解能
ADCの分解能はボードに搭載しているマイコンの仕様によって異なります。ただし、Arduinoの場合、ボード間の互換性を保つために、多くのボードではデフォルトの分解能は10ビット(0〜1023)になっています。分解能が10ビットを超えるボードについては、analogReadResolution関数で分解能の設定が可能になっています。
代表的なボードのデフォルト分解能と設定可能な最大の分解能をまとめます。
| ボード | デフォルト分解能 | 分解能 |
|---|---|---|
| Arduino Uno R3 Arduino Micro Arduino Nano Arduino Leonard Arduino Mega | 10ビット | 10ビット |
| Arduino Zero Arduino Due Arduino MKRシリーズ Arduino Nano33シリーズ | 10ビット | 12ビット |
| Arduino Uno R4 Arduino Uno Q | 10ビット | 14ビット |
| Arduino Giga R1 WiFi | 10ビット | 16ビット |
| ESP32 DevKitCシリーズ | 12ビット | 12ビット |
| ESP8266 | 10ビット | 10ビット |
| Raspberry Pi Pico | 10ビット | 12ビット |
基準電圧
分解能を大きくすると、ピンの電圧を細かく読むことができます。
例えば、Arduino Uno R4のデフォルト分解能は10ビットです。動作電圧の5Vを0〜1023の数値で読み取りますので、読み取った値は約4.89mV(5V ÷ 1023)刻みになります。
もっと細かく読み取りたい場合、Arduino Uno R4で分解能を14ビットに設定すると、読み取った値は約0.3mV(5V ÷ 16383)刻みになります。
電圧値を細かく読み取る方法は、分解能を大きくする以外にも基準電圧を変更する方法があります。
Arduino Uno R4では、デフォルトでは動作電圧の5Vを参照して0〜1023の値で読み取ります。この「参照する電圧」の5Vの値を変更することもできます。
Arduino Uno R4で、参照電圧を1.5Vに変更すると、1.5Vを0〜1023の値で読み取りますので、読み取った値は約1.47mV(1.5V ÷ 1023)刻みになります。
例えばアナログ温度センサー「LM60BIZ」は、温度が1度変化すると出力電圧は6.25mV変化します。参照電圧を5V・10ビットで読み取ると、約0.78度刻みになります(4.89mV ÷ 6.25mV)。参照電圧を1.5V・10ビットで読み取ると、約0.23度刻みになります。
このように、狭い範囲の電圧を読み取りたい場合、基準電圧を変更することも有効です。
analogRead関数で電圧値をより細かく読み取りたい場合、分解能を上げる方法と基準電圧を下げる方法があります。それぞれ次のようなメリット・デメリットがあります。
分解能を上げる方法
メリットとしては、測定可能な電圧範囲がそのまま維持される点です。5V基準のまま細かく読めるので、入力電圧の範囲を気にする必要がありません。
デメリットとしては、ノイズの影響が相対的に大きくなります。アナログ回路や電源のノイズにより、下位ビットがノイズに埋もれてしまい読み取り値がばらつきます。
もう一つのデメリットとして、analogRead関数の処理時間が長くなることがあります(ビット数が多くなることにより、より処理時間が長くかかる)。高速に測定したい用途では注意が必要です。
なお、AVRマイコン系ボード(Uno R3、Nano、Mega、Leonardo等)はハードウェアが10ビット固定なので、この分解能を上げる方法自体が使えません。
参照電圧を下げる方法
メリットとしては、AVRマイコン系ボードでも使える点です。
また、分解能を変えていないので変換時間に影響がありません。
デメリットとしては、基準電圧を超える電圧を入力するとADCの読み取り値が最大値に張り付いてしまいます。測定電圧範囲が事前に分かっている場合にのみ安全に使える方法です。
また、選択できる基準電圧がボードごとに決まっており、自由な値には設定できません。Arduino Uno R3であればDEFAULT(5V)かINTERNAL(1.1V)の2択で、中間の値は選べません。中間の値を使用したい場合は、ボードにある「AREFピン」(Analog Reference・アナログ変換の参照電圧ピン)に外部から参照電圧を供給する方法もありますが、外付け回路が必要になります。
digitalRead関数との使い分け
digitalRead関数では、ピンの電圧を2値で読み取ることができますが、anlogRead関数でも同様の処理が可能です。
例えば、analogRead関数で読み取った数値が20以下の場合はLOW、1000以上の場合はHIGHなどと判定すると、digitalRead関数と同じような処理ができます。
ただし、analogRead関数はdigitalRead関数の何倍もの処理時間が必要になり、消費電力も増加します。
デジタル値読み取りであればdigitalRead関数、アナログ値読み取りであればanalogRead関数を利用するようにしましょう。
Arduinoボード内部動作
analogReadに関するArduinoボードの内部は次のようになっています。

冒頭で説明したADCモジュール(アナログ電圧計)が内蔵されていますが、すべてのアナログピンに個別に接続されているわけではなく、1個のモジュールを切り替え器(マルチプレクサ)で切り替えながらピンの電圧を測定します。
このような構造から、異なるアナログピンを連続して読み取る場合、前のピンの影響を受ける可能性があります。
ボードによってはADCモジュールが複数内蔵されているものもあります。
例えばESP32は2つのADCモジュールが内蔵されていて、GPIO 32, 33, 34, 35, 36, 39はADCモジュール1、GPIO 0, 2, 4, 12, 13, 14, 15, 25, 26, 27はADCモジュール2にマルチプレクサを介して接続されています。
