Nr. 33 – Der Rotary Encoder KY-040

Material : Funduino Mikrocontroller, Breadboardkabel, Breadboard, Rotary Encoder KY-040, LED, Widerstand (Materialbeschaffung : www.funduinoshop.com)

Der Rotary Encoder KY-040 ist im Grunde ein rotierendes Eingabemodul, welches einem Potentiometer stark ähnelt. Die Besonderheit des Rotary Encoders besteht darin, dass relativ simpel ausgelesen kann, in welche Richtung der Nutzer den Knopf (Rotary Head) des Encoders bewegt hat und wie viele Schritte dabei zurückgelegt wurden. Die einzelnen Schritte können dabei während des Drehens durch den Benutzer auch erfühlt werden.

 

Wie funktioniert der Encoder?

An einer Seite des Encoders sind drei Pins zu erkennen.

 

 

Die zu sehenden Pins werden A, B und C genannt. Dabei sind jeweils Pin A und Pin C, sowie Pin B und Pin C miteinander verbunden. In jeder Encoder Position sind beide Verbindungen entweder geöffnet oder geschlossen. Rotiert man den Knopf nun in eine beliebige Richtungen (im oder gegen den Uhrzeigersinn), verändert sich der Status wie folgt :

Wenn beide Verbindungen geschlossen sind, bewirkt eine Rotation des Knopfes die Öffnung der Verbindungen.
Wenn beide Verbindungen geöffnet sind, bewirkt eine Rotation des Knopfes die Schließung der Verbindungen.

Dabei gilt ebenfalls :

Rotiert man den Knopf im Uhrzeigersinn, verändert sich zuerst der Status der Verbindung zwischen den Pins A und C.
Rotiert man den Knopf gegen den Uhrzeigersinn, verändert sich zuerst der Status der Verbindung zwischen den Pins B und C.

Die Reihenfolge dieser Statusänderungen werden vom Controller ausgelesen und ausgewertet.

 



 

Der Rotary Encoder KY-040 verfügt über fünf Pins.

CLK  – „Serial Clock“ Pin, Daten-Output 1, anzuschließen am digitalen Pin 6 des Mikrocontrollers.
DT     – Einzigartiger Pin des Moduls, Daten-Output 2, anzuschließen am digitalen Pin 5 des Mikrocontrollers.

Die Pins CLK und DT können an einen digitalen Pins eurer Wahl angeschlossen werden. In unserem folgenden Sketch verwenden wir die oben genannten Pins D5 und D6.

SW   Switch-Pin – Dieser gibt ein „LOW“ Signal weiter, wenn der Knopf des Encoders betätigt wird. Anzuschließen an einen Interrupt-Pin des Mikrocontrollers.

Eine Übersicht aller Interrupt-Pins der Mikrocontroller finden Sie auf der offiziellen Seite von Arduino.

+         – Pin für die Spannungsversorgung (sonst VCC), anzuschließen an den 5V Pin des Mikrocontrollers.
GND Ground Pin, anzuschließen an den GND Pin des Mikrocontrollers.

 



 

Nun widmen wir uns dem Auslesen der jeweiligen Schrittposition des Encoders. Zudem möchten wir auslesen können, ob der Knopf des Encoders betätigt wurde. Die erhobenen Daten sollen im seriellen Monitor angezeigt werden. Dies gelingt uns unter anderem durch die Verwendung des attachInterrupt() Befehls.

Eine ausführliche Dokumentation dieser Funktion finden Sie hier.

Achtung : Das Rotary Encoder Modul KY-040 benötigt eine eigene Bibliothek. Diese Bibliothek mit dem Namen „<Encoder.h>“ finden Sie im nachfolgenden Link.

https://github.com/PaulStoffregen/Encoder

 

Der Sketch : 

#include <Encoder.h>    // Verwendung der <Encoder.h> Bibliothek 

const int CLK = 6;      // Definition der Pins. CLK an D6, DT an D5. 
const int DT = 5;
const int SW = 2;       // Der Switch wird mit Pin D2 Verbunden. ACHTUNG : Verwenden Sie einen interrupt-Pin!
long altePosition = -999;  // Definition der "alten" Position (Diese fiktive alte Position wird benötigt, damit die aktuelle Position später im seriellen Monitor nur dann angezeigt wird, wenn wir den Rotary Head bewegen)

Encoder meinEncoder(DT,CLK);  // An dieser Stelle wird ein neues Encoder Projekt erstellt. Dabei wird die Verbindung über die zuvor definierten Varibalen (DT und CLK) hergestellt.


void setup()   // Beginn des Setups

{
  Serial.begin(9600); 
    
  pinMode(SW, INPUT);   // Hier wird der Interrupt installiert.
  
  attachInterrupt(digitalPinToInterrupt(SW), Interrupt, CHANGE); // Sobald sich der Status (CHANGE) des Interrupt Pins (SW = D2) ändern, soll der Interrupt Befehl (onInterrupt)ausgeführt werden.
}


void loop()

{

    long neuePosition = meinEncoder.read();  // Die "neue" Position des Encoders wird definiert. Dabei wird die aktuelle Position des Encoders über die Variable.Befehl() ausgelesen. 

        if (neuePosition != altePosition)  // Sollte die neue Position ungleich der alten (-999) sein (und nur dann!!)...
        {
        altePosition = neuePosition;       
        Serial.println(neuePosition);      // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
        }

}


void Interrupt() // Beginn des Interrupts. Wenn der Rotary Knopf betätigt wird, springt das Programm automatisch an diese Stelle. Nachdem...

{
  Serial.println("Switch betaetigt"); //... das Signal ausgegeben wurde, wird das Programm fortgeführt.

}