Rotary Encoder (KY-040)
Mit einem Rotary Encoder kann man ermitteln wie weit ein Drehgeber gedreht wurde. Anders wie ein Potentiometer hat der Rotary Encoder dabei keinen festen Anschlag sondern kann beliebig weit in eine Richtung weitergedreht werden. Der KY-040 hat pro Umdrehung 30 Positionen (alle 12°). Neben dem Drehwinkel kann man mit einem Rotary Encoder auch die Drehrichtung erkennen.
Im Inneren hat es zwei mechanische Schalter die zueinander etwas versetzt angeordnet sind sind. Bei den Rastierungen sind beide Schalter geschlossen. Auf dem Weg von Rastierung zu Rastierung werden beide Schalter geöffnet. Da die Schalter aber etwas versetzt angeordnet sind, wird je nach Drehrichtung entweder der eine oder der andere Schalter etwas früher geöffnet. Wichtig für das Verständnis ist, dass die Rastpositionen nicht genau mit den Schaltpositionen identisch sind.
Wenn der Ausgang CLK zuerst schaltet, wird im Uhrzeigersinn gedreht. Ändert der Ausgang DT seinen Pegel zuerst wird entgegen des Uhrzeigersinns gedreht.
Beide Schalter sind mit Masse verbunden welche dann im geschlossenen Zustand durchgeschaltet wird (LOW). Sind die Schalter geöffnet, liegt an jedem Ausgang über ein 10k Pullup-Widerstand +5V an (HIGH). Neben dem Drehrichtungsgeber ist beim KY-040 noch ein Drucktaster integriert, der im betätigten Zustand GND an den Ausgang SW durchschaltet.
Schaltung und Programmcode
#define CLK 4
#define DT 5
#define SW 7
void setup() {
Serial.begin(9600);
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
}
void loop() {
static int pos = 0;
static bool clkLast, clkNow;
static bool swLast, swNow;
clkNow = digitalRead(CLK);
swNow =digitalRead(SW);
if (swNow == LOW && swLast == HIGH ) {
delay(50);
Serial.println("Push");
}
// immer wenn CLK wieder auf HIGH wechselt wird geprüft...
if (clkNow == HIGH && clkLast == LOW){
// ... ob DT schon vorher geschaltet wurde
if (digitalRead(DT) == HIGH) pos++;
// ... oder noch nicht.
else pos--;
Serial.println(pos);
}
swLast = swNow;
clkLast = clkNow;
}