Arduino Rotary Encoder Module KY-040

The Keyes KY-040 Rotary Encoder

The Keyes KY-040 rotary encoder is a rotary input device (as in knob) that provides an indication of how much the knob has been rotated AND what direction it is rotating in.

It’s a great device for stepper and servo motor control.  You could also use it to control devices like digital potentiometers.

Rotary Position Measurement

A rotary or “shaft” encoder is an angular measuring device. It is used to precisely measure rotation of motors or to create wheel controllers (knobs) that can turn infinitely (with no end stop like a potentiometer has). Some of them are also equipped with a pushbutton when you press on the axis (like the ones used for navigation on many music controllers). They come in all kinds of resolutions, from maybe 16 to at least 1024 steps per revolution. Industrial encoders come from 1200PPR to 10000PPR (Pulse per revolution).

Measurement Principle

                Rotary encoders have two or three outputs A,B and Z. A and B are used to determine direction of rotation and counting the number of pulses will give the rotational position. Z is available on industrial grade encoders. It is zero position pulse. It gives only one pulse in one revolution.

Rotary Encoder Basics

A rotary encoder has a fixed number of positions per revolution (PPR).  The Keyes module KY-040 that I have has thirty of these positions.

On one side of the switch there are three pins.   They are normally referred to as A(1), B(3) and C(2).   In the case of the KY-040,  they are oriented as shown.

Inside the encoder there are two switches.  Once switch connects pin A(1) to pin C(2) and the other switch connects pin B(3) to C(1).

In each encoder position, both switches are either opened or closed.  Each angular movement causes these switches to change states as follows:

  • If both switches are closed,  turning the encoder either clockwise or counterclockwise one position will cause both switches to open
  • If both switches are open, turning the encoder either clockwise or counterclockwise one position will cause both switches to close.

The illustration below is representative of how the switch is constructed.

Angle = (360 / Encoder_Resolution) * Pulse cont

Output A is connected to interrupt (RISING) and when interrupt occurs depending on State of B output Pulse count is incremented or decremented.

As you can see, the angular position of the A terminal and the B terminal is such that:

  • Rotating the switch clockwise will cause the switch connecting A and C to change states first.
  • Rotating the switch counterclockwise will cause the switch connecting B and C to change states first.

If we were to represent the opening an closing of the switches as wave forms, it would look something like this.

Rotary Encoder Waveform
Rotary Encoder Waveform
Rotory Encoder Types
Rotary Encoder Types

There are too many encoders available in market all have basic principle of A,B output as shown in figure 12.1.  Some of the encoder have GND, +V, SW, DT, CLK. Pin configuration of these encoder is like this CLK=A, DT=B,  +V=5V given for pull-ups. SW is press action switch.

KY-040 Pin Outs

KY-040 Rotary Encoder
KY-040 Rotary Encoder


Encoder Pin out
Encoder Pin out

The pin outs for this rotary encoder are identified in the illustration below.

The module is designed so that a low is output when the switches are closed and a high when the switches are open.

The low is generated by placing a ground at Pin C and passing it to the CLK and DT pins when switches are closed.

The high is generated with a 5V supply input and pullup resistors, such that CLK and DT are both high when switches are open.

Not previously mentioned is the existence of of push button switch that is integral to the encoder.   If you push on the shaft, a normally open switch will close.    The feature is useful if you want to change switch function.   For example,  you may wish to have the ability to between coarse and fine adjustments.

Arduino Circuit Connections with Encoder

Encoder Arduino Circuit
Arduino Connections with Encoder

Arduino Code for Rotary Encoder

   read a rotary encoder with interrupts
   Encoder hooked up with common to GROUND,    encoder0PinA to pin 2, encoder0PinB to pin 4
   it doesn't matter which encoder pin you use for A or B  

#define encoder0PinA  2  //CLK Output A Do not use other pin for clock as we are using interrupt
#define encoder0PinB  4  //DT Output B
#define Switch 5 // Switch connection if available

volatile unsigned int encoder0Pos = 0;

void setup() { 

  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor
  attachInterrupt(0, doEncoder, RISING); // encoder pin on interrupt 0 - pin2
  Serial.begin (9600);
  Serial.println("start");                // a personal quirk

void loop(){
// do some stuff here - the joy of interrupts is that they take care of themselves
  Serial.println (encoder0Pos, DEC);  //Angle = (360 / Encoder_Resolution) * encoder0Pos

void doEncoder() {
  if (digitalRead(encoder0PinB)==HIGH) {
  } else {


                Open serial monitor and see the result of rotary encoder. Turn knob clock wise and anti-clock wise.

Encoder Result
Encoder Result

3 thoughts on “Arduino Rotary Encoder Module KY-040

  1. same thing i have to do in vissim embedded software which is GUI based ,
    sir please tell me the logic to find the angle rotated by encoder.

  2. I wasn’t able to get this to work on the Arduino Due.
    As written, it won’t trigger interrupts.
    Line 19 should probably read:
    attachInterrupt(digitalPinToInterrupt(encoder0PinA), doEncoder, RISING);

    With that change, the value goes up and down when the knob is turned, but it is kinda random which direction it goes.

Leave a Reply