複数の電子部品を異なるタイミングで制御

複数の電子部品を、delay関数を使用せずにタイミング制御する方法の解説動画です。

目次

【考え方】1個のLEDをdelay関数を使用せずにタイミング制御

基本的な考え方を確認するために、delay関数を使用せずに、1秒ごとにON/OFF制御するスケッチを確認します。

制御ポイント

次の動作をする点がこの制御方法のポイントです!

  • 前回制御した時刻からからどれぐらい時間が経過しているか調べる
  • その結果、1秒経過していなければ何もせず、1秒経過していたらLEDのON/OFF制御をする

これをスケッチにすると次のようになります。

/*
    1個のLEDをmillis関数で1秒ごとにON/OFF制御するスケッチ
*/

// LEDの接続ピン
#define RED_LED 12

// 前回制御時刻を保存しておく変数
unsigned long zenkai  = 0;

void setup() {
  // LED接続ピンの出力設定
  pinMode(RED_LED,  OUTPUT);
}

void loop() {
  // 今回の制御時刻
  unsigned long konkai = millis();

  // LEDの制御
  if( konkai - zenkai >= 1000 ) {
    digitalWrite(RED_LED, !digitalRead(RED_LED));
    zenkai = konkai;
  }

}

【基本形】2個のLEDをdelay関数を使用せずにタイミング制御

1個のLEDを制御するスケッチをベースにすると、簡単に電子部品を追加制御することができます。

次のスケッチは,1個のLEDの制御と同じようにもう1個のLED制御を追加したものです。

ポイント

複数の電子部品を制御する場合、「前回制御した時刻」はそれぞれの電子部品ごとに覚えておく必要があります。

「前回制御した時刻」はそれぞれの電子部品ごとに変数を用意する点がポイントになります

/*
    2個のLEDをmillis関数で1秒ごとにON/OFF制御するスケッチ
*/

// LEDの接続ピン
#define RED_LED  12
#define GREEN_LED 4

// 前回制御時刻を保存しておく変数
unsigned long zenkai_aka    = 0;
unsigned long zenkai_midori = 0;

void setup() {
  // LED接続ピンの出力設定
  pinMode(RED_LED,  OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
}

void loop() {
  // 今回の制御時刻
  unsigned long konkai = millis();

  // 赤色LEDの制御
  if( konkai - zenkai_aka >= 2000 ) {
    digitalWrite(RED_LED, !digitalRead(RED_LED));
    zenkai_aka = konkai;
  }

  // 緑色LEDの制御
  if( konkai - zenkai_midori >= 700 ) {
    digitalWrite(GREEN_LED, !digitalRead(GREEN_LED));
    zenkai_midori = konkai;
  }

}

【注意点】サーボモーター制御を追加

上のスケッチに、サーボモーター制御を追加します。

次のようなスケッチで、「0度から60度まで1度30msで回転」➡︎ 「60度から0度まで1度30msで回転」という制御をします。

for( int angle=0; angle<=60; angle++ ) {
  servo.write(angle);
  delay(30);
}

for( int angle=60; angle>=0; angle-- ) {
  servo.write(angle);
  delay(30);
}

この制御コードを2個のLEDを制御するスケッチに追加します。

/*
  2個のLEDとサーボモーターを
  millis関数で1秒ごとにON/OFF制御するスケッチ
*/

// サーボモーターのライブラリインクルードとオブジェクト生成
#include <Servo.h>
Servo servo;

// LEDの接続ピン
#define RED_LED  12
#define GREEN_LED 4

// サーボモーター信号線接続ピン
#define SERVO_PIN 6

// 前回制御時刻を保存しておく変数
unsigned long zenkai_aka    = 0;
unsigned long zenkai_midori = 0;
unsigned long zenkai_servo  = 0;

void setup() {
  // LED接続ピンの出力設定
  pinMode(RED_LED,  OUTPUT);
  pinMode(GREEN_LED, OUTPUT);

  // サーボモーター制御ピン設定
  servo.attach(SERVO_PIN);

  // サーボモーターを0度位置に回転
  servo.write(0);
}

void loop() {
  // 今回の制御時刻
  unsigned long konkai = millis();

  // 赤色LEDの制御
  if( konkai - zenkai_aka >= 1000 ) {
    digitalWrite(RED_LED, !digitalRead(RED_LED));
    zenkai_aka = konkai;
  }

  // 緑色LEDの制御
  if( konkai - zenkai_midori >= 500 ) {
    digitalWrite(GREEN_LED, !digitalRead(GREEN_LED));
    zenkai_midori = konkai;
  }

  // サーボモーターの制御
  if( konkai - zenkai_servo >= 5000 ) {
    for( int angle=0; angle<=60; angle++ ) {
      servo.write(angle);
      delay(30);
    }
    for( int angle=60; angle>=0; angle-- ) {
      servo.write(angle);
      delay(30);
    }
    zenkai_servo = konkai;
  }
}

このスケッチを実行すると残念ながらうまく制御できません。(動作の様子は動画をご確認ください)

サーボモーター制御中はLED制御が止まってしまいます。

理由は、if文内のサーボモーター制御が合計3.6秒間かかってしまい、この間、LEDの制御ができなくなるためです。


スケッチを工夫すればこの問題を回避できますが、かなり複雑になってしまいます。

そのようなときは「リアルタイムOS」を利用するとうまく制御できます。

リアルタイムOSは別の記事で詳しく解説予定です。

テンプレートスケッチ

複数の電子部品を異なるタイミングで制御する場合、millis関数を使うと見やすく変更しやすいスケッチが作成できます。

次のスケッチは、3個の電子部品を制御するテンプレートです。

/*
  3個の電子部品を異なるタイミングで制御するテンプレート
*/

// 電子部品制御に必要なライブラリがあればここでインクルードします
// 例
// #include <Servo.h>  // サーボモーターのライブラリ

// 電子部品のオブジェクト生成が必要な場合、ここで生成します
// 例
// Servo servo;

// その他必要な定義があればここに書きます
// 例
// #define RED_LED  12 // LEDの接続ピン
// const int servo_pin = 6;  // サーボモーターの接続ピン

// それぞれの電子部品制御の時間間隔 (単位:ms)
#define kankaku_1 1000  // 1つ目の電子部品
#define kankaku_2  700  // 2つ目の電子部品
#define kankaku_3 3500  // 3つ目の電子部品

// 前回制御時刻を保存しておく変数
unsigned long zenkai_1 = 0;
unsigned long zenkai_2 = 0;
unsigned long zenkai_3 = 0;

void setup() {
  // ピンの設定などが必要であればここに書きます
  // 例
  // pinMode(RED_LED, OUTPUT);
}

void loop() {
  // 今回の制御時刻
  unsigned long konkai = millis();

  // 電子部品1の制御
  if( konkai - zenkai_1 >= kankaku_1 ) {
    // ここに1つ目の電子部品の制御コードを書きます
    // 例
    // digitalWrite(RED_LED, !digitalRead(RED_LED));
    zenkai_1 = konkai;
  }

  // 電子部品2の制御
  if( konkai - zenkai_2 >= kankaku_2 ) {
    // ここに1つ目の電子部品の制御コードを書きます
    zenkai_2 = konkai;
  }

  // 電子部品3の制御
  if( konkai - zenkai_3 >= kankaku_3 ) {
    // ここに3つ目の電子部品の制御コードを書きます
    zenkai_3 = konkai;
  }

}


更新履歴

日付内容
2025.8.28新規投稿
通知の設定
通知タイミング
guest
0 コメント
新しい準
古い順 一番投票が多い
本文中にフィードバック
全てのコメントを見る
目次