Arduinoで割り込みISR()を使うコード例(1)ボタン押下監視を割り込みで
Arduinoでタクトスイッチの押下を監視したいのですが、一回のloopが長い場合、degitalread(polling)の丁度いいタイミングでスイッチを押さないといけなかったりします。先日作ったドラムマシンが一回のループが長い典型例(1秒越え)でした。
そこでInterruptというのを使うと、メインのループに割り込んだ操作が行えるようなのでサンプルコード試してみました。あまり私にとって分りやすい情報が多くなく、現時点では仕組みをあまり理解しておりませんが、動いたので記しておきます。
Arduino側の配線
9pin、13pinにLEDを接続、2pinにタクトスイッチを接続しています。
コードと動作
こちらのコードを一部改変しました。メインのloop内ではLEDが500ms周期で明滅します。一方でISR(INT0_vect)という関数?が定義されており、メインループとは独立にボタンが押された瞬間に実行されます。ISRが実行された場合13pin(ledPin_ISR)のON/OFFが切り替わり、ついでにCHANNEL=1が代入されます。
#include <avr/io.h> #include <avr/interrupt.h> byte ledPin = 9; byte ledPin_ISR = 13; byte BUTTON = 2; boolean CHANNEL =0; void setup(void) { Serial.begin( 9600 ); pinMode(BUTTON, INPUT); digitalWrite(BUTTON, HIGH); // Enable pullup resistor pinMode(ledPin_ISR, OUTPUT); digitalWrite(ledPin_ISR, LOW); EICRA |= (1 << ISC01); // Trigger on falling edge EIMSK |= (1 << INT0); // Enable external interrupt INT0 sei(); // Enable global interrupts } // Interrupt Service Routine attached to INT0 vector ISR(INT0_vect) { digitalWrite(ledPin_ISR, !digitalRead(ledPin_ISR)); // Toggle LED on pin 13 CHANNEL = 1; Serial.println("Interrupted!"); } void loop(void) { analogWrite(ledPin, 30); delay(500); analogWrite(ledPin, 255); delay(500); Serial.println(CHANNEL); CHANNEL=0; }
疑問と調べたこと
このコードの中で、どの部分が2pinをISRの実行トリガーに指定しているのか調べてみました。怪しい部分は以下の部分です。
EICRA |= (1 << ISC01); // Trigger on falling edge EIMSK |= (1 << INT0); // Enable external interrupt INT0 sei(); // Enable global interrupts
ググってみたところ、
こちらのサイトにて説明が見つかりました。とりあえず2pinと3pinが使用可能なようですね。
課題
・複数ボタンを監視したい場合の方法が分からない。
・アナログピンでも使えるのかな?