第2回
条件分岐・繰り返し
条件によって処理を変え、同じ処理を繰り返す。
if
if (condition) {
}if / else
if (temperature >= 30) {
// ...
} else {
// ...
}else if
if (temperature >= 40) {
} else if (temperature >= 30) {
} else {
}switch
switch (mode) {
case 0:
break;
case 1:
break;
default:
break;
}for
for (int i = 0; i < 10; i++) {
}for ( 初期化 ; 継続条件 ; 更新 )
↓ ↓ ↓
int i = 0 i < 10 i++while
while (condition) {
}マイコンでの注意
無限ループはマイコンでは珍しくない。
while (true) {
}ただしArduinoのloop()自体が繰り返し呼ばれるため、通常はloop()を利用する。loop()の中で長時間止まり続けると、他の処理が一切動かなくなる点に注意する。
動かして確かめる
演習に入る前に、まずこのサンプルを動かして結果を見る。追加の部品は要らない。光るのはボードに載っている内蔵LEDで、それ以外はシリアルモニタの出力で確かめられる。code/examples/02-control/を開き、pio run -t uploadで書き込んでからpio device monitorで出力を見る(手順と、外付けのLEDなどをつなぐ場合は開発環境にまとめてある)。
/**
* @brief 温度から警報の段階を決める
* @details 上から順に評価されるため、条件の順番に意味がある。
* @param temperature 温度(℃)
* @return 0=normal, 1=warning, 2=danger
*/
int alarmLevel(float temperature) {
if (temperature >= 40.0f) {
return 2;
} else if (temperature >= 30.0f) {
return 1;
} else {
return 0;
}
}
/**
* @brief 警報の段階を文字列で表示する
* @param level 警報の段階(0〜2)
*/
void printLevel(int level) {
switch (level) {
case 0:
Serial.println("normal");
break;
case 1:
Serial.println("warning");
break;
case 2:
Serial.println("danger");
break;
default:
Serial.println("unknown");
break;
}
}
/**
* @brief 内蔵LEDを指定回数点滅させる
* @param times 点滅回数
*/
void blink(int times) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(BLINK_MS);
digitalWrite(LED_BUILTIN, LOW);
delay(BLINK_MS);
}
}void loop() {
// 温度を 25.0 から 5.0 ずつ上げていき、分岐が切り替わる点を見る
static float temperature = 25.0f;
int level = alarmLevel(temperature);
Serial.print(temperature);
Serial.print(" -> ");
printLevel(level);
// 段階と同じ回数だけ点滅させる(normal のときは光らない)
blink(level);
temperature += 5.0f;
if (temperature > 45.0f) {
temperature = 25.0f;
}
delay(1000);
}--- for ---
0 1 2 3 4 5 6 7 8 9
--- while ---
3
2
1
--- if / else if / switch ---
25.00 -> normal
30.00 -> warning
35.00 -> warning
40.00 -> danger
45.00 -> danger
25.00 -> normal確かめること。
25.00はnormal、30.00はwarning、40.00はdangerになっているalarmLevel()の>= 40.0fと>= 30.0fを入れ替えると、dangerが一度も出なくなる。条件の順番に意味があるprintLevel()のbreakを1つ消すと、次のcaseへ流れ込む(フォールスルー)- LEDの点滅回数が段階と同じ回数になっている。
normalのときは光らない
演習
- 0〜9をシリアル出力する
- LEDを一定回数点滅させる
- ボタンが押されている間だけLEDを点灯する
3つ目はloop()とifの組み合わせで書ける。whileで待ち続けないほうがよい理由も一緒に考えるさせる。