Arduinoにおける割り込み処理
割込みはスイッチ、ロータリエンコーダなどの読み取りや、外部入力信号の監視などで使用され、
非同期タイミングの問題を解決してくれる。
割込みを使わずにロータリエンコーダからのパルスを漏らさず受け取ろうとすると、
入力を監視するために面倒な処理が必要となるが、
割込みを使えば他の処理を実行しながら突然発生するイベントの処理を行うことができる。
Arduino割込み使用方法
(引用:http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=3069)
Arduinoの割込みは、void setup
でattachInterrupt
により割込みを指定する。
attachInterrupt(digitalPinToInterrupt(interruptPin), toggleLED, CHANGE);
( )内は順番に、割込みピン、割込み処理関数、割込み条件
割り込みパラメータは以下の通りである:
- interrupt: 割込み番号
- function: 割込み発生時に呼び出す関数
- mode: 割込みを発生させるトリガ
- LOW ピンがLOWのとき発生
- CHANGE ピンの状態が変化したときに発生
- RISING ピンの状態がLOWからHIGHに変わったときに発生
- FALLING ピンの状態がHIGHからLOWに変わったときに発生
Arduino割込み入力はデジタルピンが使用されるが、ボード種類により使用可能なデジタルピンが異なる。
Arduino UNOではデジタルピンの2ピンと3ピンが割込みに使用できる。
このattachInterrupt
関数のパラメータとしてピン番号ではなく割込み番号を必要とする。
たとえば、Unoのピン2は割込み番号0(int0)であり、2ではなく0が正しいパラメータである。
そこで、digitalPinToInterrupt(pin)
という専用の関数を使用するとピン番号を割込み番号に変換してくれる。
さらに以下の点にも留意する。
- 割込みは通常処理を中断して行うため、割込み処理関数は簡潔な処理にとどめる。
- 割込み関数での引数や出力はグローバル変数を使用し、変数定義にてvolatileをつけて宣言する。
- delay関数は機能せず、またmillis関数の戻り値は増加しない。
- シリアル通信により受信したデータは失われ可能性がある。
Arduino割り込みの利用例
Arduino UNOのデジタル2ピンに接続されたプッシュスイッチ状態変化で割込みが発生しLEDを点滅させる回路(図1)とスケッチ(リスト1)を示す。
プッシュスイッチと並列接続された0.1uFキャパシタはチャタリング防止用である。
スケッチでは、プッシュスイッチの立上りと立下り変化(CHANGE)で割込みを発生。
割込みピンはArduino UNO使用でデジタルピンのD2を使用。
割込みルーチン(関数)で使用する変数stateはvolatile int state = LOW;
で宣言している。

リスト1
//割込みテストLED点滅スケッチ
int ledPin = 13; //LED接続デジタルピン
int interruptPin = 2; //割込みデジタルピン
volatile int state = LOW; // 割込み関数で使用する変数でvolatileをつけて宣言
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT);
//割込みコマンド、立上と立下変化で割込み
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
// 割込みルーチン
void blink() {
state = !state; //割込み立上りと立下り変化で反転
}
数十個のスイッチ処理に割込み使用
別項で紹介したArduinoアナログ入力1chで数十個のプッシュスイッチ状態を認識するスケッチで、
スイッチが押されたことを割込みにて処理する応用例を紹介する。
押されたスイッチがAnalogReadで電圧測定値で決定される回路であるが、
いずれのスイッチも押されていない時は+5Vが測定されるため、
図2に示す様に、アナログコンパレータを追加して、割込み入力とする。
スイッチが押されていないと出力はLo,いずれかのスイッチが押されると出力がHiとなり、
割込みが発生する。コンパレータ入力の10kΩと0.1uFはプッシュスイッチのチャタリング防止用である。
リスト2がこのスケッチである。

リスト2
//割込みテストスケッチ
volatile int swdata; //pushされたSWのADC readコード
int swon=0;//SW pushフラッグ
void swpush() { //SW on割込み処理
swon=1; //SW pushフラッグ ON
swdata=analogRead(0);
}
void setup() {
Serial.begin(9600);
attachInterrupt(0, swpush, RISING); //DIGITAL Pin 2: Interrupt 0
}
void loop() {
if(swon==1){
swon=0;
Serial.println(swdata);
}
}