怠惰になるために本気出す

電子工作で色々作ってます

Atmega328P(ArduinoUno)でピン変化割り込みを使用

Arduinoには便利な外部割込み関数が用意されていてピンの状況に応じて外部割込みができるため非常に便利です。
nobita-rx7.hatenablog.com


が、ArduinoUnoでこの関数を利用する場合ピン2(INT0)・ピン3(INT1)の2ピンしか使用することができずまたピンも固定のため意外と汎用性が低いため使い方によってはピンの配置やソフト面で頑張らないといけないのではないでしょうか。

ピン変化による外部割込み

外部割込みを行う方法がこれが全てではなくピン2,3以外でも外部割込みを行う方法もあり、この方法を用いて外部割込みを行ってみます。
zenn.dev

ソフト

参考にしたサイトでは常時外部割込みを行える状態になっていますがこれだとボタンを押した瞬間に外部割込みが発生しますが、今回は任意のタイミングのみ外部割込みを行いそれ以外の時は外部割込みを無効にするようにしました。

int Pin1 = 5;
int Pin2 = 6;
int LED_PIN = 4;
int ISR_Called = 0;
int OUT_Pin = 10;

void setup() {
  // 結果を表示する用のLEDのピンを設定します
  pinMode(LED_PIN, OUTPUT);
  pinMode(OUT_Pin, OUTPUT);
  pinMode(Pin1, INPUT);
  pinMode(Pin2, INPUT);
  Serial.begin(9600); 
  Serial.println("-- Sleep Test Start --");
}

void loop() {
  // D5, D6ピンの割り込みを有効にします
  PCICR |= B00000100;
  PCMSK2 |= B01100000;
  digitalWrite(OUT_Pin, HIGH);
  if(ISR_Called > 0){
      if(digitalRead(Pin1) == HIGH){
      digitalWrite(LED_PIN, HIGH);
      delay(1000);
      digitalWrite(LED_PIN, LOW);
    }else if(digitalRead(Pin2) == HIGH){
      digitalWrite(LED_PIN, HIGH);
      delay(5000);
      digitalWrite(LED_PIN, LOW);
    }
    ISR_Called = 0;
  }
}

// D5, D6いずれかに割り込み(CHANGE)が発生したときに呼ばれる関数
ISR(PCINT2_vect){
  Serial.println("Interrupt");
  ISR_Called = 1;
  // D5, D6ピンの割り込みを無効にします
  PCICR=0;
  PCMSK2=0;
}

まとめ

この外部割込みの方法は関数を利用する場合と異なり立ち上がりや立下りなどの細かい設定を行うことができずピンが変化した場合のみ外部割込みを行います。
しかし指定したピン以外で外部割込みを使えるのはかなり便利なので今後も重宝したいところです。