Today we will be seeing how to use the rotary encoder with Raspberry Pi using python programming language.One of the common usage of rotary encoder is in Industrial control but did you know that it is used in certain photographic lenses? Also they are used in rotating radar platforms etc. They are also used to track the position of the motor shaft on brush less motors with permanent magnets which are are used in robot and CNC machines.

According to Wikipedia, the definition of a rotary encoder is “A rotary encoder, also called a shaft encoder, is an electro-mechanical device that converts the angular position or motion of a shaft or axle to an analog or digital signal”. From the appearance it gives a deception of a potentiometer. Although they can be in way called similar but they are not the same. Now having spoken a bit about the rotary encoder, lets get to know more about it and do some useful projects using it.

Hardware required

The following links are part of my affiliate links.

Raspberry PI

Banggood: https://www.banggood.com/Raspberry-Pi-3-Model-B-ARM-Cortex-A53-CPU-1_2GHz-64-Bit-Quad-Core-1GB-RAM-10-Times-B-p-1041862.html?rmmds=search&p=W214159476515201703B&cur_warehouse=CN

Amazon US: http://amzn.to/2Dw3oKT

Amazon Germany : http://amzn.to/2FUW5Sj

Rotary encoder

Banggood: https://www.banggood.com/KY-040-Rotary-Decoder-Encoder-Module-For-Arduino-AVR-PIC-p-914010.html?p=W214159476515201703B&rmmds=search&cur_warehouse=CN

Amazon US: https://amzn.to/2HFqIc4

Amazon Germany : https://amzn.to/2r8gfyr

OLED Display:

Banggood: https://www.banggood.com/0_96-Inch-4Pin-Blue-Yellow-IIC-I2C-OLED-Display-Module-For-Arduino-p-969144.html?p=W214159476515201703B&cur_warehouse=CN

Amazon US: http://amzn.to/2tNAw0X

Amazon Germany: http://amzn.to/2Dt9bk6

Dupont Wire

Banggood: https://www.banggood.com/40pcs-20cm-Male-To-Female-Jumper-Cable-Dupont-Wire-For-Arduino-p-973822.html?p=W214159476515201703B&rmmds=search&cur_warehouse=CN

Amazon US: http://amzn.to/2FISFmg

Amazon Germany: http://amzn.to/2pkj27N

Keyes-40

The rotary encoder that I am using for this project is called Keyes-40. You can download the datasheet from here .

Pinout:

The Keyes-40 rotary encoder has 5 pins namely

VCC – 5V power supply

GND – Ground

CLK – Encoder Pin 1

DT – Encoder Pin 2

SW – Switch (push button)

Raspberry Pi Connection:

The CLK pin is connected to pin 17 of the Raspberry Pi . The DT pin is connected to pin 18 of the Pi and SW pin is connected to pin 27 .

KY-40 – RPi

CLK – 17

DT – 18

SW – 27

Schematics:

Hardware connection:

Explanation of the working:

The rotary encoder consists of a disk with a single track. This track is connected to the ground. The sliding contacts CLK and DT remains in a fixed position. As you spin the encoder knob the shaft along with the track rotates. This makes the CLK and DT connected to common ground on every contact with the track. The track is evenly discontinuous. According to the datasheet of the rotary encoder Ky-40, both the CLK and the DT pin needs to be pulled up and this make them come back to voltage level 5V. We can derive the direction in which it is revolving by detecting the order in which the pins went low (GND). The below picture explains the digital wave pattern.

Simulate with push button:

You can very well image the rotary encoder with two push buttons connected to GPIO 17 and 18 and the other terminals to GND. Below is the schematics.

Lets name these two buttons as CLK and DT. If you press DT first and CLK second, then release DT and then CLK. This represents a direction movement, same way if you press CLK first and DT second, then release CLK and then DT , then it represents the movement is opposite direction. Remember that both the GPIO pins are assumed to be pulled up. Pulled up means that the voltage level of the pins remain at 5V and the GPIO value will be “1” and when you press the push button then the GPIO value will go to “0”.

Basic example:

With the above code the value of the variable counter increments when you spin it clockwise and decrements when you spin it anti clockwise.

Explanation:

Line no 4,5: definition of pin numbers

Line no 6,7,8: The pins numbering is set to BCM model and then the pins are configured as input and pulled up high.

Line no 9,10: Initialising variable counter and clkLastState takes the current value of the GPIO 17.

Line no 11-24: Now the block reads the value of CLK and it if the value is different from clkLastState then read the value of dt. If it differs from the value of CLK then its incrementing, otherwise it is decrementing.

Polling vs Interrupt handling:

The above code is using the polling method. In polling method, if you want to know the value of a variable or register you keep reading always or at a specific frequency and get the value. This is CPU consuming operation and this can be solved by using Interrupt based handling. In Interrupt handling you register a function called interrupt handler or irq and specify which event you are interested in.

Basic example using interrupt:

Output:

It does the same thing as the basic example did nothing more and nothing less.

Explanation:

The only difference here is that instead of doing the entire thing in a While loop infinitely we are using a interrupt handler in the form of

GPIO.add_event_detect(17, GPIO.FALLING , callback=my_callback, bouncetime=300)

Here I am adding an event detection for the pin CLK. The event will be triggered when the pin is falling from 5V to 0V. When the event happens, the callback my_callback will be called. The bounce time is the time between one call and the other call of the event. The my_callback function is just same as what was using in the basic example, but without a while true infinite loop.

Finally, the application just waiting for keyboard interrupt using raw_input function. The entire application consumes way less CPU resource than the previous example.

Creating an OLED Menu interface:

The rotary encoders are used in control system to provide user interface. The user interface includes, Menu, Text box, Keyboard, num pad etc. Here I am going to show you how to build a menu interface with custom functions.

For that you need to get OLED display interfaced with Raspberry Pi. Refer to the here for How to interface OLED display with Raspberry Pi.

Hardware connection:

Output

Code:

I copied the sys_info.py and demo_opts.py from the https://github.com/rm-hull/luma.examples to the folder, where I have the oled_rot_menu_rpi.py. As I am importing the sys_info module, you need to install psutil as shown below.

#pip install psutil

If you have any questions related to the above example, please use the comment section below. I would be glad to help you out. As always, thank you for visiting my site and keep following.