πŸŽ›οΈ

Rotary Encoder

Projekt I07 - Drehgeber mit Taster und Interrupts

Intermediate
KY-040
Interrupt
1
Lernziele

Was du lernst

  • Hardware-Interrupts - Schnelle Reaktion auf SignalΓ€nderungen mit attachInterrupt()
  • volatile Variablen - Sichere Kommunikation zwischen ISR und Hauptprogramm
  • Taster-Entprellung - Software-Debouncing fuer zuverlaessige Eingaben
  • Drehrichtungserkennung - Quadratur-Signale auswerten

Voraussetzungen

Beginner-Projekte B01-B08 abgeschlossen, Grundlagen von digitalRead() und Zustandsvariablen bekannt

Komponenten

Der KY-040 Rotary Encoder

πŸŽ›οΈ

KY-040 Encoder

Inkrementeller Drehgeber mit integriertem Taster. Liefert Quadratur-Signale zur Richtungserkennung - perfekt fuer Menusteuerung!

Typ: Inkrementeller Encoder (relativ, nicht absolut)

Aufloesung: 20 Rastpunkte pro Umdrehung

πŸ“Œ

KY-040 Pinbelegung

  • CLK (A) - Clock/Phase A Signal
  • DT (B) - Data/Phase B Signal
  • SW - Switch (Taster beim Druecken)
  • + (VCC) - Versorgung 5V
  • GND - Masse

Logik: Aktiv LOW (interne Pull-Ups im Modul)

Interrupt-faehige Pins beim Arduino Uno

Nur Pin 2 (INT0) und Pin 3 (INT1) koennen Hardware-Interrupts ausloesen. Daher CLK an Pin 2!

2
Theorie

Quadratur-Encoder

Wie funktioniert es?

  • Zwei Signale (A und B) sind 90 Grad phasenverschoben
  • Bei Drehung rechts: A aendert sich VOR B
  • Bei Drehung links: B aendert sich VOR A
  • Durch Vergleich der Pegel: Richtung erkennbar!

Gray-Code Prinzip

Bei jedem Rastpunkt aendert sich nur EIN Bit - das verhindert Fehlzaehlungen bei Uebergaengen.

Quadratur-Signal

Drehung RECHTS:        Drehung LINKS:

CLK ──┐   β”Œβ”€β”€β”€β”        CLK ───┐   β”Œβ”€β”€
      β””β”€β”€β”€β”˜   └──             β””β”€β”€β”€β”˜

DT  ────┐   β”Œβ”€β”€β”€       DT  ─┐   β”Œβ”€β”€β”€β”€
        β””β”€β”€β”€β”˜   ─           β””β”€β”€β”€β”˜

Bei CLK-Flanke:        Bei CLK-Flanke:
CLK != DT -> ++        CLK == DT -> --
            

Trick: Bei jeder CLK-Aenderung pruefen: Sind CLK und DT unterschiedlich? Dann Rechtsdrehung!

Schaltplan

Verbindungen zum Arduino

Wokwi-Aufbau

    Arduino Uno          KY-040
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”
   β”‚           β”‚        β”‚  CLK  │─── Pin 2 (INT0)
   β”‚  Pin 2 ───┼─────────  DT   │─── Pin 3
   β”‚  Pin 3 ───┼─────────  SW   │─── Pin 4
   β”‚  Pin 4 ───┼─────────   +   │─── 5V
   β”‚           β”‚        β”‚  GND  │─── GND
   β”‚  5V ──────┼─────────       β”‚
   β”‚  GND β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”˜
            

Wichtige Verbindungen

  • CLK β†’ Arduino Pin 2 (Interrupt!)
  • DT β†’ Arduino Pin 3
  • SW β†’ Arduino Pin 4
  • + β†’ Arduino 5V
  • GND β†’ Arduino GND

Warum Pin 2?

CLK muss an einen Interrupt-Pin! Nur Pin 2 und 3 koennen beim Uno Hardware-Interrupts.

3
Code

Schritt 1: Pins und Interrupt

// I07: Rotary Encoder (KY-040)

// Encoder-Pins (CLK auf Pin 2 fuer Interrupt)
#define CLK_PIN 2   // Clock (A) - Interrupt-faehig!
#define DT_PIN 3    // Data (B)
#define SW_PIN 4    // Switch (Taster)

// WICHTIG: volatile fuer Variablen in ISR!
volatile int counter = 0;
volatile bool encoderMoved = false;

void setup() {
    Serial.begin(9600);

    // Pins als Input mit Pull-Up
    pinMode(CLK_PIN, INPUT_PULLUP);
    pinMode(DT_PIN, INPUT_PULLUP);
    pinMode(SW_PIN, INPUT_PULLUP);

    // Interrupt auf CLK-Pin bei jeder Aenderung
    attachInterrupt(digitalPinToInterrupt(CLK_PIN),
                    encoderISR, CHANGE);
}

volatile erklaert

Teilt dem Compiler mit: Diese Variable kann sich jederzeit aendern (durch Interrupt). Verhindert Optimierungen!

attachInterrupt()

CHANGE = bei jeder Flanke (HIGH→LOW und LOW→HIGH). Andere: RISING, FALLING, LOW.

3
Code

Schritt 2: Interrupt Service Routine

// ISR = Interrupt Service Routine
// Wird bei jeder CLK-Flanke automatisch aufgerufen!

void encoderISR() {
    // Richtung bestimmen durch Vergleich CLK mit DT
    if (digitalRead(CLK_PIN) != digitalRead(DT_PIN)) {
        counter++;   // Rechtsdrehung
    } else {
        counter--;   // Linksdrehung
    }
    encoderMoved = true;
}

// Merke: ISR soll SCHNELL sein!
// - Kein Serial.print() in der ISR
// - Kein delay() in der ISR
// - Nur Flag setzen, Rest im loop()

Warum funktioniert der Trick?

Bei Rechtsdrehung aendert sich CLK bevor DT folgt - beim Lesen sind sie unterschiedlich. Bei Linksdrehung sind beide zum Lesezeitpunkt gleich. Einfach aber effektiv!

3
Code

Schritt 3: Taster-Entprellung

// Entprellzeit in Millisekunden
#define DEBOUNCE_TIME 50
unsigned long lastButtonTime = 0;
bool buttonPressed = false;

void checkButton() {
    unsigned long currentTime = millis();

    if (digitalRead(SW_PIN) == LOW) {  // Taster gedrueckt
        if (!buttonPressed) {
            if (currentTime - lastButtonTime > DEBOUNCE_TIME) {
                buttonPressed = true;
                lastButtonTime = currentTime;

                // Aktion bei Tastendruck
                counter = 0;
                Serial.println("*** RESET ***");
            }
        }
    } else {
        buttonPressed = false;  // Taster losgelassen
    }
}

Warum Entprellung?

Mechanische Taster "prellen" beim Druecken - sie schalten mehrfach schnell ein/aus. Die 50ms Wartezeit filtert diese Stoerimpulse.

Ausprobieren

Simulation in Wokwi

Wokwi Projekt

Erstelle ein neues Projekt mit Arduino Uno und KY-040:

So testest du

  • Fuege einen KY-040 hinzu (Suche: "rotary encoder")
  • Verbinde: CLK β†’ Pin 2, DT β†’ Pin 3, SW β†’ Pin 4, + β†’ 5V, GND β†’ GND
  • Kopiere den Code in die sketch.ino
  • Klicke auf Play - drehe am Encoder im Simulator!
  • Tipp: Klicke auf den Encoder um die Richtung zu wechseln, klicke in die Mitte fuer den Taster!
4
Challenges

Erweiterungen

Probiere diese Aufgaben aus

πŸ’‘

Challenge 1: LED-Helligkeit

Steuere die Helligkeit einer LED mit PWM (0-255). Encoder dreht = heller/dunkler.

πŸ“‹

Challenge 2: LCD-Menue

Blaettere durch ein Menue auf dem LCD. Encoder = navigieren, Taster = auswaehlen.

🌈

Challenge 3: RGB-Farbe

RGB-LED steuern: Encoder waehlt Farbwert, Taster wechselt zwischen R/G/B Kanal.

🦾

Challenge 4: Servo-Winkel

Encoder steuert Servo-Position von 0 bis 180 Grad. Praezise Positionierung!

πŸŽ›οΈ

Geschafft!

Du beherrschst jetzt Hardware-Interrupts

⚑

Interrupts

Schnelle Reaktion mit attachInterrupt()

πŸ”’

volatile

Sichere ISR-Variablen

🎚️

Entprellung

Zuverlaessige Tastereingabe

Naechstes Projekt

I08: IR-Fernbedienung - Infrarot-Signale empfangen und dekodieren

← β†’
1 / 11