Rotary encoder with Raspberry Pi – OLED Menu interface – Python

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 platform etc. They are also used to track the position  of the motor shaft on brush less motors with permanent magnet which are are used in robot and CNC machines.

According to wikipedia the definition of 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 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 .

Rotary encoder with Raspberry Pi

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:

Rotary encoder with Raspberry Pi

Hardware connection:

Rotary encoder with Raspberry Pi

Explanation of the working:

The rotary encoder consist 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 discontinous. 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.

Rotary encoder with Raspberry Pi

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

Rotary encoder with Raspberry Pi

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 then GPIO value when you read 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: defintion 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 even happens the callback my_callback will be called. The bouncetime 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.

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

Creating a OLED Menu interface:

The rotary encoder are used in control system to provide user interface. The user inteface includes, Menu, Textbox, Keyboard, numpad etc. Here I am going to show you how to build a menu interface with custom functions.

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

Hardware connection:

Rotary encoder with Raspberry Pi

Output

Code:

I copied the sys_info.py and demo_opts.py from the https://github.com/rm-hull/luma.examples and copied to the folder where i have my oled_rot_menu_rpi.py since I am importing the sys_info module.Additionally you need to install psutil.

#pip install psutil

If you have any questions related to the above example, please use the comment section to as the question, I will be glad to help you out. As Always Thanks for visiting my site and keep following.

Rotary encoder with Raspberry Pi

Leave a Reply

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