Get tutorials Raspberry Pi Super Kit V2.0 for RaspberryPi

Lesson 8 Rotary Encoder

Introduction

A rotary encoder is a type of electro-mechanical device that converts the angular position or motion of a shaft or axle to an analog or digital code. In this lesson, we will learn how to use this device.


Components

- 1* Raspberry Pi

- 1* Breadboard

- 1* Rotary Encoder Module

- Jumper wires


Principle

A rotary encoder is an electronic switch with a set of regular pulses with strictly timing sequence. When used with IC, it can achieve increment, decrement, page turning and other operations such as mouse scrolling, menu selection, acoustic sound regulation, frequency regulation, toaster temperature regulation, and so on.

 

There are mainly two types of rotary encoders: absolute and incremental (relative) encoders. The output of absolute encoders indicates the current position of the shaft, making them angle transducers. The output of incremental encoders provides information about the motion of the shaft, which is typically further processed elsewhere into information such as speed, distance, and position.


 

Most rotary encoders have 5 pins with three functions of turning left, turning right and pressing down:

Pin 4 & 5: switching wiring terminals for pressing down. (no different from the buttons mentioned previously, so no more details will be provided here.)

Pin 2: generally connected to ground.

Pin 1 & 3: first connected to a pull-up resistor and then to a microprocessor(in this experiment, to GPIO0 and GPIO1 of Raspberry Pi); when you spin the knob of the encoder clockwise and counterclockwise, there will be pulse outputs in pin 1 and pin 3.


If both GPIO0 and GPIO1 are at high level, the switch rotates clockwise; if GPIO0 is at high level but GPIO1 is low, the switch rotates counterclockwise. Therefore, when programming, you only need to check the state of pin 3 when pin 1 is at high level, and then you can tell whether the switch rotates clockwise or counterclockwise.


Experimental Procedures

Step 1: Build the circuit

 

Raspberry Pi                       Rotary Encoder Module

3.3V                                          ‘+’

GND                                         GND

GPIO0                                       DT

GPIO1                                       CLK


For C language users:

Step 2: Change directory

cd /home/pi/Sunfounder_SuperKit_C_code_for_RaspberryPi/08_RotaryEncoder/


Step 3: Compile

       gcc rotaryEncoder.c –o rotaryEncoder -lwiringPi


Step 4: Run

       sudo ./rotaryEncoder


For Python users:

Step 2: Change directory

cd /home/pi/Sunfounder_SuperKit_ Python_code_for_RaspberryPi/


Step 3: Run

         sudo python 08_rotaryEncoder.py

 

Now, gently rotate the encoder to change the value of the variable in the above program, and you will see the value printed on the screen. Rotate the encoder clockwise, the value will increase; or rotate it counterclockwise, the value will decrease.


 

Further Exploration

In this experiment, the pressing down function of rotary encoder is not involved. Try to explore this function by yourself !



C Code

/**********************************************************************
* Filename    : rotaryEncoder.c
* Description : make a rotaryEncoder work.
* Author      : Robot
* E-mail      : support@sunfounder.com
* website     : www.sunfounder.com
* Date        : 2014/08/27
**********************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>

#define  RoAPin    0
#define  RoBPin    1
#define  RoSPin    2

static volatile int globalCounter = 0 ;

unsigned char flag;
unsigned char Last_RoB_Status;
unsigned char Current_RoB_Status;

void rotaryDeal(void)
{
	Last_RoB_Status = digitalRead(RoBPin);

	while(!digitalRead(RoAPin)){
		Current_RoB_Status = digitalRead(RoBPin);
		flag = 1;
	}

	if(flag == 1){
		flag = 0;
		if((Last_RoB_Status == 0)&&(Current_RoB_Status == 1)){
			globalCounter ++;
			printf("globalCounter : %d\n",globalCounter);
		}
		if((Last_RoB_Status == 1)&&(Current_RoB_Status == 0)){
			globalCounter --;
			printf("globalCounter : %d\n",globalCounter);
		}

	}
}

void rotaryClear(void)
{
	if(digitalRead(RoSPin) == 0)
	{
		globalCounter = 0;
		printf("globalCounter : %d\n",globalCounter);
		delay(1000);
	}
}

int main(void)
{
	if(wiringPiSetup() < 0){
		fprintf(stderr, "Unable to setup wiringPi:%s\n",strerror(errno));
		return 1;
	}

	pinMode(RoAPin, INPUT);
	pinMode(RoBPin, INPUT);
	pinMode(RoSPin, INPUT);

	pullUpDnControl(RoSPin, PUD_UP);

	while(1){
		rotaryDeal();
		rotaryClear();
	}

	return 0;
}


Python Code

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time

RoAPin = 11    # pin11
RoBPin = 12    # pin12
RoSPin = 13    # pin13

globalCounter = 0

flag = 0
Last_RoB_Status = 0
Current_RoB_Status = 0

def setup():
	GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
	GPIO.setup(RoAPin, GPIO.IN)    # input mode
	GPIO.setup(RoBPin, GPIO.IN)
	GPIO.setup(RoSPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)
	rotaryClear()

def rotaryDeal():
	global flag
	global Last_RoB_Status
	global Current_RoB_Status
	global globalCounter
	Last_RoB_Status = GPIO.input(RoBPin)
	while(not GPIO.input(RoAPin)):
		Current_RoB_Status = GPIO.input(RoBPin)
		flag = 1
	if flag == 1:
		flag = 0
		if (Last_RoB_Status == 0) and (Current_RoB_Status == 1):
			globalCounter = globalCounter + 1
			print 'globalCounter = %d' % globalCounter
		if (Last_RoB_Status == 1) and (Current_RoB_Status == 0):
			globalCounter = globalCounter - 1
			print 'globalCounter = %d' % globalCounter

def clear(ev=None):
        globalCounter = 0
	print 'globalCounter = %d' % globalCounter
	time.sleep(1)

def rotaryClear():
        GPIO.add_event_detect(RoSPin, GPIO.FALLING, callback=clear) # wait for falling


def loop():
	global globalCounter
	while True:
		rotaryDeal()
#		print 'globalCounter = %d' % globalCounter

def destroy():
	GPIO.cleanup()             # Release resource

if __name__ == '__main__':     # Program start from here
	setup()
	try:
		loop()
	except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child program destroy() will be  executed.
		destroy()


Video


Copyright © 2012 - 2016 SunFounder. All Rights Reserved.


Previous chapter: Lesson 7 How to Drive a DC Motor

Next chapter: Lesson 9 555 Timer

SunFounder
Apr 05 2017 at 01:22 am



© Developed by CommerceLab