LEDの点滅 – プログラム例2

プログラム例2

#include <Arduino.h> // Arduino.h の読み込み

/*
 * setup 関数
 */
void setup() {
  /* ここにプログラムの最初に1回だけ実行したい処理を上から順に記述していきます */

  // シリアル通信を115200bpsで開始
  Serial.begin(115200);

  Serial.println("初期設定の開始");

  // 入出力設定(アノード)
  pinMode(0, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
  pinMode(18, OUTPUT);
  pinMode(19, OUTPUT);
  // 入出力設定(カソード)
  pinMode(21, OUTPUT);
  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT);
  pinMode(25, OUTPUT);
  pinMode(26, OUTPUT);
  pinMode(27, OUTPUT);
  pinMode(32, OUTPUT);
  pinMode(33, OUTPUT);

  // 出力レベル設定(アノード)
  digitalWrite(0, LOW);
  digitalWrite(2, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(16, LOW);
  digitalWrite(17, LOW);
  digitalWrite(18, LOW);
  digitalWrite(19, LOW);
  // 出力レベル設定(カソード)
  digitalWrite(21, LOW);
  digitalWrite(22, HIGH);
  digitalWrite(23, HIGH);
  digitalWrite(25, HIGH);
  digitalWrite(26, HIGH);
  digitalWrite(27, HIGH);
  digitalWrite(32, HIGH);
  digitalWrite(33, HIGH);

  Serial.println("初期設定の完了");
}

Code language: Arduino (arduino)
/*
 * loop 関数
 */
void loop() {
  /* ここにプログラム中で繰り返し実行したい処理を上から順に記述していきます */

  digitalWrite(0, HIGH); // LEDを点灯
  delay(1000);           // 待ち時間

  digitalWrite(0, LOW);  // LEDを消灯
  delay(1000);           // 待ち時間
}
Code language: Arduino (arduino)

ドットマトリクスLEDは、点滅しているように見えましたか?


delay関数の役割

この STEP で出てきた時間待ち関数「delay」は、単なる時間待ちを行うためだけの関数ではなく、実は、ESP32 でプログラムを動かす上で重要な役割を持っている関数です。

ESP32 の開発フレームワークでは、マイコンには FreeRTOS という OS(オペレーティング・システム)がインストールされ、ユーザの作成したプログラムは OS 上のタスクとして動いています。マイコンは、ユーザの作成したプログラムの他に、背後で動いている OS 関連のタスクも実行する必要があるのですが、実は delay 関数は単なる時間待ち関数ではなく「今は時間待ちを行っているので、他のタスクに集中して良いですよ」ということを OS に伝える役割も持っています。

そのため、loop 関数の中では、原則として delay 関数での時間待ちが行われるようにしておくことが望ましいです。

loop 関数内に delay による時間待ちが無い場合、以下のような問題が生じます。

  • loop 関数が極めて高頻度で実行されることになり、それだけ OS に負荷がかかって無駄な電力消費が増える(実測では,delay が無いとおおよそ 25mA ほど消費電流が増えるようです)。
  • 背後で動いている OS 関連のタスクを実行する時間が適切に確保されず、プログラムによっては動作がおかしくなることがある。

このような問題を回避するために、特に事情が無ければ loop 関数内には「delay(1)」を入れておくと良いでしょう。記述は loop 関数内のどこでも構いませんが、フローチャート上 delay 関数が実行されないままプログラムが回り続けるのを避けるようにする必要があります。

以下は「何もしない」loop 関数に delay(1) を加えた例です。

void loop() {
  /* ここにプログラム中で繰り返し実行したい処理を上から順に記述していきます */

  delay(1); // 時間待ち
}Code language: JavaScript (javascript)

なお、delay 関数の時間待ちが長ければ長いほど、原理的には消費電力も減ることになりますが、例えば上記コードで delay(1) を delay(1000) にした場合でも、消費電流の違いはせいぜい 1mA 程度です。

前の記事

マイコンのクロック周波数