A Rotary Encoder that’s Always on the Money! The ‘Bourns EAW’ Contacting Encoder

//A Rotary Encoder that’s Always on the Money! The ‘Bourns EAW’ Contacting Encoder


A rotary encoder that is “NEVER” wrong!
No debounce code needed!


All my content is free.

If you feel that my videos are helping and you would like to contribute, you can toss some coins in the Tip Jar via PayPal.

Select amount then click the “Donate” button.

Brainy-Bits Tip Jar Amount

I’ve made many tutorials using the very popular KY-040 rotary encoder, it works, it’s cheap, easy to find, but like many others rotary encoders it bounces a ‘lot’ and requires quite a bit of programming to make it accurate.

KY-040 Rotary Encoder Arduino
I made a tutorial on the best way I’ve found so far to use the KY-040 in a tutorial HERE.


Today we will look at the ‘Bourns EAW’ absolute contacting encoder, which uses a mechanical way instead of a purely digital one like the KY-040.

Quick overview

The ‘Bourns EAW’ as many advantages compared to the KY-040:

  • It has 128 rotary positions
  • Uses a mechanical way to know where it is, so no debounce code is needed
  • It’s fairly cheap compared to other encoders like it (‘$7)
How does it work?

Inside the Bourns encoders are 8 contactor tracks (which are connected to the 8 external pins on the encoder), and depending on where the shaft of the encoder is, those tracks convert to a specific binary code (00010001).

So for every 128 positions a different binary code can be obtained to know ‘exactly’ where the encoder is.

Here’s an sample of some of the positions and the corresponding binary results:


So no matter where the shaft is rotated to, we can know for certain where it is just by reading the 8 pins and matching that result to the binary map above.

Since it uses a mechanical way to know where it is, this type of encoder will always return the same results, even when the power is removed from the Arduino.

One downside of using this encoder might be that it requires 8 Pins to connect to an Arduino, compared to only 2 Pins when using the KY-040.

** But we will see in a future tutorial how to reduce the number of pins needed…  Stay tuned!

Connection Diagram

Arduino Bourns Connections

In this tutorial were using the ‘Bourns EAW’ encoder to control a Stepper Motor.

Were also using an I2C LCD to display the encoder values and number of steps taken by the Stepper Motor.  The 16×2 character LCD is connected to the popular I2C LCD Backpack that can be found on Amazon.

LCD Connections:
5v and Ground from the Arduino and A4 – A5 to SDA and SCL of the backpack

EasyDriver Connections:
Pin 10 and 11 of Arduino to DIR and STEP pin of the driver
Ground of Arduino to Ground of driver
The EasyDriver is connected to a 12V power supply

Bourns EAW connections:
Pin 2 to 9 of Arduino connected to pin 1 to 8 of the encoder
Ground of Arduino connected to a Common pin of the encoder


We are using a library created for the Bourns EAW encoder.

The library has many options to get values from the encoder, the most useful being:

  • Raw: this is the actual position of the encoder from 0 to 127, this will always be the same even if power is lost and restored.
  • Upost: same as Raw but starts at logical zero to 127, so everytime the Arduino is powered the value will be zero and is based on the Raw value.
  • Mpost: this is a multiturn value, that will start from zero when the Arduino is powered and can go from -32768 to 32768, this is the one we are using in this tutorial.
/* Control Stepper Motor with 'Bourns EAW' encoder
Created by Yvan / https://Brainy-Bits.com

This code is in the public domain...

You can: copy it, use it, modify it, share it or just plain ignore it!

#include <LiquidCrystal_I2C.h>  // I2C LCD Library by Francisco Malpartida https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
#include <AccelStepper.h>  // AccelStepper Library https://www.arduinolibraries.info/libraries/accel-stepper

#define I2C_ADDR 0x27  // I2C address of typical I2C LCD Backpack

// LCD Pins to I2C LCD Backpack - These are default for HD44780 LCD's
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

// Create instance for LCD called: i2c_lcd
LiquidCrystal_I2C i2c_lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

const int pinSTEP=11;  // STEP pin of EasyDriver connected to pin 11 of UNO
const int pinDIR=10;  // DIR  pin of EasyDriver connected to pin 10 of UNO

AccelStepper stepper(1, pinSTEP, pinDIR);  // Stepper setup

// Include the Bourns EAW Encoder library and maps
#include <ACE128.h>  // https://github.com/arielnh56/ACE128

#include <ACE128map12345678.h> // mapping for pin order 12345678

// Pin x of UNO connected to pin x of Encoder (example: UNO pin 2 connected to pin 1 of encoder, etc...)
ACE128 myACE(2,3,4,5,6,7,8,9, (uint8_t*)encoderMap_12345678);

int16_t multiturn_encoder_value;  // Variable to hold multiturn value of encoder (-32768 to 32767)

void setup() {
  i2c_lcd.begin (16,2); //  our LCD is a 16x2, change for your LCD if needed
  // LCD Backlight ON
  i2c_lcd.clear(); // Clear the LCD screen

  stepper.setCurrentPosition(0);  // Set current position of stepper at startup to zero
  stepper.setMaxSpeed(1000.0);      // Set Max Speed of stepper
  stepper.setAcceleration(5000.0);  // Acceleration of stepper
  stepper.setSpeed(1000.0);  // Speed of stepper

  myACE.begin();    // initialize the encoder library

void loop() {

  multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  stepper.moveTo(multiturn_encoder_value); // set stepper new position to move to
  while (stepper.distanceToGo() != 0) {  // if stepper hasn't reached new position
    stepper.runSpeedToPosition();  // move the stepper until new position reached

// Display the encoder multiturn and stepper position on LCD
  i2c_lcd.print("Encoder: ");
  i2c_lcd.print("      ");
  i2c_lcd.print("Stepper: ");
  i2c_lcd.print("      ");  

For the price, this encoder is a really good option for many projects that requires accurate readings.

In this tutorial we didnt’ use the capability of the encoder to ‘remember’ it’s position after a power failure, but this could be a great option for some projects.

The KY-040 still has a place for systems that don’t require absolute accuracy, like for menu selection, but the Bourns EAW sure has a place for other circuits.

As many electronic components, you might not have a use for such an encoder right now, but it’s always good to know it exists and might be the solution for a future project!

Thank you for stopping by!


Copy and Paste the above code/sketch in your Arduino IDE software.

Link to the libraries used in this tutorial:

By | 2019-02-24T22:28:33-05:00 February 22nd, 2019|Tutorials|


  1. Chad Vanderbyl May 30, 2020 at 11:13 pm - Reply

    hi this was a great tutorial and I got one of these encoders but I having and issue with it adding numbers once I go above 100 or into the negative it seems to put an extra number in it. if I go below zero and come back up instead of 0 it will be 01 and then go up from there is there any way to make it not do this? thanks

  2. Chad Vanderbyl May 26, 2020 at 11:44 pm - Reply

    Your video was great. I have the encoder working but when I go below zero and come back up it seems to add and extra number on the back side. so instead of 0 its 01 and if I move it a bunch it will add a third number sometimes anyway to stop this? Thanks

  3. mick April 7, 2020 at 6:05 am - Reply

    call me thick but the code does not verify comes up with error

    no matching function for call to ‘ACE128(int, int, int, int, int, int, int, uint8_t*)’

    can any one help please

  4. Timothy Rehfeldt (KJ6CWB) January 15, 2020 at 12:50 am - Reply

    Comment…Hi There. I just built this project, using your sketch. Thank you for sharing. I’ve corrected some of my mistakes, but this one I cant figure out. Whether I rotate the encoder CW or CCW, the motor always turns CW. I substituted the Easy Driver for a TB6600. I’m about to buy an east driver, but I thought I could use the TB6600 just the same. This is my first arduino project, so I’m pretty happy I got this far. Anyone have any thoughts? Thanks, Tim

  5. Bill Samek June 12, 2019 at 4:50 pm - Reply

    Hi, Good tutorial, , thanks! I’m an amateur radio operator building a antenna tuner. I’m using the rotary encoder for both capacitor and roller inductor position. Will your code remember the last postions of the encoder if the power to the Arduino fails/ If not how would be the best way to do this

    • Christopher Spring July 14, 2019 at 9:22 pm - Reply

      Ok so the LCD library is installed now but I get an error code saying that LiquidCrystal_IC2 has no member named ‘setBacklightPin’
      Error Positive was not declared in this scope
      Return code is not 0

      I’m just a computer illiterate man trying to get a stepper motor to move accurately. Donation inbound for any assistance

  6. Ben May 16, 2019 at 1:38 pm - Reply

    Hello !

    Many thanks for this terrific and good tutorial !
    It took me some time but now it’s working.
    Is there a possibility to ad a seccond stepper with a seccond encoder ?

    • Christopher Spring July 14, 2019 at 8:42 pm - Reply

      Hi. Great tutorial you have here. As I know nothing about coding. I’m not finding the same library as you have on the link that’s provided. Theres alot of different .zip libraries there but not the same as you’re using. I’m trying to make a macro focus stacking rail. Thanks

  7. Nicolo March 25, 2019 at 10:38 am - Reply

    If I use the encoder ky 040 it is the same the program and all?
    Thank you so much

Leave A Comment