GPIOの入力として一番基本的なスイッチを扱います。スイッチで気を付けることはチャタリングのガードです。チャタリングとはスイッチを
押したまたは離したときにでるノイズのことです。このチャタリングのガードで問題なのは、
製品を開発中ではスイッチが新しいので、チャタリングが発生しない。
試しに新品のスイッチを(50円くらいの安物)をオシロスコープオシロスコープで確認したが、チャタリングはありません。
製品の開発時はチャタリングガードの評価が難しいです。
しかし、製品を使いこんでいくと1回しか押してないのに2回分の動作をした。などの不具合がでてきます。
このチャタリングはちょっとスイッチが馬鹿になってきたなですむ場合とそうでない場合があります。例えば電話機。
誤ダイヤルとなって全然違うところにかかってしまったら大変です。それなので電話関係はスイッチの選定と評価に力をいれます。
チャタリングとガード対策
一番簡単な方法です。
青の矢印がチャタリングが発生したところです。 チャタリングガードの方法は、タイマー割り込みでスイッチを監視して2回連続でLOWを検出したらスイッチが押されたと判定します。
タイマーの周期、有効とする検出方法は製品によって様々です。
ソースです。コメントをたくさん入れておきました。
# -*- coding: utf-8 -*-
import sys
import tkinter as tk
import wiringpi as wp
#タイマー間隔
INTERVAL = 50
#afterを再セットするためのグローバル変数
g_root = None
g_lblSwich = None
g_prevSWinput = None
#タイマー after のイベントハンドラー
def onTimer():
global g_root, g_lblSwich, g_prevSWinput
if wp.digitalRead(24) == wp.GPIO.LOW:
#現在の入力値がLOW
if g_prevSWinput == wp.GPIO.LOW:
#2回続けてLOW
g_lblSwich.configure(text = 'switch ON')
else:
#現在の入力値がHIGH
if g_prevSWinput == wp.GPIO.HIGH:
#2回続けてHIGH
g_lblSwich.configure(text = 'switch OFF')
#現在の入力値を前回入力値にセット
g_prevSWinput = wp.digitalRead(24)
#タイマー再セット
g_root.after(INTERVAL, onTimer)
def main():
global g_root, g_lblSwich, g_prevSWinput
g_root = tk.Tk()
g_root.title("Switch control")
g_root.geometry("250x40")
g_lblSwich = tk.Label(
g_root,
bg='yellow', relief=tk.RIDGE, bd=2,
text='Switch status')
g_lblSwich.place(x=10, y=10)
#wiringpaiの初期設定
wp.wiringPiSetup()
#ボタンの初期設定
wp.pinMode(24,wp.GPIO.INPUT)
wp.pinMode(25,wp.GPIO.INPUT)
#入力ポートをプルアップ
wp.pullUpDnControl(24, wp.PUD_UP)
wp.pullUpDnControl(25, wp.PUD_UP)
g_prevSWinput = wp.digitalRead(24)
#タイマーに周期とイベントハンドラーonTimerをセット
g_root.after(INTERVAL, onTimer)
g_root.mainloop()
if __name__ == "__main__":
main()
外観です。
|