Rotary Encoder

Rotary Encoder

Für Arduino


// 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

© Veit Götz 2012 - 2024
Impressum
Datenschutz
Statistiken
Spenden