本文へ移動
Arduinoのif文、
結局「もし〜なら」が分かれば怖くない。
「センサー値が○以上ならLEDを光らせたい」「ボタンを押したときだけモーターを動かしたい」——Arduino工作のほとんどは、この「もし〜なら」を書くif文にたどり着きます。この記事では、ボタンでLEDを点ける最初の一歩から、センサー値を3段階に判定する実用コード、&&や||による複数条件、=と==の取り違えというベテランでもやりがちなミス、そして「if文が動かない」ときに確認すべき項目まで、実際に動くコードとあわせて順番に解説します。
なぜArduino工作の大部分がif文になるのか
Arduinoのloop()は電源が入っている間ずっと繰り返し実行されますが、その中身は「毎回同じ動きをする」だけではありません。実際には、「ボタンが押されているか」「センサーの値がどのくらいか」を毎回チェックし、その結果によって動きを変えるという作業がほとんどです。この「チェックして、結果によって動きを変える」部分を担当するのがif文です。
LEDを光らせる、ブザーを鳴らす、モーターを回す——どんな出力も、突き詰めると「何かの条件が成り立った時だけ実行する」という形に落とし込まれます。つまりif文の書き方をマスターすることは、Arduino工作の設計図の描き方をマスターすることとほぼ同じ意味を持ちます。
基礎文法(setup/loop、変数、for、whileなど)を一から確認したい場合は、まず土台となる基礎知識と、モーターや表示器を含むコピペ用コード集をまとめた入門ガイドに目を通しておくと、この記事の内容がより理解しやすくなります。
if文の基本構文とdigitalRead/analogReadの復習

if文の基本形はとてもシンプルです。if ( 条件 ) { 条件が成り立つ時に実行する処理 }という形で、条件の部分にはtrue(成り立つ)かfalse(成り立たない)のどちらかに評価される式を書きます。
if (条件) {
// 条件がtrueの時だけ実行される
}
else {
// 条件がfalseの時に実行される(省略可能)
}
if文の中でよく使うのが、ボタンやセンサーの値を読み取る2つの命令です。どちらも「読み取る」命令ですが、扱える値の細かさが異なります。
| 命令 | 読み取れる値 | if文での典型的な使い方 |
|---|---|---|
digitalRead(pin) |
HIGH(5V)かLOW(0V)の2択 | if (digitalRead(2) == LOW)(ボタンが押されている) |
analogRead(pin) |
0〜1023の1024段階 | if (analogRead(A0) >= 500)(センサー値がしきい値以上) |
条件式を作るときは、下の比較演算子を使います。特に「等しいかどうか」を調べる時は==を使うという点が最初のつまずきポイントで、これは7章で詳しく解説します。
| 演算子 | 意味 |
|---|---|
== |
等しい(イコール2つ) |
!= |
等しくない |
< / > |
より小さい/より大きい |
<= / >= |
以下/以上 |
これらの詳しい仕様は、Arduino公式のifページ ↗と、公式ビルトイン例のIf Statement ↗にまとまっています。
コード1:ボタンを押したらLED点灯

最初の一歩は、ボタンの状態をdigitalRead()で読み取り、押されている時だけLEDを光らせるコードです。ボタンにはINPUT_PULLUPを使うことで、外付けの抵抗を用意せずに配線を減らせます。
// ボタンを押している間だけLEDを点灯する
const int BUTTON_PIN = 2;
const int LED_PIN = 8;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // 内部プルアップを使う
pinMode(LED_PIN, OUTPUT);
}
void loop() {
bool pressed = digitalRead(BUTTON_PIN) == LOW; // 押すとLOWになる
if (pressed) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
ボタンの配線は「片方をピン、もう片方をGND」に接続するだけでOKです。外部抵抗を使う回路の場合はINPUT(プルアップなし)にして、10kΩ程度のプルダウン抵抗を別途用意します。
コード2:センサー値が500以上ならブザー
次は、analogRead()で読み取ったセンサー値(0〜1023)が、あるしきい値を超えたらブザーを鳴らすコードです。ここでは「500以上」を条件にしています。可変抵抗、光センサー、加速度センサーなど、アナログ値を返すセンサーであれば同じ考え方で応用できます。
// センサー値が500以上になったらブザーを鳴らす
const int SENSOR_PIN = A0;
const int BUZZER_PIN = 8;
const int THRESHOLD = 500;
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(9600); // 実測値を確認するためのシリアル出力
}
void loop() {
int sensorValue = analogRead(SENSOR_PIN);
Serial.println(sensorValue); // シリアルモニタで値を確認できる
if (sensorValue >= THRESHOLD) {
tone(BUZZER_PIN, 1000); // 1000Hzの音を鳴らし続ける
} else {
noTone(BUZZER_PIN);
}
delay(50);
}
センサーは種類や個体差、周囲の明るさ・温度によって値の範囲が変わります。コードを書く前に一度シリアルモニタで実際の数値の動きを観察し、そのうえでしきい値を決めると狙い通りに動きやすくなります。
コード3:300未満・300〜700・700以上の3段階判定
しきい値が1つだけの判定に慣れたら、次は複数のしきい値で段階分けする判定です。else ifを使うと、「300未満」「300〜700」「700以上」のような3段階(あるいはそれ以上)の判定を1つのif文の塊として書けます。ここではLEDの色を変える例で確認します。
// センサー値を3段階に判定してLEDの色を切り替える
const int SENSOR_PIN = A0;
const int LED_LOW = 5; // 300未満:青LED
const int LED_MID = 6; // 300〜700:黄LED
const int LED_HIGH = 7; // 700以上:赤LED
void setup() {
pinMode(LED_LOW, OUTPUT);
pinMode(LED_MID, OUTPUT);
pinMode(LED_HIGH, OUTPUT);
Serial.begin(9600);
}
void loop() {
int value = analogRead(SENSOR_PIN);
Serial.println(value);
// 上から順番に判定され、最初に成立した条件だけが実行される
if (value < 300) {
digitalWrite(LED_LOW, HIGH);
digitalWrite(LED_MID, LOW);
digitalWrite(LED_HIGH, LOW);
} else if (value < 700) {
digitalWrite(LED_LOW, LOW);
digitalWrite(LED_MID, HIGH);
digitalWrite(LED_HIGH, LOW);
} else {
digitalWrite(LED_LOW, LOW);
digitalWrite(LED_MID, LOW);
digitalWrite(LED_HIGH, HIGH);
}
delay(100);
}
else if (value >= 300 && value < 700)のように毎回下限も書いてしまうこと自体は間違いではありませんが、条件が増えるほど書き間違いのリスクが上がります。「1つ前のifで否定された範囲がそのまま前提になる」という考え方に慣れると、コードがすっきりして読みやすくなります。
複数条件を指定する&&と||
「2つのセンサーが両方とも一定値を超えたら」「ボタンAかボタンBのどちらかが押されたら」というように、複数の条件を1つのif文にまとめたい場面がよくあります。ここで使うのが&&(論理AND)と||(論理OR)です。
| 演算子 | 読み方 | 成立する条件 |
|---|---|---|
&& |
論理AND(かつ) | 両方の条件がtrueの時だけtrue |
|| |
論理OR(または) | どちらか一方でもtrueならtrue |
// &&(両方満たす)と||(どちらか満たす)の使い分け
const int SENSOR_A = A0;
const int SENSOR_B = A1;
const int BUTTON_1 = 2;
const int BUTTON_2 = 3;
const int LED_PIN = 8;
void setup() {
pinMode(BUTTON_1, INPUT_PULLUP);
pinMode(BUTTON_2, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int valueA = analogRead(SENSOR_A);
int valueB = analogRead(SENSOR_B);
bool button1Pressed = digitalRead(BUTTON_1) == LOW;
bool button2Pressed = digitalRead(BUTTON_2) == LOW;
// && : 2つのセンサーが「両方とも」500以上の時だけ点灯
bool bothSensorsHigh = (valueA >= 500) && (valueB >= 500);
// || : ボタン1「または」ボタン2、どちらか押されたら点灯
bool eitherButtonPressed = button1Pressed || button2Pressed;
if (bothSensorsHigh || eitherButtonPressed) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
&&(論理AND)と&(ビット単位のAND)は見た目が似ていますが全くの別物です。同様に||(論理OR)と|(ビット単位のOR)も別物です。if文の条件には基本的に2文字の&&・||を使います。詳しい仕様は公式の&&(logical AND)ページ ↗と公式の||(logical OR)ページ ↗で確認できます。
=と==を間違えた場合に何が起きるか
if文で最も有名な落とし穴が、代入(=)と比較(==)の取り違えです。見た目がほぼ同じなうえに、間違えてもコンパイルエラーにならないことが多いため、初心者だけでなく経験者でも時々やってしまうミスです。
int sensorValue = 0;
// 【誤り】=は代入演算子。この式は「10を代入する」動作をしてしまう
if (sensorValue = 10) {
// sensorValueに10が代入され、しかもif文の条件は常にtrueになる
// → 条件分岐のつもりが「常に実行される処理」になってしまう
}
// 【正しい】==は比較演算子。sensorValueが10と等しいかどうかを調べる
if (sensorValue == 10) {
// sensorValueが本当に10の時だけ実行される
}
このミスはArduino IDEの検証(コンパイル)で多くの場合エラーになりません。代入も比較もどちらも文法的に正しい式だからです。動かしてみて「なぜか条件を満たしていないのに毎回反応する」という時は、真っ先に=と==を疑ってください。
比較する側を先に書く「ヨーダ記法」(if (10 == sensorValue))にしておくと、うっかり=を1つだけ書いてしまった時に10側へは代入できずコンパイルエラーになるため、ミスに早く気づけます。読みにくいと感じる場合は無理に使う必要はありませんが、知っておくと安心です。
if文が動かないときの確認項目
「if文を書いたのに反応しない」「常にtrueまたは常にfalseになっている」という時は、上から順番に次の項目を確認すると、多くの場合原因が見つかります。
波かっこ { } の対応が取れているか。if文のブロックの開始と終了がずれていると、意図しない範囲が条件付きになったり、逆に常時実行される部分ができてしまいます。
行末のセミコロン ; を書き忘れていないか。if文自体にセミコロンは不要ですが、その中の各処理文には必要です。抜けているとコンパイルエラーになります。
=(代入)と==(比較)を混同していないか。7章で解説した通り、条件が常にtrueになるバグの代表例です。
pinMode()で入出力の設定を忘れていないか。INPUTのつもりのピンがOUTPUTのままだと、digitalRead()が期待通りの値を返しません。
配線のピン番号とコード内のピン番号が一致しているか。ブレッドボード上の配線を変えた後、コードの定数を直し忘れているケースは非常に多いです。
シリアルモニタで実際の値を確認したか。Serial.println(sensorValue);を条件のすぐ上に一時的に追加し、想定通りの数値が来ているかを目で見て確認します。しきい値をまたいでいないだけ、というケースも珍しくありません。
変数の型やスコープが合っているか。ループ内だけで宣言した変数を別の場所から参照しようとしていないか、int型で受けるべき値をbool型で受けていないかなどを確認します。
不等号の向き(< と >、<= と >=)が意図通りか。「以上」のつもりで>だけを書いてしまい、しきい値ちょうどの時に条件から漏れる、というのもよくあるミスです。
一度に全部を疑うと混乱しやすいので、まずシリアルモニタで「if文に渡っている値」自体が正しいかを確認し、値が正しいのに反応しないなら条件式の書き方(=と==、不等号の向き、波かっこ)を疑う、という順番で進めると効率的です。
よくある質問とまとめ
if文とif...else、else ifの違いは何ですか?
ifは条件が成り立つ時だけ処理をします。elseを付けると「それ以外の場合」の処理を追加でき、else ifを重ねると3段階以上の判定を1つの塊として書けます。上から順番に条件が調べられ、最初に成立した条件のブロックだけが実行されます。
=(イコール1つ)と==(イコール2つ)を間違えるとどうなりますか?
if(x = 10)のように=を1つだけ書くと、比較ではなく代入が行われ、xに10が代入された上でその式自体が常にtrueと評価されます。結果としてif文の中が常に実行されてしまい、意図した条件分岐にならないバグの原因になります。
if文を書いたのにLEDやブザーが反応しません。何を確認すればいいですか?
波かっこの対応、セミコロンの有無、=と==の混同、pinModeの設定漏れ、ピン番号の配線との不一致、シリアルモニタでの実測値確認、変数の型やスコープ、条件の不等号の向きの8点を順番に見直すと大半の原因が見つかります。
複数条件を指定する&&と||はどう使い分けますか?
&&(論理AND)はすべての条件が同時にtrueの時だけ成立します。||(論理OR)はどれか1つでもtrueなら成立します。両方の条件を満たしてほしい時は&&、いずれか一方でよい時は||を使います。
if文は「条件を書いて、成り立つ時だけ動かす」というシンプルな考え方の積み重ねです。まずは1章のボタンLEDで感覚をつかみ、しきい値判定、3段階判定、&&・||による複数条件へと1つずつ組み合わせを増やしていけば、センサーを使ったほとんどの工作に応用できるようになります。詰まった時は8章のチェックリストとシリアルモニタでの実測値確認に戻るのが、結局いちばんの近道です。
コメント