非公式Rock研究所

Radxaのシングルボード(主にRock4c+)について書いています

Debounce on a Pushbutton-デバウンス対応

注意:当サイトに掲載されている手順は動作を保証するものではないもの、また、当サイトに掲載されている情報をもとに電子回路を作成した結果によって生じたことについて、一切の責任を負えないことをご了承ください。

【Article】「GPIOページに掲載する記事について」 - 非公式Rock研究所
https://informal-r-labo.net/posts/article005



Debounce on a Pushbutton-デバウンス対応

ここではデバウンスに対応したコーディングで、ボタンの押下を正確に読み取り、LEDの点灯を制御する。

Arduino Built-in

この記事の元ネタである、ArduinoのBuilt-inのページリンク

Debounce on a Pushbutton | Arduino Documentation
https://docs.arduino.cc/built-in-examples/digital/Debounce/

デバウンス(Debounce)とは

あまり聞きなれない単語であるが、英単語の検索サイトである英辞郎の訳語がしっくり来たので参考で掲載しておく。

debounceの意味・使い方|英辞郎 on the WEB
https://eow.alc.co.jp/search?q=debounce

ボタンスイッチを押下したとき、押し始めと押し終わりの端子が触れるぎりぎりの状態では、端子は短い時間で細かく何度も接触しており、高速でスイッチが連打されているのと同じ状態になる。デバウンス対応していないと、その接触を個々に読み取り、1回のボタン押下でも、デバイスは複数回押下されたと認識されてしまう。

イメージがわかなければ一度、デバウンスなしでボタンスイッチのプログラムを作成するとよいだろう。

【Article】「Non Debounce on a Pushbutton-No Debounce, No Life.」 - 非公式Rock研究所
https://informal-r-labo.net/posts/article008

回路図

ボタンと連動するLEDの回路図は以下のようになる。

-デバウンス対応の回路図

図は電子部品を接続するためにブレッドボードを使用している。電気部品の端子を接続するため、接続を中継する線(黄色)を使用している。

Pythonコード

~/pyディレクトリに"Debounce_sw.py"のファイル名でviを起動し、編集モードで以下のコードを入力する。
(Rock4c+には日本語が入力できないため、カッコ書きのコメント行は入力不要。)

# (ライブラリのimport)
import mraa
import time

# (SW Pin8を操作対象にして、mr.DIR_OUT_LOWで"LOW"状態に初期化)
gpio_sw = mraa.Gpio(8)
gpio_sw.dir(mraa.DIR_OUT_LOW)

# (反映に少しタイムラグがあるので、1秒ほど待機)
time.sleep(1)

# (gpioをmraa.DIR_INで読み取りに変更)
gpio_sw.dir(mraa.DIR_IN)

# (LED Pin13を操作対象にして、mr.DIR_OUTで"出力"に設定)
gpio_led = mraa.Gpio(13)
gpio_led.dir(mraa.DIR_OUT)

# (SWのステータス変数の初期化)
buttonState = 0
lastbuttonState = 0

# (LEDのステータス変数の初期化)
ledState = 0
gpio_led.write(ledState)

# (Debounceの開始時間変数の初期化)
lastDebounceTime = 0

while True:
    # (スイッチの状態を読み取り)
    reading = gpio_sw.read()
    # (開始時ステータスとスイッチの状態が変化したとき)
    if reading != lastbuttonState:
        # (変化時の時間を記録)
        lastDebounceTime = time.time()
    # (0.05秒後)
    if time.time() - lastDebounceTime > 0.05:
        # (終了時ステータスとスイッチの状態が異なっていれば)
        if reading != buttonState:
            # (終了ステータスをスイッチの状態に変更)
            buttonState = reading
             # (スイッチの状態が【押す】だったとき)
            if buttonState == 1:
                # (LEDの点灯を切り替える)
                ledState = int(not bool(ledState))
                gpio_led.write(ledState)
    # (開始時ステータスを今の状態に更新)
    lastbuttonState = reading

コーディングが完了すれば保存する。

紹介したPythonコードについて参考にしたサイトのリンクを貼っておく。

Debounce on a Pushbutton | Arduino Documentation
https://docs.arduino.cc/built-in-examples/digital/Debounce/

【Python】処理時間を3行のコードで取得する方法|time | Smart-Hint
https://smart-hint.com/python/time-dif/

Pythonの真偽値bool型(True, False)と他の型との変換・判定 | note.nkmk.me
https://note.nkmk.me/python-bool-true-false-usage/

コードの実行

電子部品の結線が間違っていないか確認し、問題なければ先程のコードを管理者権限で実行する。
(GPIOを操作するには管理者権限が必要。)

$ sudo python3 ~/py/Debounce_sw.py
デバウンス対応実行(1枚目) デバウンス対応実行(2枚目) デバウンス対応実行(3枚目) デバウンス対応実行(4枚目) デバウンス対応実行(5枚目) デバウンス対応実行(6枚目)

ボタンを押せばLEDが切り替わる単純な機能だが、その当たり前の裏にはこのような工夫があることに感服する。