Inhaltsverzeichnis:

Eine komplette Arduino-Rotationslösung - Gunook
Eine komplette Arduino-Rotationslösung - Gunook

Video: Eine komplette Arduino-Rotationslösung - Gunook

Video: Eine komplette Arduino-Rotationslösung - Gunook
Video: Brisant: Ist Baerbock’s Studium eine komplette Lüge? 2024, November
Anonim
Eine komplette Arduino-Rotationslösung
Eine komplette Arduino-Rotationslösung

Drehgeber sind drehbare Steuerknöpfe für elektronische Projekte, die häufig mit Mikrocontrollern der Arduino-Familie verwendet werden. Sie können verwendet werden, um Parameter fein abzustimmen, durch Menüs zu navigieren, Objekte auf dem Bildschirm zu bewegen und Werte jeglicher Art einzustellen. Sie sind ein üblicher Ersatz für Potentiometer, da sie genauer und unendlich gedreht werden können, einen diskreten Wert nach dem anderen inkrementieren oder dekrementieren und oft mit einem Druckschalter für Auswahlfunktionen integriert sind. Es gibt sie in allen Formen und Größen, aber die niedrigste Preisklasse ist schwer zu erreichen, wie unten erläutert.

Es gibt unzählige Artikel über die Arbeitsdetails und Verwendungsmodi von Rotary Encodern sowie zahlreiche Beispielcodes und Bibliotheken zu deren Verwendung. Das einzige Problem ist, dass keiner von ihnen mit den chinesischen Drehmodulen der niedrigsten Preisklasse 100% genau funktioniert.

Schritt 1: Drehgeber im Inneren

Drehgeber im Inneren
Drehgeber im Inneren
Drehgeber im Inneren
Drehgeber im Inneren
Drehgeber im Inneren
Drehgeber im Inneren

Der Drehteil des Encoders hat drei Pins (und zwei weitere für den optionalen Schalterteil). Einer ist die gemeinsame Masse (schwarzer GND), die anderen beiden dienen der Richtungsbestimmung beim Drehen des Knopfes (sie werden oft als blaues CLK und rotes DT bezeichnet). Beide sind an einen PULLUP-Eingangspin des Mikrocontrollers angeschlossen, wodurch der Pegel HIGH zu ihrem Standardwert wird. Wenn der Regler nach vorne (oder im Uhrzeigersinn) gedreht wird, fällt zuerst der blaue CLK auf den Pegel LOW, dann folgt der rote DT. Wenn man sich weiter dreht, steigt der blaue CLK wieder auf HIGH, dann steigt der rote DT wieder auf HIGH, wenn der gemeinsame GND-Patch beide Anschlusspins verlässt. Damit wird ein voller Tick FWD (oder im Uhrzeigersinn) abgeschlossen. Das gleiche gilt für die andere Richtung BWD (oder gegen den Uhrzeigersinn), aber jetzt fällt Rot zuerst und Blau steigt zuletzt zurück, wie in den zweistufigen Bildern gezeigt.

Schritt 2: Elend, das für viele echte Schmerzen verursacht

Elend, das vielen echten Schmerz bereitet
Elend, das vielen echten Schmerz bereitet
Elend, das vielen echten Schmerz bereitet
Elend, das vielen echten Schmerz bereitet
Elend, das vielen echten Schmerz bereitet
Elend, das vielen echten Schmerz bereitet

Häufiges Problem für Arduino-Bastler, dass billige Rotary-Encoder-Module zusätzliche Änderungen der Ausgangspegel abprallen lassen, was zu zusätzlichen und falschen Richtungszählwerten führt. Dies verhindert ein fehlerfreies Zählen und macht es unmöglich, diese Module in genaue Rotationsprojekte zu integrieren. Diese zusätzlichen Prells werden durch die mechanischen Bewegungen der Patches über die Anschlussstifte verursacht und können selbst durch das Anbringen zusätzlicher Kondensatoren nicht vollständig beseitigt werden. Bounces können überall in den vollständigen Tick-Zyklen auftreten und werden durch reale Szenarien auf den Bildern veranschaulicht.

Schritt 3: Lösung mit endlicher Zustandsmaschine (FSM)

Finite State Machine (FSM)-Lösung
Finite State Machine (FSM)-Lösung

Das Bild zeigt den vollständigen Zustandsraum der möglichen Pegeländerungen für die beiden Pins (blauer CLK und roter DT), sowohl für korrekte als auch für falsche Bounces. Basierend auf dieser Zustandsmaschine kann eine Komplettlösung programmiert werden, die immer 100% genau arbeitet. Da bei dieser Lösung keine Filterverzögerungen notwendig sind, ist sie auch die schnellstmögliche. Ein weiterer Vorteil der Trennung des Zustandsraums der Pins vom Arbeitsmodus besteht darin, dass man nach Belieben sowohl den Polling- als auch den Interrupt-Modus anwenden kann. Durch Abfragen oder Interrupts können Pegeländerungen an Pins erkannt werden, und eine separate Routine berechnet den neuen Zustand basierend auf dem aktuellen Zustand und den tatsächlichen Ereignissen von Pegeländerungen.

Schritt 4: Arduino-Code

Arduino-Code
Arduino-Code

Der folgende Code zählt die FWD- und BWD-Ticks auf dem seriellen Monitor und integriert auch die optionale Umschaltfunktion.

// Peter Csurgay 2019-04-10

// Pins des Rotary, die auf Arduino-Ports abgebildet sind

#define SW 21 #define CLK 22 #define DT 23

// Aktueller und vorheriger Wert des vom Drehregler abgestimmten Zählers

int curVal = 0; int prevVal = 0;

// Sieben Zustände von FSM (Finite State Machine)

#define IDLE_11 0 #define SCLK_01 1 #define SCLK_00 2 #define SCLK_10 3 #define SDT_10 4 #define SDT_00 5 #define SDT_01 6 int state = IDLE_11;

Leere Einrichtung () {

Serial.begin(250000); Serial.println("Start…"); // Level HIGH ist Standard für alle Pins pinMode (SW, INPUT_PULLUP); pinMode (CLK, INPUT_PULLUP); pinMode (DT, INPUT_PULLUP); // Sowohl CLK als auch DT lösen Interrupts für alle Pegeländerungen aus attachInterrupt(digitalPinToInterrupt(CLK), rotationCLK, CHANGE); AttachInterrupt(digitalPinToInterrupt(DT), RotaryDT, CHANGE); }

Leere Schleife () {

// Handhabung des optionalen Schalters, der in einigen Drehgebern integriert ist if (digitalRead (SW) = = LOW) { Serial.println ("Pressed"); while(!digitalRead(SW)); } // Jede Änderung des Zählerwerts wird im Serial Monitor angezeigt if (curVal! = prevVal) { Serial.println (curVal); prevVal = curVal; } }

// State Machine-Übergänge für CLK-Level-Änderungen

Void rotationCLK () { if (digitalRead (CLK) = = LOW) { if (state = = IDLE_11) state = SCLK_01; sonst if (state==SCLK_10) state = SCLK_00; sonst if (state==SDT_10) state = SDT_00; aufrechtzuerhalten. Sonst { if (state==SCLK_01) state = IDLE_11; sonst if (state==SCLK_00) state = SCLK_10; sonst if (state==SDT_00) state = SDT_10; sonst if (state==SDT_01) { state = IDLE_11; curVal--; } } }

// Zustandsmaschinenübergänge für DT-Level-Änderungen

Void rotationDT () { if (digitalRead (DT) = = LOW) { if (state = = IDLE_11) state = SDT_10; sonst if (state==SDT_01) state = SDT_00; sonst if (state==SCLK_01) state = SCLK_00; aufrechtzuerhalten. Sonst { if (Zustand = = SDT_10) Zustand = IDLE_11; sonst if (state==SDT_00) state = SDT_01; sonst if (state==SCLK_00) state = SCLK_01; sonst if (state==SCLK_10) { state = IDLE_11; curVal++; } } }

Schritt 5: Fehlerfreie Integration

Im angehängten Video können Sie überprüfen, ob die FSM-Lösung auch bei Low-Range-Drehgebern mit verschiedenen sporadischen Bounce-Effekten genau und schnell arbeitet.

Empfohlen: