とりあえずやりたいことは出来たようなので余計なことを言うと、
-1よりも心配しなきゃいけないことが一杯ある気がします。
aなんていう変数名じゃなくて意味のある名前を使うこととか、
2つしか状態がないのならif()~else~で処理すべきじゃないかとか
似た処理をふたつならべることの是非とか
チャタリングへの対応とか
a=a*(-1);
なんてことさえしなければ、小学生だって単純な負の数ぐらい聞きかじっているでしょうし
(そもそも私だったら割り込み使わないなぁ)
コメント頂きました。
今回想定しているのが、
①delayを使ってLEDの点滅を制御。歩行者信号機で、青点灯→点滅→赤 のような感じです。
②スイッチが押されたら、①の青点灯のdelayを待たずに割り込んで、点滅→赤
のようなプログラムなのですが、割り込みを使わないでできる方法があれば、教えてくださいませ。
とのことですので、サンプルを書きました。青点灯10秒->青点滅5秒->赤点灯10秒を繰り返します。それぞれの途中でボタンSWを押す(ピン-GND間短絡)と、時間を待たずに次の状態に遷移します。割り込みは使っていません。
Arduino
1const int BUTTON = 10;//ピンアサインは私の環境に合わせています。適宜変更して下さい
2const int GREEN = 2;
3const int RED = 3;
4
5const int DLY_UNIT = 10;//1ループの時間(ミリ秒)
6const int PERIOD_GREEN = 10 * 1000 / DLY_UNIT;//緑点灯期間(DLY_UNIT単位)
7const int PERIOD_BLINK = 5 * 1000 / DLY_UNIT;//緑点滅期間
8const int PERIOD_RED = 10 * 1000 / DLY_UNIT;//赤点灯期間
9const int BLINK_CYCLE = 0.5 * 1000 / DLY_UNIT;//緑点滅周期
10int count = 0; //時間を計るための変数
11const int CHATFILTER = 100 / DLY_UNIT; //チャタリング除去時間
12bool buttonHistory[CHATFILTER];//チャタリング除去のための履歴
13
14enum STATUS { //LED状態変数
15 STAT_GREEN,
16 STAT_BLINK,
17 STAT_RED
18} stat;
19
20void setup() {
21 for (int i = 0; i < CHATFILTER; i++) {
22 buttonHistory[i] = true;
23 }
24 pinMode(GREEN, OUTPUT);
25 pinMode(RED, OUTPUT);
26 pinMode(BUTTON, INPUT_PULLUP);
27 stat = STAT_GREEN;
28 Serial.begin(115200);
29}
30
31bool checkButtonOn() {//ボタンが「押された」ことを検出する
32 static bool prevButton = true;
33 bool currentButton = true;
34 bool isButtonStable = true;
35 bool ret = false;
36 currentButton = digitalRead(BUTTON);
37 for (int i = 1; i < CHATFILTER; i++) {
38 if (currentButton != buttonHistory[i - 1]) {
39 isButtonStable = false;
40 }
41 buttonHistory[i] = buttonHistory[i - 1];
42 }
43 buttonHistory[0] = currentButton;
44 if (isButtonStable) {
45 ret = prevButton != currentButton && prevButton;
46 prevButton = currentButton;
47 }
48 return ret;
49}
50
51void loop() {
52 bool green = false;
53 bool red = false;
54 bool isButtonTurnedOn = checkButtonOn();
55 Serial.println(isButtonTurnedOn);
56 switch (stat) {//状態によって動作を振り分ける
57 case STAT_GREEN:
58 green = true;//緑の点灯処理
59 if (count > PERIOD_GREEN || isButtonTurnedOn) {//次に遷移する条件
60 count = 0;//時間クリア
61 stat = STAT_BLINK;//次の状態へ
62 }
63 break;
64 case STAT_BLINK:
65 green = (count / BLINK_CYCLE) & 1;
66 if (count > PERIOD_BLINK || isButtonTurnedOn) {
67 count = 0;
68 stat = STAT_RED;
69 }
70 break;
71 case STAT_RED:
72 red = true;
73 if (count > PERIOD_RED || isButtonTurnedOn) {
74 count = 0;
75 stat = STAT_GREEN;
76 }
77 break;
78 default:
79 stat = STAT_GREEN;
80 }
81 digitalWrite(RED, red);
82 digitalWrite(GREEN, green);
83 delay(DLY_UNIT);
84 count++;
85}
この程度のプログラムの場合、割り込みを使う使わないは本質ではありません。なんなら、ボタンの検出部分を割り込みを使ったものに置き換えるのも大した手間ではないでしょう。
要は、長時間のdelay()がプログラムの動作を阻害するので、それを短時間のdelay()の繰り返しに置き換えてやる、ということです。あるいは、細切れのdelay()ではなくmillis()を使って時間を計ってもいいですけれど、とにかく長時間のdelay()を使わないことですね。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/27 23:25
2020/03/28 00:01