Rotary Encoder - Understand and Use It (Arduino/other ΜController)

About: Create your own stuff ----------- No resistance can drop our

A rotary encoder is a electro-mechanical device which converts rotational motion into digital or analog information. It can turn clockwise or counter-clockwise. There are two types of rotary encoders: Absolute and relative (incremental) encoders.

While an absolute encoder outputs a value proportional to the current shaft angle, an incremental encoder outputs the step of the shaft and its direction.(In this case we have an incremental encoder)

Rotary encoders are becoming more popular because you are able to use two functions in one electrical module: A simple switch for confirming opperations and the rotary encoder to navigate, e.g. through a menu.

An incremental rotary encoder generates two output signals while its shaft is rotating. Depending on the direction, one of the signals leads the other. (see below)

Step 1: Understanding the Output Data

As you can see when the encoder shaft starts to rotate clockwise, Output A falls to LOW first and Output B follows it. In a counter-clockwise direction the operation turns opposite.

Now we just have to implement this on our µController (I used an Arduino Nano).

Step 2: Build the Circuit

As I described before the outputs create a HIGH and a LOW flank. To get a clean HIGH at the data pin A and B of the µController we have to add Pull-Up resistors. The common Pin C goes straight to ground for the LOW flank.

To get information about the internal switch (push-button) we will use the other two pins. One of them goes to VCC and the other one to a data Pin of the µController. We also have to add a Pull-Down Resistor to the data pin to get a clean LOW.

It is also possible to use internal Pull-Up and Pull-Down resistors of your µController!

In my case the pinout looks like:

  • +3,3V => +3,3V (Arduino)(also +5V possible)
  • GND => GND (Arduino)
  • A => Pin10
  • B =>



  • C => GND
  • SW =>



Step 3: Writing the Code

int pinA = 10; //internal switch A
int pinB = 11; //internal switch B int pinSW = 12; //switch (pressed Encoder) int encoderPosCount = 0; // starts at zero, change if you want

int positionval; bool switchval; int mrotateLast; int mrotate;

void setup() { int mrotateLast = digitalRead(pinA); Serial.begin (9600); delay(50); }

void loop() { readencoder(); if(readswitch() == 1){ Serial.println("Switch = 1"); } }

int readencoder (){ mrotate = digitalRead(pinA); if (mrotate != mrotateLast){ //knob is rotating if (digitalRead(pinB) != mrotate) { //switch A changed first -> rotating clockwise encoderPosCount ++; Serial.println ("rotated clockwise"); } else {// switch B changed first -> rotating counterclockwise encoderPosCount--; Serial.println ("rotated counterclockwise"); }

Serial.print("Encoder Position: "); Serial.println(encoderPosCount); Serial.println(""); } mrotateLast = mrotate; return encoderPosCount; } bool readswitch(){

if(digitalRead(pinSW)!=0){ // switch is pressed while(digitalRead(pinSW)!=0){} //switch is currently pressed switchval = 1; } else{switchval = 0;} //switch is unpressed return switchval; }

Now you can turn the encoder and the variable encoderPosCount will count up if you rotate clockwise and count down if you rotate counter clockwise.

Thats it! Simply and usefull.

Feel free to change and perform the code. You can implement it in your project.

I will also upload a LED project where I used the encoder to set the brightness of my LEDs.

See you next time!



    • Build a Tool Contest

      Build a Tool Contest
    • Sweet Treats Challenge

      Sweet Treats Challenge
    • Warm and Fuzzy Contest

      Warm and Fuzzy Contest