ROTARY ENCODER KY-040 on Arduino UNO - May 2014
WIRING INFORMATION
Connect CLK to Pin 2 on Arduino Board (CLK is Data Output 1 of KY-040)
Connect DT to Pin 3 on Arduino Board (DT is Data Output 2 of KY-040)
Connect SW to Pin 4 on Arduino Board (Switch - goes LOW when pressed)
Connect GND to ground
Connect + to +5V (this will pull up CLK and DT with 10 KiloOhm resistors)
Connect a 0,47µ capacitor from ground to CLK (debouncing)
Connect a 0,47µ capacitor from ground to DT (debouncing)
Connect a 10 KiloOhm resistor from +5V to SW (no integrated pullup for SW !!)
It is better NOT to use internal pull-up resistors on the Arduino, instead
use the integrated pull-ups of KY-040 (this requires “+” to be connected to 5V).
You can check if your version of the KY-040 has pull-up resistors on the bottom
side ouf the printed circuit board.
If not, use internal pull-ups from Arduino or external pull-ups.
In the stopping positions the KY-040 has always HIGH signals on both CLK and DT.
When you turn the encoder from one position to another, either CLK or DT goes LOW
before the other signal goes LOW as well.
The signal that goes LOW first determines if the encoder is turned left or right.
Once you reach the next stopping position both signals will be HIGH again.
If you press the push button, the current count can be reset to ZERO.
For faster response you might increase the speed of the serial connection.
(Make sure, that the Serial Monitor is also set to a higher speed,
otherwise you will get no output).
My rotary encoder came from china for 2 dollars, and after some debugging i found out, that it sometimes
behaves strange (e.g. it gives a signal to the SW pin - although I did not press the button.)
So for serious projects invest a dollar more and buy a quality product.
volatile boolean TurnDetected;
volatile boolean up;
const int PinCLK=2; // Used for generating interrupts using CLK signal
const int PinDT=3; // Used for reading DT signal
const int PinSW=4; // Used for the push button switch
void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK
if (digitalRead(PinCLK))
up = digitalRead(PinDT);
else
up = !digitalRead(PinDT);
TurnDetected = true;
}
void setup () {
pinMode(PinCLK,INPUT);
pinMode(PinDT,INPUT);
pinMode(PinSW,INPUT);
attachInterrupt (0,isr,FALLING); // interrupt 0 is always connected to pin 2 on Arduino UNO
Serial.begin (9600);
Serial.println("Start");
}
void loop () {
static long virtualPosition=0; // without STATIC it does not count correctly!!!
if (!(digitalRead(PinSW))) { // check if pushbutton is pressed
virtualPosition=0; // if YES, then reset counter to ZERO
Serial.print ("Reset = "); // Using the word RESET instead of COUNT here to find out a buggy encoder
Serial.println (virtualPosition);
}
if (TurnDetected) { // do this only if rotation was detected
if (up)
virtualPosition++;
else
virtualPosition--;
TurnDetected = false; // do NOT repeat IF loop until new rotation detected
Serial.print ("Count = ");
Serial.println (virtualPosition);
}
}