Das Erkennen und Umgang mit Kontaktprellen auf dem Raspberry Pi

Sie müssen möglicherweise mit Kontaktprellen für Ihren nächsten Raspberry Pi Projekt fertig zu werden. einen Schalter zu lesen, ist ganz einfach. Es gibt entweder eine 0 oder eine 1 ist, je nachdem, ob der Schalter gedrückt wird. Schalter sollte immer zwischen dem Mehrzweck Eingang / Ausgang (GPIO) Eingangs-Pin und Boden und entweder ermöglichen, die internen Pull-up-Widerstand oder fixieren einen externen Widerstand mit ihnen verbunden werden. Wenn ein Schalter geschlossen ist, macht es einen Weg zur Masse. Sie lesen einen logisch niedrigen oder null, wenn dieser Weg gemacht wird.

Sie können auch andere Anordnungen sehen, wo ein Schalter zwischen dem GPIO Eingangsstift und 3V3 verbunden ist, aber dies wird nicht empfohlen, weil Schalter normalerweise auf lange Drähte sind. lange Drähte Routing mit der Erde verbunden ist weniger riskant als mit einer Stromspannung. Dies ist, wie Sie einen Switch verbinden.

bild0.jpg

Obwohl ein Schalter mit Masse mit einem Pull-up-Widerstand auf eine hohe Spannung nur 1 oder 0 lesen können, sind am Schalter ein wenig komplexer. Nehmen wir zum Beispiel einen 1-Pfund-Sack Zucker und legen Sie es von etwa 6 Zoll auf eine harte Oberfläche wie ein Tisch. Es trifft die Oberfläche mit einem dumpfen Schlag und stoppt. Nun versuchen, die gleiche Sache mit einem Ping-Pong-Ball, und Sie werden sehen, dass es springt. Der erste Schlag des Ping-Pong-Ball ist nicht so hoch wie die Höhe Sie es fiel von, aber es ist ziemlich hoch. Dann wird der Ball fällt und springt wieder, nur geringfügig niedriger. Dies setzt sich fort mit immer kleineren Prallhöhen, bis der Ball zur Ruhe kommt. Beachten Sie, dass je niedriger die prallen, desto kürzer ist die Zeit zwischen bounces- die Bounces beschleunigen, bis der Ball zur Ruhe kommt.

Die Schaltkontakte sind ähnlich - sie sind starre Oberflächen schnell zusammen kommen, und sie hüpfen. So sehr, dass, wenn Sie die Logikpegel der Schalter gibt aus untersuchen, werden Sie nicht einen einfachen Übergang von einem hohen zu einem niedrigen, aber eine Reihe von Übergängen sehen zusammen rückt näher und näher, bis ein stationärer Niveau erreicht ist. Dies wird als eine schmutzige Kante oder Kontaktprellen bekannt.

image1.jpg

Dieser rasche Wechsel von 0 auf 1 kann ein Problem sein, wenn der Computer am Schalter ist auf der Suche sehr schnell. In der Tat geschieht dies viel schneller als ein Benutzer einen Knopf drücken kann, aber manchmal Umstände oder Code wird geschehen lassen. Um das Problem zu veranschaulichen, betrachten Sie den folgenden Code, Haken einen Schalter zwischen den GPIO 2 (Pin 3) und Masse (Pin 6). Dieser Stift hat einen Pull-up-Widerstand auf der Platine montiert.

# Bounce Problem zeigt Kontaktprellen # Autor: Mike Cookimport timeimport wiringpi2 als ioio.wiringPiSetupGpio () io.pinMode (2,0) # zu inputlastPress = io.digitalRead (2) count = 0pressTime = time.time () print "Test Push Taste ", während True: drücken = io.digitalRead (2), wenn Presse == 0 und lastPress = drücken: count + = 1pressTime = time.time (), wenn count> = 5: print" fünf Pressen "count = 0lastPress = drücken

Die Technik, die hier verwendet wird, ist fünf Schalter drückt zu zählen und dann ausdrucken, wenn der Computer sie alle gezählt hat. Wenn Sie dies versuchen, können Sie feststellen, dass es heraus druckt, dass es fünf Pressen nach vier oder sogar drei Pressen erkannt hat, sowie alle fünf. Kurz gesagt, ist es unzuverlässig, weil das Kontaktprellen ist fehlerhaft zählt zu verursachen.

Um dies zu untersuchen tiefer, müssen Sie das Intervall zwischen den Pressen zu messen. Dies wird mit dem folgenden Code getan.

# Bounce Maßnahme # Maßnahmen Kontakt Zeitintervall # Autor: Mike Cookimport timeimport wiringpi2 als ioio.wiringPiSetupGpio () io.pinMode (2,0) # zu inputlastPress = io.digitalRead (2) count = 0startTime = time.time () Intervall = [0.0,0.0,0.0,0.0,0.0] print "Testdruckknopf", während True: drücken = io.digitalRead (2), wenn Presse == 0 und lastPress = drücken: Intervall [count] = time.time () - startTimecount + = 1startTime = time.time (), wenn count> = 5: print "fünf Pressen", IntervalCount = 0startTime = time.time () lastPress = drücken

Der Abstand zwischen jedem Schalter drücken wird in einer Liste erfasst. Dies wird aus der Systemzeittakt abgeleitet und zählt die Anzahl der Sekunden seit dem das System hochgefahren. Durch Subtraktion der Systemzeit von dem Zeitpunkt der aktuellen Presse, Sie die Zeit seit der letzten Presse bekommen. Das Ergebnis der Ausführung dieses Programms wird hier gezeigt:

fünf Pressen [1,2872810363769531, 0.25738978385925293,6.198883056640625e-05, ,27149009704589844, 6.699562072753906e-05] fünf Pressen [2,247836112976074, 0.31453490257263184,0.32202887535095215, ,2885620594024658, 0,33057308197021484] fünf Pressen [1,048125982284546, 3.504753112792969e-05,0.5636959075927734, ,43523192405700684, ,4095041751861572] fünf Pressen [14,676625967025757, 0.24735713005065918,0.24397802352905273, 0,33951711654663086, ,34607601165771484]

Beachten Sie, dass der Code nicht versucht, die Anzahl der Bits in den Lesungen zu reduzieren, haben aber einen genauen Blick auf einige von ihnen, und Sie werden sehen, dass einige Ende mit einem e-05. Das ist die Standardmethode, 10 zu sagen, die Macht der -5- dies wird als Exponent Format bekannt und ist die Standardmethode, Fließkommazahlen werden in den meisten Rechen gezeigt. Also, die lächerliche Anzahl der Stellen nach dem Komma zu vergessen, diese Zahl ist, 6.12e-05, wird als 0,0000612 oder 61,2 Mikrosekunden (us) interpretiert, die ist viel schneller als jeder Mensch etwas drücken. Dies ist ein Beispiel für das Kontaktprellen. Sie sehen nicht jeden Schlag, weil der Computer nur Proben, die die Logikpegel der Leitung in diskreten Intervallen.

Der Weg, um dies zu verhindern ist eine Totzeit einzuführen - das heißt, der Schalter für eine bestimmte Zeit zu ignorieren, nachdem eine Presse eingetreten ist. Bei vielen Gelegenheiten, wird dies natürlich geschehen, weil Sie eine print-Anweisung oder einen anderen Code haben könnte, die einige Zeit in Anspruch nimmt, bevor der Schalter erneut überprüft wird. Wenn nicht, würde eine einfache Lösung sein, eine Verzögerung hinzuzufügen, unmittelbar nachdem der Schalter erkannt wurde, so dass nichts in der Potentialprellzeit erfolgt.

Doch für die ultimative debounce, müssen Sie einen Schalter Übergang erkannt wird eine Kenntnis von der Zeit zu machen. Dann, wenn ein anderer Übergang erkannt wird, nur um sie als real behandeln, wenn eine bestimmte Zeit zwischen dem letzten wirklichen Übergang und der heutigen Zeit abgelaufen ist. Ein Beispiel hierfür ist in den folgenden Code dargestellt.

# Bounce Lösung # Wie mit Bounce # Autor zu bewältigen: Mike Cookimport timeimport wiringpi2 als ioio.wiringPiSetupGpio () io.pinMode (2,0) # zu inputlastPress = io.digitalRead (2) count = 0pressTime = time.time () print "Test-Taster", während True: drücken = io.digitalRead (2), wenn Presse == 0 und lastPress = drücken und (time.time () - pressTime)> 0,025: count + = 1pressTime = time.time (), wenn count> = 5: print "fünf Pressen" count = 0lastPress = drücken

Hier ist das Geheimnis ist die zusätzliche Prüfung in der ob Anweisung, die verstrichen sind, mindestens 25 Millisekunden (ms) überprüft, dass, bevor ein Übergang als real genommen wird.

Verschiedene Arten von mechanischen Schaltern aufprallen zu einem unterschiedlichen Grad. Je nach genau das, was Ihr Code ist und wie schnell es läuft, kann dies oder kann kein Problem sein. Wenn Sie einen mechanischen Schalter auf Leseerlebnis "Phantom" Übergänge zu tun, ist es wahrscheinlich, Kontaktprellen zu sein. Wenn ja, können Sie eine der hier beschriebenen Techniken verwenden, um die Wirkung zu beseitigen.

Menü