チャタリング除去

RPi.GPIOで add_event_detect を使うと入力ポートの変化点を検出できるので便利なのだが、接点式スイッチは押された瞬間に細かくOn/Offが変化するチャタリング現象が発生するため、それもすべて検出されてしまい都合が悪い。

チャタリング除去は抵抗やコンデンサを使って回路的に行う方法と、ソフトウェア的に行う方法があって、ここではソフトウェア的に除去する方法を試してみる。

プログラムは以下の通り

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import RPi.GPIO as GPIO
import time

class button:
    def __init__(self, port, stat = GPIO.LOW, pud = GPIO.PUD_OFF):
        self.port = port
        self.stat = stat
        self.detect = False
        self.dt = time.time()
        GPIO.setup(self.port, GPIO.IN, pud)
    def get(self):
        stat = GPIO.input(self.port)
        dt = time.time()
        if stat != self.stat and dt > self.dt + 0.02:
            self.stat = stat
            self.dt = dt
            self.detect = True
        return self.stat        
    def check(self):
        stat = self.get()
        detect = self.detect
        self.detect = False
        return stat,detect

if __name__ == "__main__":
    GPIO.setmode(GPIO.BCM)
    btns = [button(17, GPIO.LOW, GPIO.PUD_DOWN),
            button(22, GPIO.LOW, GPIO.PUD_DOWN)]
    try:
        while True:
            for btn in btns:
                stat,detect = btn.check()
                if(detect):
                    if(stat == GPIO.LOW):
                        print btn.port,'FALLING'
                    else:
                        print btn.port,'RISING'
    except KeyboardInterrupt:
        print '\nbreak'
        GPIO.cleanup()

除去する方法は色々と考えられるが、最初の変化点を検出してから一定時間は変化をチェックしない単純な方法でやってみた。時間の経過はCPUクロックタイムをカウントする time.clock() を使用。 ※
どのぐらい待てば確実にチャタリング除去できるのかは良く分からなかったので、実測して値を設定したが、場合によっては調整する必要があるかも知れない。

※2013/03/16追記 : time.clock()が正しい値を返さない場合がある(原因不明)事が分かったので、time.time()に変更

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中