本文へ移動
Arduinoのif文、
結局「もし〜なら」が分かれば怖くない。
「センサー値が○以上ならLEDを光らせたい」「ボタンを押したときだけモーターを動かしたい」——Arduino工作のほとんどは、この「もし〜なら」を書くif文の書き方にたどり着きます。この記事では、ボタンでLEDを点ける最初の一歩から、センサー値を3段階に判定する実用コード、&&や||による複数条件、=と==の取り違えというベテランでもやりがちなミスまで、実際に動くコードとあわせて順番に解説します。さらに、switch文との使い分けや、if文が動かないときに確認すべき項目も紹介するので、この記事だけでArduinoの条件分岐に関するつまずきをひと通り解消できます。
なぜArduino工作の大部分がif文になるのか
Arduinoのloop()は電源が入っている間ずっと繰り返し実行されます。しかし中身は「毎回同じ動きをする」だけではありません。実際にはほとんどの場面で、「ボタンが押されているか」「センサーの値がどのくらいか」を毎回チェックする作業が発生します。そのうえで、チェックの結果によって動きを変えるという処理が続きます。この「チェックして、結果によって動きを変える」部分を担当するのがif文です。
どんな出力もif文に行き着く理由
LEDを光らせる、ブザーを鳴らす、モーターを回す——どんな出力も、突き詰めると「何かの条件が成り立った時だけ実行する」という形に落とし込まれます。つまりif文の書き方をマスターすることは、Arduino工作の設計図の描き方をマスターすることとほぼ同じ意味を持ちます。だからこそ、この記事ではif文の基礎から実用的な応用まで順番に確認していきます。
スケッチの土台となるsetup()とloop()の役割や実行順序をまだ確認していない場合は、先にArduinoのsetup()とloop()とは?実行順序と書き方に目を通しておくと、この記事の内容がより理解しやすくなります。ボタンやLED、抵抗などの部品をまだ揃えていない場合は、Arduinoに必要な工具・部品リストも参考にしてください。
if文の書き方の基本構文とdigitalRead/analogReadの復習

if文の基本形
if文の基本形はとてもシンプルです。if ( 条件 ) { 条件が成り立つ時に実行する処理 }という形で書き、条件の部分にはtrueかfalseのどちらかに評価される式を入れます。
if (条件) {
// 条件がtrueの時だけ実行される
}
else {
// 条件がfalseの時に実行される(省略可能)
}
if文の中でよく使うのが、ボタンやセンサーの値を読み取る2つの命令です。どちらも「読み取る」命令ですが、扱える値の細かさが異なります。なお、それぞれのピンを使う前にはpinMode()での入出力設定が必要になる点も忘れずに押さえておきましょう。
| 命令 | 読み取れる値 | if文での典型的な使い方 |
|---|---|---|
digitalRead(pin) |
HIGH(5V)かLOW(0V)の2択 | if (digitalRead(2) == LOW)(ボタンが押されている) |
analogRead(pin) |
0〜1023の1024段階 | if (analogRead(A0) >= 500)(センサー値がしきい値以上) |
比較演算子の一覧
条件式を作るときは、下の比較演算子を使います。特に「等しいかどうか」を調べる時は==を使うという点が最初のつまずきポイントです。この点については7章で詳しく解説します。
| 演算子 | 意味 |
|---|---|
== |
等しい(イコール2つ) |
!= |
等しくない |
< / > |
より小さい/より大きい |
<= / >= |
以下/以上 |
digitalRead・analogReadそのものの詳しい仕組みはanalogRead・analogWriteの使い方で、pinModeの3つのモードの詳細はArduinoのピンモード(pinMode)の基礎解説で、それぞれ深掘りしています。ここでは、if文の条件式としての使い方に絞って解説します。
また、pressedやsensorValueのように条件の結果や読み取り値を変数に入れて使う場面が多く出てきます。変数の型の使い分けにまだ自信がない場合は、Arduinoの変数の型(int・float・String)の使い分けもあわせて確認しておくとスムーズです。
なお、これらの詳しい仕様は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Ω程度のプルダウン抵抗を別途用意します。LED側の抵抗値の計算方法はArduinoでLEDを光らせる基本回路|配線から抵抗値計算で詳しく解説しています。
コード2:センサー値が500以上ならブザー
次は、analogRead()で読み取ったセンサー値(0〜1023)が、あるしきい値を超えたらブザーを鳴らすコードです。ここでは「500以上」を条件にしています。この考え方は、可変抵抗、光センサー、加速度センサーなど、アナログ値を返すセンサーであれば同じように応用できます。たとえば温湿度センサー(DHT11・DHT22)や超音波距離センサー(HC-SR04)を使う工作でも、このしきい値判定の考え方がそのまま使われています。
// センサー値が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が省略できる理由
else if (value >= 300 && value < 700)のように毎回下限も書いてしまうこと自体は間違いではありませんが、条件が増えるほど書き間違いのリスクが上がります。「1つ前のifで否定された範囲がそのまま前提になる」という考え方に慣れると、コードがすっきりして読みやすくなります。
このような多段階のしきい値判定は、圧センサーを用いた電子工作の基礎編のように「弱く押した/強く押した」を判定する場面でもそのまま応用できます。
複数条件を指定する&&と||
「2つのセンサーが両方とも一定値を超えたら」「ボタンAかボタンBのどちらかが押されたら」というように、複数の条件を1つのif文にまとめたい場面がよくあります。ここで使うのが&&(論理AND)と||(論理OR)です。
&&(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)ページ ↗で確認できます。
複数センサーを&&や||で組み合わせる考え方は、リハビリ用途にも応用されています。たとえばArduino×筋電センサー完全ガイドでは2チャンネルの筋電値を組み合わせて判定する場面が出てきます。また、Arduinoを使ったリアルタイムフィードバックシステムの作り方では、複数の条件をまとめてフィードバック動作に変換する場面が登場します。
=と==を間違えた場合に何が起きるか
if文で最も有名な落とし穴が、代入(=)と比較(==)の取り違えです。見た目がほぼ同じなうえに、間違えてもコンパイルエラーにならないことが多いため、初心者だけでなく経験者でも時々やってしまうミスです。
int sensorValue = 0;
// 【誤り】=は代入演算子。この式は「10を代入する」動作をしてしまう
if (sensorValue = 10) {
// sensorValueに10が代入され、しかもif文の条件は常にtrueになる
// → 条件分岐のつもりが「常に実行される処理」になってしまう
}
// 【正しい】==は比較演算子。sensorValueが10と等しいかどうかを調べる
if (sensorValue == 10) {
// sensorValueが本当に10の時だけ実行される
}
なぜif文の中身が常に実行されるのか
このミスはArduino IDEの検証(コンパイル)で多くの場合エラーになりません。なぜなら、代入も比較もどちらも文法的に正しい式だからです。そのため、動かしてみて「なぜか条件を満たしていないのに毎回反応する」という時は、真っ先に=と==を疑ってください。コンパイル時に検出されるエラーの一覧はArduinoのコンパイルエラー一覧|書き込み・動作トラブル対処法にまとめています。
比較する側を先に書く「ヨーダ記法」(if (10 == sensorValue))にしておくと、うっかり=を1つだけ書いてしまった時に10側へは代入できずコンパイルエラーになるため、ミスに早く気づけます。読みにくいと感じる場合は無理に使う必要はありませんが、知っておくと安心です。
if文とswitch文はどちらを使うべきか
Arduinoにはif文のほかに、switch文という条件分岐の書き方もあります。「1つの変数の値が、AならこれB、ならこれ……」というように、1つの変数を複数のパターンと比較する場合はswitch文のほうがすっきり書けることがあります。一方で、この記事で扱ってきたようなしきい値による範囲判定や、&&・||を使う複合条件はswitch文では表現できず、if文が必須になります。
// switch文の例:モードの値によって処理を切り替える
int mode = 2;
switch (mode) {
case 1:
// modeが1の時の処理
break;
case 2:
// modeが2の時の処理
break;
default:
// どれにも当てはまらない時の処理
break;
}
// if文でなければ書けない範囲判定・複合条件の例
int sensorValue = analogRead(A0);
if (sensorValue >= 300 && sensorValue < 700) {
// 300以上700未満、というswitchでは表現できない条件
}
| 判定したい内容 | 向いている書き方 |
|---|---|
| 変数が特定の値(1、2、3…)のどれと一致するか | switch文 |
| しきい値による範囲判定(○以上、○未満など) | if文 |
| 複数の条件を&&・||で組み合わせる判定 | if文 |
| true/falseの2択のみの判定 | if文(switchでも書けるが冗長になりがち) |
Arduinoのセンサー工作では、値をピンポイントの整数で比較するよりも「○○以上なら」「○○未満なら」という範囲判定を使う場面のほうが圧倒的に多いため、この記事で解説してきたif文が主役になるケースがほとんどです。switch文はモード切り替えのような限られた場面で覚えておく、という位置づけで十分でしょう。
if文が動かないときの確認項目
「if文を書いたのに反応しない」「常にtrueまたは常にfalseになっている」という時は、上から順番に次の項目を確認すると、多くの場合原因が見つかります。
文法まわりのチェック(1〜3)
波かっこ { } の対応が取れているか。if文のブロックの開始と終了がずれていると、意図しない範囲が条件付きになったり、逆に常時実行される部分ができてしまいます。
行末のセミコロン ; を書き忘れていないか。if文自体にセミコロンは不要ですが、その中の各処理文には必要です。抜けているとコンパイルエラーになります。
=(代入)と==(比較)を混同していないか。7章で解説した通り、条件が常にtrueになるバグの代表例です。
配線・データまわりのチェック(4〜8)
pinMode()で入出力の設定を忘れていないか。INPUTのつもりのピンがOUTPUTのままだと、digitalRead()が期待通りの値を返しません。
配線のピン番号とコード内のピン番号が一致しているか。ブレッドボード上の配線を変えた後、コードの定数を直し忘れているケースは非常に多いです。
シリアルモニタで実際の値を確認したか。Serial.println(sensorValue);を条件のすぐ上に一時的に追加し、想定通りの数値が来ているかを確認します。しきい値をまたいでいないだけ、というケースも珍しくありません。
変数の型やスコープが合っているか。ループ内だけで宣言した変数を別の場所から参照しようとしていないか、あるいはint型で受けるべき値をbool型で受けていないかなどを確認します。
不等号の向き(< と >、<= と >=)が意図通りか。「以上」のつもりで>だけを書いてしまい、しきい値ちょうどの時に条件から漏れる、というのもよくあるミスです。
一度に全部を疑うと混乱しやすいので、まずシリアルモニタで「if文に渡っている値」自体が正しいかを確認しましょう。値が正しいのに反応しない場合は、条件式の書き方(=と==、不等号の向き、波かっこ)を疑うという順番で進めると効率的です。
この記事のコードでは動作確認のしやすさを優先してdelay()を使っていますが、delay()の間はif文自体を含めてloop()全体が止まってしまいます。ボタン反応が鈍い、あるいは他の処理と組み合わせると動きが不自然になる、という場合はArduinoのmillis()でdelayを使わない書き方を参考に、delay()なしの書き方へ置き換えることを検討してください。
次のステップ:条件分岐をさらに整理する
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文とswitch文はどちらを使うべきですか?
1つの変数が特定の値と一致するかどうかを複数パターン判定したい時はswitch文が読みやすくなります。一方、しきい値による範囲判定や&&・||を使う複合条件はif文でなければ書けません。センサー値の範囲判定が中心のArduino工作では、基本的にif文を使う場面のほうが多くなります。
まとめ
if文の書き方は「条件を書いて、成り立つ時だけ動かす」というシンプルな考え方の積み重ねです。まずは1章のボタンLEDで感覚をつかみ、しきい値判定、3段階判定、&&・||による複数条件へと1つずつ組み合わせを増やしていきましょう。そうすれば、センサーを使ったほとんどの工作に応用できるようになります。もし途中で詰まった時は、9章のチェックリストとシリアルモニタでの実測値確認に戻るのが、結局いちばんの近道です。
コメント