Rotary Encoder
Arduino-Bastelprojekt: Drehgeber mit Encoder für Menüsteuerung und Werteingabe.
Ein Rotary Encoder (Drehgeber) ist ein Bauteil, mit dem sich Werte durch Drehen und Drücken eingeben lassen – ideal für Menüsteuerung, Lautstärkeregler oder Einstellungen an Geräten. Im Gegensatz zu einem Potentiometer liefert der Encoder keine absolute Position, sondern relative Änderungen: Beim Drehen werden Impulse ausgegeben, die Richtung wird über die Phasenlage der beiden Ausgangssignale erkannt.
Materialien
- Arduino (Uno, Nano oder kompatibel)
- Rotary Encoder mit Drucktaster (z. B. KY-040)
- Optional: Pull-up-Widerstände (oft bereits im Modul integriert)
Pinbelegung
| Encoder | Arduino |
|---|---|
| CLK | Pin 2 |
| DT | Pin 3 |
| SW (Drucktaster) | Pin 4 |
| + | 5V |
| GND | GND |
Das Programm nutzt einen Timer-Interrupt (Timer1), um die Encoder-Signale mit etwa 1 kHz abzutasten. Über eine Lookup-Tabelle wird aus der Phasenfolge die Drehrichtung ermittelt – hier mit 1/4-Auflösung. Über die serielle Schnittstelle werden Drehimpulse (+1/−1) und Tastendrücke (PressDown/PressUp) ausgegeben.
// Rotary Controller #define BTN_A_PIN 2 // CLK #define BTN_B_PIN 3 // DT #define BTN_PUSH_PIN 4 // SW bool Btn_Push_Last; volatile int8_t AB_Old = 0; volatile int RotaryPos = 0; //int8_t StepTable[16] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // 1/1 Auflösung //int8_t StepTable[16] = {0, 0,0,0,1,0,0,-1, 0,0,0,1,0,0,-1,0}; // 1/2 Auflösung int8_t StepTable[16] = {0, 0,0,0,0,0,0,-1, 0,0,0,0,0,1, 0,0}; // 1/4 Auflösung void setup(){ pinMode(BTN_A_PIN, INPUT); // Rotary button pinMode(BTN_B_PIN, INPUT); pinMode(BTN_PUSH_PIN, INPUT); Btn_Push_Last = digitalRead(BTN_PUSH_PIN); noInterrupts(); // Jetzt keine Interrupts TIMSK1 |= (1<<OCIE1A); // Timer 1 Output Compare A Match Interrupt Enable TCCR1A = 0; // "Normaler" Modus TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10); // WGM12: CTC-Modus einschalten; Bit CS12 und CS10 setzen = Vorteiler: 1024 OCR1A = 14; // Frequenz = 16000000 / 1024 / 15 = rd. 1kHz Abtastfrequenz -> Überlauf bei 14, weil die Zählung bei 0 beginnt interrupts(); // Interrupts wieder erlauben Serial.begin(250000); Serial.println("Drehknopf Test"); } void loop(){ if(digitalRead(BTN_PUSH_PIN) != Btn_Push_Last){ Btn_Push_Last = !Btn_Push_Last; if(Btn_Push_Last==HIGH) Serial.println("PressUp"); else Serial.println("PressDown"); } if(RotaryPos!=0){ // if there was a change Serial.println(RotaryPos); // output the difference RotaryPos = 0; // reset } } ISR(TIMER1_COMPA_vect) { // timer to read rotary button AB_Old <<= 2; AB_Old &= B00001100; AB_Old |= (digitalRead(BTN_B_PIN) << 1) | digitalRead(BTN_A_PIN); RotaryPos += StepTable[AB_Old]; }
Weitere Artikel
Gefällt dir die Webseite? Unterstütz die werbefreie Seite mit einer Spende.



Kommentare