From 1f1b56dd6b8e71c5a8d2f9e360092e8167ec6416 Mon Sep 17 00:00:00 2001 From: Alexander Kauerz Date: Wed, 15 Feb 2012 22:01:28 +0100 Subject: Wilde Dinge von Arduino.cc querkopiert. Stichwort: RotaryEncoders --- Drehimpulsgeber/drehimp.cpp | 108 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 21 deletions(-) (limited to 'Drehimpulsgeber/drehimp.cpp') diff --git a/Drehimpulsgeber/drehimp.cpp b/Drehimpulsgeber/drehimp.cpp index 4f64629..bcd38b8 100644 --- a/Drehimpulsgeber/drehimp.cpp +++ b/Drehimpulsgeber/drehimp.cpp @@ -1,28 +1,94 @@ #include -void doCount0(); -void doCount1(); - -volatile int cnt0 = 0; // Digitaler Pin 2 und 3 -volatile int cnt1 = 0; - -void setup() -{ - digitalWrite(2, HIGH); - digitalWrite(3, HIGH); - attachInterrupt(0, doCount0, CHANGE); - attachInterrupt(1, doCount1, CHANGE); - Serial.begin(9600); +/* interrupt routine for Rotary Encoders + tested with Noble RE0124PVB 17.7FINB-24 http://www.nobleusa.com/pdf/xre.pdf - available at pollin.de + and a few others, seems pretty universal + + The average rotary encoder has three pins, seen from front: A C B + Clockwise rotation A(on)->B(on)->A(off)->B(off) + CounterCW rotation B(on)->A(on)->B(off)->A(off) + + and may be a push switch with another two pins, pulled low at pin 8 in this case + raf@synapps.de 20120107 + +*/ + +// usually the rotary encoders three pins have the ground pin in the middle +enum PinAssignments { + encoderPinA = 2, // rigth + encoderPinB = 3, // left + clearButton = 8 // another two pins +}; + +volatile unsigned int encoderPos = 0; // a counter for the dial +unsigned int lastReportedPos = 1; // change management +static boolean rotating=false; // debounce management + +// interrupt service routine vars +boolean A_set = false; +boolean B_set = false; + + +void setup() { + + pinMode(encoderPinA, INPUT); + pinMode(encoderPinB, INPUT); + pinMode(clearButton, INPUT); + // turn on pullup resistors + digitalWrite(encoderPinA, HIGH); + digitalWrite(encoderPinB, HIGH); + digitalWrite(clearButton, HIGH); + +// encoder pin on interrupt 0 (pin 2) + attachInterrupt(0, doEncoderA, CHANGE); +// encoder pin on interrupt 1 (pin 3) + attachInterrupt(1, doEncoderB, CHANGE); + + Serial.begin(9600); // output +} + +// main loop, work is done by interrupt service routines, this one only prints stuff +void loop() { + rotating = true; // reset the debouncer + + if (lastReportedPos != encoderPos) { + Serial.print("Index:"); + Serial.println(encoderPos, DEC); + lastReportedPos = encoderPos; + } + if (digitalRead(clearButton) == LOW ) { + encoderPos = 0; + } +} + +// Interrupt on A changing state +void doEncoderA(){ + // debounce + if ( rotating ) delay (1); // wait a little until the bouncing is done + + // Test transition, did things really change? + if( digitalRead(encoderPinA) != A_set ) { // debounce once more + A_set = !A_set; + + // adjust counter + if A leads B + if ( A_set && !B_set ) + encoderPos += 1; + + rotating = false; // no more debouncing until loop() hits again + } } -void loop() -{ Serial.print(cnt0); - Serial.print(" - "); - Serial.println(cnt1); - delay(1000); +// Interrupt on B changing state, same as A above +void doEncoderB(){ + if ( rotating ) delay (1); + if( digitalRead(encoderPinB) != B_set ) { + B_set = !B_set; + // adjust counter - 1 if B leads A + if( B_set && !A_set ) + encoderPos -= 1; + + rotating = false; + } } -// Dummy interrupt functions -void doCount0() {cnt0++;} -void doCount1() {cnt1++;} -- cgit v1.2.3