12. Arduino for Production!! How to Receive Stable GPIO Push Button Input on the ARM Microcontroller - Software Debouncing Part 1

12. Arduino für die Produktion!! Wie man stabile GPIO-Tasteneingaben am ARM-Mikrocontroller empfängt – Software-Entprellung Teil 1

Arduino hat seinen Chipsatz auf leistungsstarke, fortschrittliche Chips wie die ARM-Mikrocontroller-Architektur umgestellt, so dass das Befolgen dieser Tutorials Ihnen sehr nützen wird, wenn Sie ein Anhänger von Arduino sind, besonders wenn Sie auf dem Weg sind, ein ernsthafter Entwickler für die Produktion zu werden. Das Erlernen der Bare-Chip-Methode, wie in meinen Videos und Inhalten gezeigt, bereitet Sie auf eine kostengünstigere und effizientere Produktion vor, anstatt mit Arduino zu beginnen, das auf Einzelprojekte ausgerichtet ist.

In diesem Video werden wir eine LED dazu bringen, jedes Mal an- und auszuschalten, wenn wir einen Drucktaster vollständig betätigen und loslassen. Wir werden unserer einfachen GPIO-Eingabe für Drucktaster etwas Komplexität hinzufügen. Da der Drucktaster ein mechanisches Bauteil ist, werden wir einige Probleme haben, weil das Signal mechanisch auf und ab springen wird. Wir müssen also das Springen herausnehmen und nur die reinen hohen und niedrigen Werte berücksichtigen, die vom Drucktaster erzeugt werden, wenn er an einen Pin des STM32 ARM Mikrocontrollers angeschlossen ist.

Drucktastenschalter sind mechanische Bauteile. Innerhalb dieses Drucktastenschalters befinden sich Leitungen mit Kontakten an den Leitungen, und dann gibt es einen leitfähigen Bereich am Kolben des Drucktasters, der, wenn er gedrückt wird, Kontakt mit den beiden Leitungen herstellt und einen Stromkreis zwischen den beiden Leitungen erzeugt. Diese Aktion verursacht elektrische Probleme, da mechanische Aktionen viel langsamer ablaufen als der elektrische Stromfluss.

Es kann ein Szenario geben, in dem ein hohes Signal (oder eine 1 im Code) zu einem niedrigen Signal wird, wenn der Drucktaster gedrückt wird (wenn der Drucktaster an Masse oder das niedrige Signal angeschlossen ist, wenn die beiden Leitungen verbunden sind). Natürlich kann das umgekehrt passieren, wo das Signal niedrig beginnt und dann beim Drücken hoch geht (was die Art und Weise ist, wie unser Stromkreis angeschlossen ist).

Was jedoch passiert, wenn Sie einen Drucktaster drücken, ist, dass er niedrig beginnt und wenn der Drucktaster gedrückt wird, kann die Spannung mehrmals hoch und niedrig springen, bevor sie sich auf dem hohen Signal stabilisiert. In der Software, während der Pin gelesen wird, wird dies offensichtlich sein und der Pin wird viele Hochs und Tiefs zeigen.

Unsere Absicht ist es, den Teil zu eliminieren, der hoch und niedrig springen wird (1 und 0). Da wir eine LED haben, die beim Drücken des Drucktasters umgeschaltet wird, möchten wir nicht, dass die LED bei einem einzigen Drucktastendruck mehr als einmal umschaltet. Dies wird geschehen, wenn der Mikrocontroller den springenden Teil liest. Stellen Sie sich vor, wie frustrierend es wäre, die Ein-/Aus-Taste Ihrer TV-Fernbedienung zu drücken und Ihr Fernseher schaltet sich unvorhersehbar ein und wieder aus.

Um das Springen zu eliminieren, werden wir einen Zähler verwenden, wenn der Drucktaster gedrückt wird und ein stabiles hohes oder niedriges Signal vorliegt (viele 1en oder 0en hintereinander). Wir möchten wissen, ob der Drucktaster mit einem stabilen hohen Signal gedrückt wird und ob der Drucktaster nicht mit einem stabilen niedrigen Signal gedrückt wird. Wir möchten das instabile Zeug nicht zählen, und dieses Zeug wird niedrige Zählungen haben.

Wenn Sie sich Online-Code ansehen, werden Sie feststellen, dass andere Programmierer eine Verzögerung ab dem Zeitpunkt implementieren, an dem der Drucktaster gedrückt wird. Die Verzögerung soll theoretisch das Springen überwinden. Es gibt ein paar Gründe, warum ich diesen Ansatz nicht mag. Erstens kann Code in einer Verzögerung nicht ausgeführt werden, da eine Verzögerung nur eine Schleife von leeren Zyklen des Mikrocontrollers ist. Und zweitens testet die Zeitverzögerung nur zwei Zeitpunkte. Die beiden Punkte könnten immer noch einige fehlerhafte springende Abtastwerte sein.

Alternativ möchte ich, dass das Programm testet, ob der Eingangs-Pin eine Eins oder eine Null ist. Wenn es eine Eins ist, wird es im nächsten Zyklus erneut getestet, ob es wieder eine Eins ist. Wenn es eine Null ist, dann wird der gedrückte Zustand der Taste als nicht gedrückt eliminiert. Dieser Prozess wird immer wieder durchgeführt, bis genügend Abtastwerte vorhanden sind, so dass das Programm sagen kann: Ich bin zuversichtlich, dass die Taste gedrückt ist. Dies funktioniert auch umgekehrt für den Zustand, wenn die Taste nicht gedrückt ist, wo es eine Anzahl von Null-Abtastwerten testet. Die Anzahl der Abtastwerte wird eine Variable sein, die als Konfidenzschwelle bezeichnet wird. Diese Idee ist sehr ähnlich zu einem Zustandsautomaten, bei dem das Programm Operationen durchläuft und Daten sammelt, während es läuft, und auf diese Daten reagiert.

Wie genau machen wir das? Wir messen eine Null am Pin und dann haben wir etwas Prellen, dann landen wir auf einem hohen Signalpegel (einer Eins). Wir werden mit einigen Variablen arbeiten. Die erste Variable ist die offensichtlichste, ButtonPressed. Diese Variable wird entweder gleich Null oder Eins sein, was mir sagt, ob die Taste gedrückt ist oder nicht. Die Variable ButtonPressed wird Eins sein, wenn genügend Abtastwerte von Einsen vorhanden sind. Wenn genügend Abtastwerte auf niedrigem Signalpegel (Nullen) vorhanden sind, dann wird die Variable ButtonPressed Null sein.

Dafür müssen wir zwei weitere Variablen einführen: ButtonPressedConfidenceLevel und ButtonReleasedConfidenceLevel. Wir werden den ButtonPressedConfidenceLevel hochzählen, wenn er einem hohen Pegel oder einer Eins entspricht, und dies so lange tun, bis er eine Konfidenzschwelle erreicht, an der die Variable ButtonPressed auf Eins geändert werden kann. Es gibt eine wichtige Überlegung, die wir implementieren müssen: Wir müssen die Konfidenzlevel-Variablen hochzählen, wenn der entgegengesetzte Tastenstatus vorhanden ist. Zum Beispiel wird der ButtonPressedConfidenceLevel nur hochgezählt, wenn die Variable ButtonPressed Null ist. Es macht keinen Sinn, den ButtonPressedConfidenceLevel hochzuzählen, wenn ButtonPressed bereits gleich Eins ist. Dies gilt auch für den anderen Zustand, wenn der ButtonReleasedConfidenceLevel hochgezählt wird. Wenn dieser ButtonPressed gleich Eins ist, können wir den Ausgangspin umschalten (die LED umschalten).

Bevor wir beginnen, müssen Sie das vorherige Programm (den einfachen GPIO-Eingang) überprüfen, bei dem wir einfaches Abfragen am Eingangs-Pin durchführen und die LED (Ausgangs-Pin) eingeschaltet wird, wenn der Eingangs-Pin eine Eins liest. Die erste Änderung, die wir vornehmen werden, ist das Entfernen des Codes für den Ausgangs-LED-Pin. Wir werden diesen Code wieder einfügen, wenn wir das Umschalten des LED-Ausgangs-Pins implementieren.

Beginnen wir mit etwas Pseudocode.

In der While-Schleife sollten wir Folgendes haben:

// Wenn die Taste gedrückt wird (IDR - Eingangsdatenregister)
if (GPIOB->IDR & GPIO_IDR_1)
{
}
else
{
}


Wenn die Bedingung wahr ist, dann ist der Taster gedrückt. Im Codeblock, der ausgeführt wird, wenn wahr, müssen wir die Variable "Button Pressed Confidence Level" erhöhen. Dann können die LEDs umgeschaltet und die Variable "Button Pressed" auf eins geändert werden. Denken Sie daran, dass dieser Teil des Codes nicht ausgeführt werden sollte, es sei denn, die Variable "Button Pressed" ist null. Warum sollten wir diese Tests durchführen, um die Variable "Button Pressed" zu ändern, wenn diese Variable bereits eins ist?

Wenn eine Null an den Eingangs-Pin kommt, möchten wir den Button Released Confidence Level erhöhen. Wenn dann der Button Released Confidence Level größer ist als die Konfidenzschwelle, dann kann die Button Pressed Variable auf Null geändert werden.

// Wenn die Taste gedrückt wird (IDR - Eingangsdatenregister)
if (GPIOB->IDR & GPIO_IDR_1)
{
if (/*Variable Taste gedrückt ist 0*/)
{
// Erhöhen Sie den Konfidenzlevel "Taste gedrückt"
// Schalten Sie die LEDs um, sobald die Konfidenz "Taste gedrückt" die Konfidenzschwelle überschritten hat
// Aktualisieren Sie die Variable "Taste gedrückt" auf 1
}
}
else
{
if (/*Variable Taste gedrückt ist 1*/)
{
// Erhöhen Sie den Konfidenzlevel "Taste losgelassen"
// Sobald der Konfidenzlevel "Taste losgelassen" erreicht wurde
// Aktualisieren Sie die Variable "Taste gedrückt" auf 0
}
}


Alle Variablen, die in der while-Schleife aktualisiert werden, müssen sich in der Hauptfunktion außerhalb der while-Schleife befinden, damit sie nicht immer wieder neu initialisiert werden.

// Variable "Taste gedrückt" initialisieren
// Konfidenzlevel "Taste gedrückt" initialisieren
// Konfidenzlevel "Taste losgelassen" initialisieren
[[TUTORIALMENU(tutorial-arm" frameborder="0" allowfullscreen>
Zurück zum Blog

Hinterlasse einen Kommentar