今回はスイッチ応用編です。
過去にも取り上げたことがありましたが、改めて紹介します。
スイッチ変化の捉え方
スイッチからの信号変化の捉え方はいくつかあると思います。
- pinMode()をINPUTにしてdigitalRead()で取り込む
- 割り込み関数で状態管理する
1.についてはこれまで行ってきた内容です。テキストや過去の記事を読んで復習してください。
2.についてはテキストに事例がなかったので、改めて確認します。
ソースコードは過去記事から引用します。
// Pin 10 has an LED connected on Bread boards. // give it a name: int led = 10; int mode = 0; // the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output. pinMode(led, OUTPUT); // 割り込み関数の登録 // 割り込み番号:0 // 割り込み関数:interruptsw // 割り込み発生条件:信号立上り attachInterrupt(0, interruptsw, CHANGE); } // the loop routine runs over and over again forever: void loop() { if(mode==0){ // modeが1だったら digitalWrite(led, LOW); // turn the LED on (HIGH is the voltage level) delay(500); // wait for a second digitalWrite(led, HIGH); // turn the LED off by making the voltage LOW delay(500); // wait for a second }else{ // modeが0だったら digitalWrite(led, HIGH); } } // 割り込み処理 void interruptsw() { if(mode){ mode = 0; }else{ mode = 1; } }
これまでは直接ピンの状態を監視していましたが、今回は割り込み処理を利用して状態を監視しています。
割り込み処理には「LOW(0V)」「HIGH」といった信号レベル(ただしHIGHはDueのみ)、「CHANGE」「RISING」「FALLING」といった信号変化を検知することができます。
1つの信号に1つの割り込みしか登録できませんから「CHANGE」にて信号の立上り、立下りを検知することにします(ソースコード中の16行目です)。
一方で割込みが発生したときの処理ですが、動作モードを切り替えるようにします(ソースコード中の34~41)。
初期値が0に規定していますから、最初の変化(押す)でモードが1に変わり、次の変化(離す)でモードが0に戻ります。
実際の動作を見てみましょう。
通常状態ではLEDが点滅している状況(モード0)で、スイッチを押下すると(モード1)LEDが消灯します。またスイッチを離すと元の状況(モード0)に戻り、LEDが点滅します。
loop()内は繰り返し動作する関数ですが、呼び出されるタイミングは不定期です(人の時間軸からみると十分にリアルタイム性はあると思います)。イベントが起きたら(イベント駆動→イベントドリブン)○○を行うと規定した方がスッキリすることもありますので、割込みの使い方は知っておいて損はないと思います。