Drehimpulsgeber / Rotary Encoder

1.Was ist ein Drehimpulsgeber und was kann ich damit machen 

Unter einem Drehimpulsgeber auch bekannt als Endlos Encoder oder Rotary Encoder versteht man einen Signal Geber der meist in Form eines Drehknopfes daher kommt und endlos in beide Richtungen gedreht werden kann. Optisch in etwa zu vergleichen mit einem Drehpotentiometer, der Haupt unterschied liegt in der Fähigkeit endlos in beide Richtungen gedreht werden zu können und nur noch an und aus Zuständen zu übertragen und kein Analoges Signal wie bei einem Poti. Jetzt zu der Hauptfrage, wann benutzt man ein Poti oder wann ist es besser einen Drehimpulsgeber zu benutzten. Ehrlich gesagt kann ich da keinem so einen Richtige Antwort geben, aber ich versuche es mal aus meiner Sicht zu beschreiben wie ich das passende wann und wo einordnen würde. Nehmen wir zu erst einmal das Poti und als Arbeitsplattform immer beides an einem Arduino Uno betrieben. Um ein Poti zu betreiben brauche ich, mal von der Spannung abgesehen einen Analogen Eingang am Gerät. Dieser Eingang arbeitet am Arduino Uno mit einer Auflösung von 10 Bit und ermöglicht es uns mit einer Genauigkeit von 1024 Schritten etwas zu steuern oder zu regulieren.Diesen Wert haben wir auch ohne großen Aufwand in der Software zur Verfügung stehen und man kann diesen Wert Intern im Arduino natürlich in Zahlen Bereiche Mappen mit Zahlen die bis zu 100 000 gehen können, aber auf gar keinen Fall eine Zahl gezielt einstellen wenn sie in einem höheren Bereich liegt als 1024. Kommen wir jetzt zum Drehimpulsgeber, um diesen am Arduino zu betreiben benötigen wir im Falle eines (ALPS STEC12E07) 2 Digitale Eingänge. Diese 2 Eingänge müssen wir mit etwas mehr Aufwand als das bei einem Analogen Eingang der Fall ist abfragen und haben anschließend die Möglichkeit das ein drehen nach Rechts einen Wert 1 abzieht und ein drehen nach Links 1 dazu zählt. Nun können wir also mit einem Drehregler eine Zahl gezielt einstellen egal wie hoch der Zahlen Bereich auch ist. Jetzt mal 2 kleine Beispiele aus der Praxis: 

Beispiel 1

  • Aufgabe: Ich möchte mit einem Drehregler die Hintergrund Beleuchtung von einem Displays Regulieren. Lösung: Dafür würde ich ein Poti wählen 1. reichen mir 10 Bit dafür aus 2. ist es den Aufwand nicht Wert einen Drehimpulsgeber zu verwenden.

Beispiel 2

  • Aufgabe: Ich möchte mit 2 Drehreglern einen Cursor auf einem Display an eine x/y Position setzen. Lösung: Dafür würde ich 2 Drehimpulsgeber verwenden da ich dadurch in genauen Schritten arbeiten kann.Und egal wie oft sich die Auflösung des Displays noch ändert ich
    kann die Schritte selbst definieren.

2.Wie ist ein Drehimpulsgeber aufgebaut ? 

Im Gegensatz zu einem Poti bei dem sich der Widerstand durch die Drehung ändert, ist ein Drehimpulsgeber im inneren anders aufgebaut. Im inneren befindet sich eine nicht leitende drehende Scheibe. Auf dieser Scheibe sind in bestimmten Abständen am äußeren Rand leitende Flächen mit Lücken dazwischen angeordnet.(Siehe unten). Über dieser Scheibe sind befinden sich 2 feste Positionen mit Kontakten welche an die äußeren Anschluss Pins geführt sind. Durch drehen des Drehimpulsgeber in eine bestimmte Richtung ergibt sich jeweils ein anderes Muster der Ein und Aus Zustände.(Siehe Diagramm)

Position 1

Position 2

Position 3

Position 4

Animation der Scheibe bei Recht bzw. Links lauf. In diesem Fall ein Drehimpulsgeber mit 12 Schritten

3.Schaltung / Anschluß

4.Beispiel Programm

4.Beispiel Programm

 

////////////////////////////////////////////////////////////////////////
///// Beispiel Quellcode 4 Rotary Drehimpulsgeber im Loop abfragen /////
////////////////////////////////////////////////////////////////////////

// Variable Encoder 1
int encoder0PinA = 11;
int encoder0PinB = 10;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;

// Variable Encoder 2
int encoder1PinA = 9;
int encoder1PinB = 8;
int encoder1Pos = 0;
int encoder1PinALast = LOW;
int n1 = LOW;

// Variable Encoder 3 
int encoder2PinA = 7;
int encoder2PinB = 6;
int encoder2Pos = 0;
int encoder2PinALast = LOW;
int n2 = LOW;

// Variable Encoder 4
int encoder3PinA = 5;
int encoder3PinB = 4;
int encoder3Pos = 0;
int encoder3PinALast = LOW;
int n3 = LOW;


void setup() { 
// Declare Pins as Input 
  pinMode (encoder0PinA,INPUT);
  pinMode (encoder0PinB,INPUT);
  pinMode (encoder1PinA,INPUT);
  pinMode (encoder1PinB,INPUT);
  pinMode (encoder2PinA,INPUT);
  pinMode (encoder2PinB,INPUT);   
  pinMode (encoder3PinA,INPUT);
  pinMode (encoder3PinB,INPUT);  
// Start Serial to check up Encoders  
  Serial.begin (9600);
} 

void loop() { 
// Read current Encoder pin A Positions to nX
  n = digitalRead(encoder0PinA);
  n1 = digitalRead(encoder1PinA);
  n2 = digitalRead(encoder2PinA);  
  n3 = digitalRead(encoder3PinA);     


  if ((encoder0PinALast == LOW) && (n == HIGH)) {   // Check last State of Encoder pin A = 0  && n = 1
    if (digitalRead(encoder0PinB) == LOW) {         // Check current Encoder pin B = 0
      encoder0Pos--;                                // Count down Encoder value -1
    } 
    else {
      encoder0Pos++;                                // Count up Encoder value +1
    }
    Serial.print ("Position 1: ");                  // Write Encoder value to Serial
    Serial.print (encoder0Pos);
    Serial.println (" ");
  } 

  if ((encoder1PinALast == LOW) && (n1 == HIGH)) {   // Check last State of Encoder pin A = 0  && n = 1
    if (digitalRead(encoder1PinB) == LOW) {         // Check current Encoder pin B = 0
      encoder1Pos--;                                // Count down Encoder value -1
    } 
    else {
      encoder1Pos++;                                // Count up Encoder value +1
    }
    Serial.print ("Position 2: ");                  // Write Encoder value to Serial
    Serial.print (encoder1Pos);
    Serial.println (" ");
  } 


  if ((encoder2PinALast == LOW) && (n2 == HIGH)) {   // Check last State of Encoder pin A = 0  && n = 1
    if (digitalRead(encoder2PinB) == LOW) {         // Check current Encoder pin B = 0
      encoder2Pos--;                                // Count down Encoder value -1
    } 
    else {
      encoder2Pos++;                                // Count up Encoder value +1
    }
    Serial.print ("Position 3: ");                  // Write Encoder value to Serial
    Serial.print (encoder2Pos);
    Serial.println (" ");
  } 
  

  if ((encoder3PinALast == LOW) && (n3 == HIGH)) {   // Check last State of Encoder pin A = 0  && n = 1
    if (digitalRead(encoder3PinB) == LOW) {         // Check current Encoder pin B = 0
      encoder3Pos--;                                // Count down Encoder value -1
    } 
    else {
      encoder3Pos++;                                // Count up Encoder value +1
    }
    Serial.print ("Position 4: ");                  // Write Encoder value to Serial
    Serial.print (encoder3Pos);
    Serial.println (" ");
  } 

// Write n to last state of Encoder pin A
  encoder3PinALast = n3;
  encoder2PinALast = n2;
  encoder1PinALast = n1;
  encoder0PinALast = n;
}