How to connect an Incremental Rotary Encoder to the Pi environment?

In my last post we discussed how to implement object classification with SVMs. However, I’ve been also working latyely on a lot on hardware-based projects that require fine-tuning and control of motors. Specifically, I’m developing a prosthesis that needs precise control of body position, managed by several motors. During this process, I noticed a clear gap in available information on how to effectively wire and program rotary encoders, which are crucial for achieving such precision. I’ve put together this detailed guide to show you how to perform a LPD3806 encoder Raspberry Pi integration, particularly the with a Raspberry Pi Zero 2 W.

This guide is designed to fill the documentation void, offering a straightforward approach to incorporating these invaluable encoders into your projects. Whether you’re working on a prosthesis like me or any other project that requires accurate motor control, this tutorial will give you the tools and knowledge you need to succeed. Letsa’ go into the exciting world of rotary encoders!


Table of contents

About the Incremental Rotary Encoders

Incremental rotary encoders output a series of electrical pulses corresponding to the amount of rotation. These pulses are used to measure increments of movement, hence the name “incremental”. They are distinguished by their ability to indicate rotation, speed, and direction (clockwise or counter-clockwise) but not the absolute position. To establish a point of reference or “zero” position, additional sensors or initial calibration processes are often required.

The core advantage of incremental encoders lies in their simplicity and reliability. They don’t need to maintain a record of their position when power is off, unlike absolute encoders that provide a unique code for each position, allowing for immediate location awareness upon startup. This makes incremental encoders more straightforward and cost-effective for applications where absolute positioning is not critical or can be established via an external reference point.

Figure 1: Illustration of a rotary encoder mechanism, where a disk with indentations interrupts light to sensors in multiple phases, generating pulses that track motor movement. Image source: Micronor Sensors

The LPD3806 Model: Distinct Features

The LPD3806 model stands out among incremental rotary encoders for several reasons. It’s an AB two-phase incremental photoelectric encoder, which means it uses light to detect rotational changes. This photoelectric method offers high precision and sensitivity, making the LPD3806 particularly suitable for applications requiring fine control and accuracy, such as in prosthetic devices or precise motor control systems.

  • Photoelectric Sensing: Unlike mechanical or magnetic encoders, the photoelectric encoder like the LPD3806 benefits from minimal wear and tear due to its non-contact sensing technology. This results in a longer lifespan and higher reliability, especially in clean environments where dust or magnetic fields might interfere with mechanical or magnetic sensors.
  • Two-Phase Output: The LPD3806 provides a two-phase (A and B) output which allows for the detection of direction. By comparing the phase shift between A and B outputs, the encoder can determine whether the movement is clockwise or counter-clockwise. This dual-phase output also enhances resolution, as each phase shift represents a fraction of a complete rotation, allowing for more precise measurement of movement. As shown in Figure 1, some producers of the LPD3806 even add one additional Z phase for checking full rotations of the shaft!
  • Advantages Over Other Models: When compared to other types of incremental encoders, the LPD3806’s photoelectric sensing offers superior precision and durability, particularly in environments where precision is paramount and external conditions are controlled. Moreover, its two-phase output not only enhances accuracy in direction and speed detection but also contributes to its versatility in various applications.

In summary, the LPD3806 model is a robust choice for projects that require detailed and reliable monitoring of rotational movements. Its photoelectric technology, combined with the two-phase output, makes it an excellent option for engineers and hobbyists alike who need precise control over their mechanical systems.


Wiring the Encoder to Raspberry Pi

Let’s now focus on the LPD3806 encoder Raspberry Pi integration. Wiring an incremental rotary encoder to a Raspberry Pi requires careful attention to the encoder’s datasheet and the Raspberry Pi’s GPIO pinout. Here’s how to do it:

  1. Identify the Encoder Pins: The LPD3806 has four main connections: Vcc (power), GND (ground), A (phase A output), and B (phase B output). For understanding which wire is which, you should consult the manufacturer’s datasheet. However, Figure 2 provides a visual representation of the most common colour code usually found on these sensors.
  2. Connect the Power and Ground: Connect the Vcc pin of the encoder to a 3.3V pin on the Raspberry Pi and the GND pin to one of the Pi’s ground pins.
  3. Connect the Output Pins: Connect the A (phase A output) and B (phase B output) pins of the encoder to GPIO pins on the Raspberry Pi. In this tutorial, we use GPIO 10 for Enc_A and GPIO 9 for Enc_B, but you can use any available pair of GPIO of your board (be sure to change the code accordingly).

To help guide you through this process, I have prepared an image showing the required wiring setup. This visual aid is designed to make the integration process as straightforward as possible, highlighting which pins on the Raspberry Pi correspond to the LPD3806’s connections. Following this guide will ensure that your encoder is correctly powered and able to communicate its rotational measurements to the Raspberry Pi.

Figure 2: LPD3806 encoders usually hold a standard wire color protocol, so most likely your unit’s color code will be the same as mine!

About the additional phases in some models

When working with LPD3806 encoders, you might come across models that include an extra mesh or additional wires, intended to enhance the encoder’s functionality or protect against signal interference. This extra mesh is designed to shield the encoder’s signals from external electrical noise, potentially improving the accuracy of your readings.

While some guides recommend connecting this shielding mesh to the ground as a precaution against interference, it’s not always a necessary step for every project. If you’re working in a relatively interference-free environment or if you’re just experimenting and learning, you might choose to leave this mesh disconnected initially. This allows you to test your setup without it and observe if there’s any noticeable interference affecting your signals. If you encounter issues that you suspect are caused by electrical noise, grounding the mesh could be a straightforward fix.

I have already mentioned this a couple of times, but I want to stress that it’s worth noting that certain versions of the LPD3806 encoder come equipped with extra wires for added functionalities. These could be for features like an index signal, which provides a once-per-revolution pulse, or other specialized outputs. For the purposes of this tutorial, where the focus is on basic wiring and code implementation, these additional wires can be left disconnected. It simplifies the setup process, allowing you to concentrate on getting the fundamental rotational tracking working. Let’s dive into the code for making this bad boy work!


Setting Up Your Raspberry Pi

Before diving into the code, ensure your Raspberry Pi is set up with the latest version of Raspbian and that you have access to the terminal or an SSH connection. If you do not know how to do so, leave a comment and I will write another post entry tutorial! Also, make sure you have the correct libraries installed in your raspberry board by running these commands:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python3-rpi.gpio
  1. apt-get update + upgrade – This command updates the list of available packages and their versions and then upgrades all the installed packages to their latest versions.
  2. install python3-rpi.gpio – Downloads the RPi.GPIO library, which provides easy access to the GPIO (General Purpose Input/Output) pins of the Raspberry Pi, allowing you to create programs that read data from sensors, control motors, and other physical outputs.

Make sure you run these commands to have your environment set up correctly for the project. With your Raspberry Pi updated and the necessary libraries installed, you’ll be all set to proceed with coding your project.


Python Script for Reading Encoder Data
'''
Code by Rodrigo C. Curiel, 2024. 
Check this and more snippets at www.curielrodrigo.com 
'''

# Import the required libraries
import RPi.GPIO as GPIO
from time import sleep

# Setup the GPIO pins (could be different for your particular case)
Enc_A = 10
Enc_B = 9

# Position counter
counter = 0

# Encoder state
last_A = 0
last_B = 0

# Make the initial setup for the assigned pins on the RPI board
def init():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(Enc_A, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(Enc_B, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Define a sample reading function for the encoder phases
def read_encoder():
    return GPIO.input(Enc_A), GPIO.input(Enc_B)

# Define a simple updating function for the counter 
def update_position(A, B):
    global counter, last_A, last_B
    if A != last_A or B != last_B:  # Only update on change
        if A == 1 and B == 0 and last_A == 0:  # Clockwise
            counter += 1
        elif A == 0 and B == 1 and last_B == 0:  # Counter-clockwise
            counter -= 1
        last_A, last_B = A, B

# Our main loop function 
def main():
    init()
    print("Monitoring rotary encoder...")
    try:
        while True:
            A, B = read_encoder()
            update_position(A, B)
            print(f"Position: {counter}")
            # This sleep should be short to avoid loosing steps on your reading. It might require some tunning for your use case
            sleep(.0000001)
    except KeyboardInterrupt:
        GPIO.cleanup()
        print("Program exited cleanly")

# When this script is called, run the main function
if __name__ == '__main__':
    main()

This script sets up the GPIO pins, reads the encoder’s output, and updates the position counter based on the direction of rotation. It’s designed for simplicity and effectiveness. It provides a basic framework for interfacing a Raspberry Pi with an incremental rotary encoder, utilizing GPIO pins for input. After initializing s the GPIO setup, it reads encoder phase changes and updates a counter to track the encoder’s position. The main loop continuously monitors the encoder, displaying the position in real time, with fine-tuning advised for the sleep interval to ensure accurate step tracking.

Testing the code

To execute and evaluate the functionality of this script, start by copying the provided code into a new file. Save this file in a location that’s easily accessible from your terminal, naming it encoders.py. To run the script and observe the measurements from your encoder in real-time, navigate to the directory where you saved encoders.py using the terminal. Once there, execute the following command:

python3 encoders.py

This command initiates the script, allowing you to monitor the encoder’s position updates directly in your terminal window. This setup represents a basic implementation, offering a straightforward method to get started with your encoder on the Raspberry Pi.

For those interested in enhancing the script’s functionality, consider integrating GPIO interrupts. This advanced approach allows your script to respond immediately to changes detected by the encoder’s pins, potentially increasing the accuracy and responsiveness of your position tracking. Incorporating interrupts requires a deeper dive into GPIO programming and event handling in Python.

If you decide to explore this more dynamic method and develop a version of the code that uses interrupts, I encourage you to share your insights and improvements! By commenting your enhanced code or sharing it within our community, you contribute valuable knowledge that can help others in their projects!


Conclusion

Wiring an incremental rotary encoder to a Raspberry Pi is a straightforward process that opens up a multitude of possibilities for hobbyists and developers alike. By following this guide, you’re now equipped to incorporate precise position tracking into your projects. Remember, experimentation is key to innovation, so don’t hesitate to modify and improve upon this basic setup to suit your specific needs. For more comprehensive projects and guides, stay tuned to this blog! I hope this entry helps you out!

Categories:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *