GPIOInterrupt

はじめに

デジタルピンの入力で割り込みを発生させ、事前に登録した関数を呼び出します。

プログラム

定義等

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <Arduino.h>

struct Button {
    const uint8_t PIN;
    uint32_t numberKeyPresses;
    bool pressed;
};

Button button1 = {23, 0, false};
Button button2 = {18, 0, false};
 

struct Button は、ピン番号と割り込みが発生した回数、ピンの状態(押されているかどうか)を表す構造体です。

button1とbutton2は、23番ピンと18番ピン用の変数です。

isr()

12
13
14
15
16
17
18
19
20
21
22
void ARDUINO_ISR_ATTR isr(void* arg) {
    Button* s = static_cast<Button*>(arg);
    s->numberKeyPresses += 1;
    s->pressed = true;
}

void ARDUINO_ISR_ATTR isr() {
    button2.numberKeyPresses += 1;
    button2.pressed = true;
}
 

上記の関数はそれぞれ、GPIOに変化があった時に呼び出される関数です。

最初のisr()は、引数を持っていて、引数で指定された変数を操作します。

2番目のisr()は、button2を操作します。

関数が呼ばれると、numberKeyPressesをインクリメントし、pressedをtrueにします。

ARDUINO_ISR_ATTR属性を付けることで、このコードがIRAM(Instruction RAM)に配置されるようにしています。esp32では、割り込みハンドラはIRAMに配置する必要があるようです。

ARDUINO_ISR_ATTRは、esp32-hal.hで、定義されています。

setup()

23
24
25
26
27
28
29
30
void setup() {
    Serial.begin(115200);
    pinMode(button1.PIN, INPUT_PULLUP);
    attachInterruptArg(button1.PIN, isr, &button1, FALLING);
    pinMode(button2.PIN, INPUT_PULLUP);
    attachInterrupt(button2.PIN, isr, FALLING);
}
 

pinMode()で、button1.PINとbutton2.PINをINPUT_PULLUPに設定します。

attachInterrupt()を用いて、割り込みハンドラを登録します。button1は、引数ありのisr()を、button2は、引数なしのisr()を登録しています。

attachInterrupt()は、ESP32向けに、少し、拡張されています。

loop()

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void loop() {
    if (button1.pressed) {
        Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
        button1.pressed = false;
    }
    if (button2.pressed) {
        Serial.printf("Button 2 has been pressed %u times\n", button2.numberKeyPresses);
        button2.pressed = false;
    }
    static uint32_t lastMillis = 0;
    if (millis() - lastMillis > 10000) {
      lastMillis = millis();
      detachInterrupt(button1.PIN);
    }
}

ボタンが押されていれば(pressedがtrue)であれば、シリアルコンソールに押された回数を表示して、pressedをfalseに設定します。

最初のloop()の実行から10秒以上経過した場合は、detachInterrupt()を使ってbutton1の割り込みを解除します。

なお、このプログラムを試してみたところ、button1に割り込みを発生させても、何も表示されませんでした。私の勘違いかもしれませんが。

バージョン

Hardware:ESP-WROOM-32
Software:Arduino core for the ESP32 2.0.4

最終更新日

September 4, 2022

inserted by FC2 system