Raspberry Pi Pico でプッシュボタンのチャタリングを上手く処理してみた

プッシュボタン(タクトスイッチ)を押すとどうしてもオン・オフのときにチャタリング(非常に短い時間にオン・オフが繰り返される現象)が発生します。
チャタリングの原因であるスイッチ内部の振動現象を捉えてバウンスと言われることもあります。

Raspberry Pi Picoにプッシュボタン(タクトスイッチ)を取り付けて何かの処理中にボタンの割込みを受け付けようとしたのですが、もちろんチャタリング(バウンス)によって何度も割込みが発生してしまいました。
ボタン1個ならベタなプログラミングでもいいのですが、ボタンをたくさん使おうとすると同じようなコードがいくつもできるので、micropythonの Pinクラスを拡張して、チャタリング(バウンス)を対処したボタン割込み処理を作ってみました。

PushButton.py: チャタリング(バウンス)を対処したボタンクラス

#PushButton.py

from machine import Pin
import utime

class Debounced(Pin):
"""Extend micropython basic class 'Pin'
to support debounced IRQ"""

def __init__ (self, id, pull=-1):
super().__init__(id, Pin.IN, pull)
self.lastPressed = 0
self.func = None
self.bouncer = 500 # default debouncing time[mSec]


def __del__ (self):
super().__del__()


def callback(self, pin):
""" internal callback function to take care bounce """

now = utime.ticks_ms()
if now - self.lastPressed > self.bouncer:
self.lastPressed = now
self.func(pin)


def debouncedIRQ(self, func, trigger, bouncer = 500):
""" debounced IRQ support function

Args:
func: callback function to be called
trigger: IRQ trigger same as Pin triggers
bouncer: debouncing time in mSec
"""
self.func = func
self.bouncer = bouncer
self.irq(self.callback, trigger)




demo-button-irq.py: サンプルプログラム

from machine import Pin
from time import sleep

from PushButton import Debounced


# Callback function
def pressButton(button):
print("pressed ", button)


# Use GPIO 11, 12, 13
p1 = Debounced(11, Pin.PULL_DOWN)
p2 = Debounced(12, Pin.PULL_DOWN)
p3 = Debounced(13, Pin.PULL_DOWN)

# request irq and assign callback function
p1.debouncedIRQ(pressButton, Pin.IRQ_RISING)
p2.debouncedIRQ(pressButton, Pin.IRQ_RISING)
p3.debouncedIRQ(pressButton, Pin.IRQ_RISING)

# loop
while True:
print("waiting...")
sleep(10)




GitHubでコードを公開してます。
https://github.com/backy0175/pico-examples

この記事へのコメント