Raspberry Pi - Rotary Encoder

This tutorial instructs you how to use the incremental rotary encoder with Raspberry Pi. Here's what we'll cover:

Hardware Preparation

1×Raspberry Pi 4 Model B
1×Rotary Encoder
1×Jumper Wires
1×(Optional) Screw Terminal Adapter for Raspberry Pi

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of Rotary Encoder

A spinning knob that turns movement into a signal is called a rotary encoder. It shows you how much something twisted and where it's placed. There are two main kinds:

  • Incremental encoder: This uses fast signals to measure how much something changed.
  • Absolute encoder: This kind provides a unique code for each position, so you know exactly where something is, even if the power goes off.

This guide concentrates on the incremental encoder.

Rotary Encoder Module Pinout

rotary encoder pinout

A rotary encoder module has 4 pins:

  • CLK pin (Output A): is the main pulse that tells us how much rotation has occurred. Whenever you turn the knob by one detent (click) in either direction, the CLK pin outputs a signal that is a completes a full cycle (LOW HIGH LOW).
  • DT pin (Output B): acts like the CLK pin but outputs a signal lags behind CLK signal by 90 degrees. It helps us figure out the direction of rotation (clockwise or anticlockwise).
  • SW pin: is the output from the pushbutton inside the encoder. It’s normally open. If we use a pull-up resistor in this pin, the SW pin will be HIGH when the knob is not pressed, and LOW when it is pressed.
  • VCC pin (+): needs to be connected to VCC (between 3.3 and 5 volts)
  • GND pin: needs to be connected to GND (0V)

Rotary Encoder vs Potentiometer

You may confuse the rotary encoder with the potentiometer. but they are distinct components. Here's a comparison between them:

  • Rotary encoder is like the modern version of potentiometer, but they can do more things.
  • Rotary encoder can spin around in a full circle without stopping, while potentiometer can only turn about three-quarters of the circle.
  • Rotary encoder outputs pulses, while potentiometer outputs the analog voltage.
  • Rotary encoder is handy when you just need to figure out how much the knob has moved, not exactly where it is. Potentiometer is useful when you really need to know exactly where a knob is.

How Rotary Encoder Works

rotary encoder output

Inside the encoder, there's a disc with slots connected to a pin called C, which is like a shared ground. There are two more pins, A and B.

  • When you twist the knob, pins A and B touch the shared ground pin C, but in a certain order depending on which way you turn the knob (clockwise or counter-clockwise).
  • These touches create two signals. They're a bit different in timing because one pin touches the ground before the other. Two signals are 90 degrees out of sync with each other. This is called quadrature encoding.
  • When you turn the knob in clockwise direction, pin A touches the ground before pin B. When you turn the knob to the counterclockwise direction, pin B touches the ground before pin A.
  • By monitoring when each pin touches or leaves the ground, we can figure out which way the knob is turning. We do this by checking what happens to pin B when pin A changes.
How rotary encoder works

When A changes states from LOW to HIGH:

  • If B is LOW, the knob is turned clockwise.
  • If B is HIGH, the knob is turned counter-clockwise.

※ NOTE THAT:

Pin A and B are connected to CLK and DT pins. However, depending on the manufacturers, the order may be different. The codes provided below are tested with the rotary encoder from DIYables

How To Program For Rotary Encoder

  • Check the signal from CLK pin
  • If the state changes from LOW to HIGH, check the state of the DT pin.
    • If the state of the DT pin is HIGH, the knob is turned in the counter-clockwise direction, increase the counter by 1
    • If the state of the DT pin is LOW, the knob is turned in the clockwise direction, decrease the counter by 1

Wiring Diagram

The wiring diagram between Raspberry Pi and rotary encoder

This image is created using Fritzing. Click to enlarge image

Raspberry Pi Code – Rotary Encoder

The below Raspberry Pi code does:

  • Detects the direction and amount of rotation of the encoder.
    • If detecting the knob turned by one detent (click) in clockwise direction, increase the counter by one.
    • If detecting the knob turned by one detent (click) in anticlockwise direction, decrease the counter by one.
  • Detects if the button is pressed.

Detailed Instructions

  • Make sure you have Raspbian or any other Raspberry Pi compatible operating system installed on your Pi.
  • Make sure your Raspberry Pi is connected to the same local network as your PC.
  • Make sure your Raspberry Pi is connected to the internet if you need to install some libraries.
  • If this is the first time you use Raspberry Pi, See how to set up the Raspberry Pi
  • Connect your PC to the Raspberry Pi via SSH using the built-in SSH client on Linux and macOS or PuTTY on Windows. See to how connect your PC to Raspberry Pi via SSH.
  • Make sure you have the RPi.GPIO library installed. If not, install it using the following command:
sudo apt-get update sudo apt-get install python3-rpi.gpio
  • Create a Python script file rotary_encoder.py and add the following code:
# This Raspberry Pi code was developed by newbiely.com # This Raspberry Pi code is made available for public use without any restriction # For comprehensive instructions and wiring diagrams, please visit: # https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-rotary-encoder import RPi.GPIO as GPIO import time # Pin numbers on Raspberry Pi CLK_PIN = 7 # GPIO7 connected to the rotary encoder's CLK pin DT_PIN = 8 # GPIO8 connected to the rotary encoder's DT pin SW_PIN = 25 # GPIO25 connected to the rotary encoder's SW pin DIRECTION_CW = 0 DIRECTION_CCW = 1 counter = 0 direction = DIRECTION_CW CLK_state = 0 prev_CLK_state = 0 button_pressed = False prev_button_state = GPIO.HIGH # Configure GPIO pins GPIO.setmode(GPIO.BCM) GPIO.setup(CLK_PIN, GPIO.IN) GPIO.setup(DT_PIN, GPIO.IN) GPIO.setup(SW_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Read the initial state of the rotary encoder's CLK pin prev_CLK_state = GPIO.input(CLK_PIN) try: while True: # Read the current state of the rotary encoder's CLK pin CLK_state = GPIO.input(CLK_PIN) # If the state of CLK is changed, then pulse occurred # React to only the rising edge (from LOW to HIGH) to avoid double count if CLK_state != prev_CLK_state and CLK_state == GPIO.HIGH: # If the DT state is HIGH, the encoder is rotating in counter-clockwise direction # Decrease the counter if GPIO.input(DT_PIN) == GPIO.HIGH: counter -= 1 direction = DIRECTION_CCW else: # The encoder is rotating in clockwise direction => increase the counter counter += 1 direction = DIRECTION_CW print("Rotary Encoder:: direction:", "CLOCKWISE" if direction == DIRECTION_CW else "ANTICLOCKWISE", "- count:", counter) # Save last CLK state prev_CLK_state = CLK_state # State change detection for the button button_state = GPIO.input(SW_PIN) if button_state != prev_button_state: time.sleep(0.01) # Add a small delay to debounce if button_state == GPIO.LOW: print("The button is pressed") button_pressed = True else: button_pressed = False prev_button_state = button_state except KeyboardInterrupt: GPIO.cleanup() # Clean up GPIO on program exit
  • Save the file and run the Python script by executing the following command in the Terminal:
python3 rotary_encoder.py
  • Turn the knob in clockwise, then counterclockwise
  • Press the knob
  • Check out the outcome in the Terminal.
PuTTY - Raspberry Pi
DIRECTION: Clockwise | COUNTER: 1 DIRECTION: Clockwise | COUNTER: 2 DIRECTION: Clockwise | COUNTER: 3 DIRECTION: Clockwise | COUNTER: 4 DIRECTION: Clockwise | COUNTER: 5 DIRECTION: Counter-clockwise | COUNTER: 4 DIRECTION: Counter-clockwise | COUNTER: 3 DIRECTION: Counter-clockwise | COUNTER: 2 DIRECTION: Counter-clockwise | COUNTER: 1 DIRECTION: Counter-clockwise | COUNTER: 0 The button is pressed

Code Explanation

Check out the line-by-line comments in the code

Raspberry Pi Rotary Encoder Application

With Rotary Encoder, we can do the following applications but not limit:

  • Raspberry Pi - Rotary Encoder controls Position of Sevo Motor
  • Raspberry Pi - Rotary Encoder controls Brightness of LED
  • Raspberry Pi - Rotary Encoder controls Speed of Stepper Motor

Video Tutorial

Learn More