Skip to main content

Quadrature Encoder Basics Part 2: Practice

After learning a few things about the quadrature encoders in the previous article – Encoder Basics Part 1 - Theory– let's try to detect the signals they emit!

What you will need:

  • Stepper or DC Motor with incremental quadrature encoder
  • 8-pin encoder connector cable
  • Arduino board (in this case we are using Arduino UNO R3)
  • LCD Screen to display results (in this example Sainsmart 4x20 chars)
  • Breadboard and Dupont cables

First of all, we will need to strip one side of the 8-pin encoder cable.


Now that we have a clear image of the 8 pin cables we should identify them. If you are using an igus encoder cable they are as following:

A and B channels on White and Green

A/ and B/ inverted channels on Brown and Yellow (used for filtering)

Index channel N and N/ on Pink and Blue (emits one signal per rotation of the motor used for homing)

Ground on Grey

VCC on Red (5VDC)

We know that the Arduino UNO has a 5VDC output pin and that should be adequate to power the encoder, of course using an external power supply adds stability and less fluctuation but let's keep it as simple as possible.

Wiring the encoder to the Arduino UNO

As stated above the connections will be as following:

Encoder – Arduino

VCC Red 5V
CH B Green Pin 2 (important as we will use the pin as an external interrupt)
CH A White Pin 4

LCD Screen – Arduino

VCC Red 5V
SDA Blue A4
SCL Purple A5

And here is a block diagram:


After connecting the Arduino to the PC, open the Arduino IDE with a new sketch.

From the menu bar select: Tools > Board > Arduino Genuino UNO (or your respective board). And from the same tab, the port that you have your Arduino connected to.

Writing the code

Let's explain some basic parts of the code. We will first include the libraries needed:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

Display the home screen on the LCD for 1500ms:

 lcd.home ();
  lcd.print("Encoder Tester.");  // Print a message to the LCD.
  lcd.setCursor( 0, 3);//Set the cursor to line 3 (first line is line 0)
  lcd.print("Please plug encoder.");

Attach the RISING interrupt:

 attachInterrupt(0, runEncoder1, RISING );  
// encoder pin on interrupt 0 >>(pin 2 on arduino)

Because of the nature of the LCD whenever a character is printed, it stays on the LCD until is overwritten by another character (including space). The count of steps will increment and decrement 500 ticks per motor rotation.

So if the motor moves forward half rotation the LCD will print 250 steps and if the motor moves backwards for half rotation the ticks decrement to 0-ticks but the LCD will actually show 150 as last two numbers were printed but not refreshed.To solve this "bug", we will refresh the LCD by printing spaces every time that the value of the character decreases.

 lcd.setCursor ( 8, 2 );        // go to the 2nd line
  lcd.print(Pos1, DEC);  
   if (Pos1 < 100000) lcd.print(" ");
  if (Pos1 < 10000) lcd.print(" ");
  if (Pos1 < 1000) lcd.print(" ");
if (Pos1 < 100) lcd.print(" ");
if (Pos1 < 10) lcd.print(" "); 

  lcd.setCursor ( 0, 3 );        // go to the fourth line
  lcd.print("                    ");

Last but not least, we should set the interrupts routine:

void runEncoder1()
 if (digitalRead(encoder1PinA) == digitalRead(encoder1PinB))   
   encoder1Pos++;    // count up if both encoder pins are HIGH on pin change interrupt
   encoder1Pos--;    //count down if pins are HIGH and LOW

Having in mind the encoder sequence from the datasheet:


In a clockwise (positive) rotation, if we attach the interrupt to channel A, the interrupt will be triggered by the HIGH signal. The Arduino will check if channel B is HIGH as well, which is not, and the Arduino will record -1 encoder steps which is wrong.

So the interrupt should be attached to channel B, when channel B goes HIGH, Arduino will check channel A which will be also HIGH and it will recond +1 encoder steps.

If the motor moves counter-clock wise, thus the sequence is reversed, when channel B goes HIGH and triggers the interrupt, Arduino will check channel A which will be LOW and it will register -1 encoder steps.

How are these signals used in automation projects?

With low-end generic controllers, we would command the stepper motor to move one rotation which equals 200 motor steps. Only channels A and B are used.

After the command was sent and completed by the motor, we would check if the encoder steps are on 500.

If a command of 200 motor steps is sent and we get 500 encoder steps feedback, motion was completed successfully.

If on the other case we get less encoder steps, it means that motor lost some steps due to excessive load, obstacles etc. thus we will instruct the motor to be disabled (de-energised) and an error to be emitted through a red LED for example.

With high end controllers like the igus D1 Dryve, channels A, B are used for feedback, N can be used for homing if needed, A/, B/ and N/ for filtering.

With the D1 Dryve when a motor with an encoder is used, we can enable closed loop.

Closed loop is a field-oriented control with sinusoidally commutated current-vector control meaning that the motor current is controlled on the go using the live feedback from the encoders in relation to the load.

For example, if the load increases the controller will increase the supplied current to the motor and vice versa. This eliminates the posibility of losing steps thus losing position which is a main problem when using stepper motors.

Here are pictures of the completed project:



More information about the motor and the D1 Dryve controller?

More information about encoders?

Encoder Basics

Full Code?

(Look at the attachments below.)

In a new series of articles, I will start exploring motor controllers for various types of motors and the different control modes they have.

Thank you for reading, please comment your thoughts/ questions at the comment section!



Electro-mechanical background with interest in motion control and automation, DC, EC, Steppers! Low Cost Automation Engineer at igus, UK.
DesignSpark Electrical Logolinkedin