goo blog サービス終了のお知らせ 

酒と薔薇の日々(その2)

好きなことだけ求めて生きるアスペ気味のINTJ人

並行動作試験1 1秒ごとのLED点滅

2023年09月07日 16時22分03秒 | マイコン(ESP32・Arduino等)

まずは、LEDだけを1秒ごと交互点滅させるプログラム

起動後の時間を監視し10秒ごとにフェーズを0..と遷移し、フェーズ1,2の場合のみ交互点滅する。
久しぶりにマジで書いてみた。

=========================

/*
    踏切模型の並行動作テスト
    LEDを1秒おきに左右交互に点滅させる
      getPhase()関数内で経過時間から現在のフェーズを0..2値で取得し、
      フェーズに従ってLEDLEDを交互点灯させる
      フェーズ2を超えるとフェーズ0になり、交互点灯動作は終了する
    2023/9/7
*/
#define wl_R   4 // 警告灯 右
#define wl_L   5 // 警告灯 左
#define ss_R  12 // 列車センサー 右
#define servoPin  9 // サーボpin
const int intervalLED = 1000; // LED点滅間隔

#include "Servo.h" 
Servo servo;  // MyServo生成
unsigned long startT = millis();   //  開始時間記録
int phase = 0;    //  現在のフェーズを与える 0:待機 1:LED点滅期 2:LED点灯期
//unsigned long ms = 0;      // SW押下からの時間 MS
bool warnLedOn = false; // 警告灯点滅期間フラグ
bool servoDwOn = false; // サーボ下降フラグ
int wlCnt = 0;  // 警告LEDが点灯した回数

// SW押されるの待つ
void waitSwitch(){
  while (digitalRead(ss_R) == HIGH){  //スイッチが押されるまで待つ
    digitalWrite(wl_R, HIGH);
    delay(200);
    digitalWrite(wl_R, LOW);
    delay(200);
  }
}

void setup() {
  pinMode(wl_R,OUTPUT);
  pinMode(wl_L,OUTPUT);
  pinMode(ss_R,INPUT_PULLUP);   // スイッチをPullUPで使用
  servo.attach(servoPin);
  servo.write(90);              // バー直立
  //waitSwitch();                 // SW押されるの待つ
  digitalWrite(wl_R, LOW);
  digitalWrite(wl_L, LOW);

  Serial.begin(9600);
  Serial.print('start at ');
  Serial.println(startT);
}

void getPhase(){  //  現在のフェーズを判定する
  unsigned long pastT = millis() - startT; //  開始からの時刻を得る
  if (pastT <= 10*1000){
    phase = 0;
    warnLedOn = false;
    servoDwOn = false;
    return;
  }
  if (pastT <= 20*1000){
    phase = 1;
    warnLedOn = true;
    servoDwOn = false;
    return;
  }
  if (pastT <= 30*1000){
    phase = 2;
    warnLedOn = true;
    servoDwOn = true;
    return;
  }
  phase = 0;
  warnLedOn = false;
  servoDwOn = false;
}

void dbg(){
  Serial.print(millis());
  Serial.print("  Phase:");
  Serial.print(phase);
  Serial.print("  LEd:");
  Serial.print(warnLedOn);
  Serial.print("  Servo:");
  Serial.print(servoDwOn);
  Serial.print("  wlCnt:");
  Serial.print(wlCnt);
  Serial.println("");
}

// warnLedOn=trueの間 警告LEDを交互点滅させる
void do_LED(){
  static unsigned long lastT = 0;  // 最後の点滅交代時刻をstaticで記録
  unsigned long nowT = millis();       // 現在時刻取得
  if (!warnLedOn){                // warnLedOn=True時のみLEDを点灯させる
     digitalWrite(wl_R, LOW);
     digitalWrite(wl_L, LOW);
     wlCnt = 0;                   // 消灯時は点滅回数を0にしておかないと交互表示ができない
     return;
  }
  if (nowT - lastT >= intervalLED){  //  1秒ごとに値を反転させる
    lastT = nowT;  
    digitalWrite(wl_R, ! digitalRead(wl_R));  
    digitalWrite(wl_L, ! digitalRead(wl_L));
  }
  wlCnt = wlCnt + 1;
}

//  点滅開始時に交互表示状態を作っておく   
void start_LED(){
  digitalWrite(wl_R, HIGH);
  digitalWrite(wl_L, LOW);
  wlCnt = 1;
}

void loop() {
  getPhase();
  if ((wlCnt == 0) && (phase == 1)){
    Serial.println("start_LED()");
    start_LED();    //  点滅開始時に一回だけ交互表示状態を作っておく
  } 
  dbg();
  do_LED();
  delay(1000);
}

 

この記事についてブログを書く
« 踏切模型のテスト | トップ | 並行動作試験2 サーボ »