Another illustration that demonstrate using rotary encoder. Rotary encoder is an electro mechanical device that convert the angular position or a motion of a shaft or axle to analog or digital code. Rotary encoder are usually used at the side which is perpendicular to the shaft. They act as sensors for detecting angle, speed, length, position and acceleration in automation field. As you turn the knob you will hear a sound from the knob indicating that one position has been rotated. If the internal contact were originally HIGH after a single click they would now both in LOW state breaking the circuit.
With a simple bit of logic you can work out the direction of the rotation. Most rotary encoder has a 5 pins with 3 functions or tuning left, right and pressing down. Pin 1 and Pin 2 are switch wiring terminals used to press. They are similar to buttons. Pin 4 usually placed in ground and the Pin 3 and Pin 5 are first connected to pull up resistor and then wired to the microcontroller. The diagram below demonstrates the right and left rotation pulse.
Incremental encoder provides two phase square wave, these phase difference are 90 degree, usually called A and B channel. The rotational speed of a channel related information is given, while the two channel signal by comparing the sequence detail obtained in the rotation direction. There is a unique signal called the (Z) or zero channel that provided the absolute encoder zero, this signal is a square wave accord with the center line of the channel (A) square wave.
Accuracy depends on mechanical and electrical factors, these issues are indexing errors, disc eccentricity, bearing eccentric, electronic device errors and inaccuracies introduced by optical parts. The encoder determines the degree of accuracy of the measurement unit and electrical pulses generated by the encoder stars. The following degrees rotation of the mechanical axis to represent, and the axis of rotation must be a complete cycle. You have to know how much the equivalent of a 360 degree electrical angle, you can use these formula to calculate the degree. 360 = 360*/n* pulse / revolution.
Components Required
- Raspberry Pi / Banana Pi / Orange Pi (If your using Banana Pi or Orange See first the GPIO Pins)
- Rotary Encode
- Solder Less Bread Board
- Jumper Wire / DuPont Wire
Wiring Guide
C Code / Wiring Pi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
#include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <wiringPi.h> #define RotateAPin 4 //Define as CLK #define RotateBPin 5 // Define as DT #define SwitchPin 1 // Define as Push Button Switch static volatile int globalCounter = 0 ; unsigned char flag; unsigned char Last_RoB_Status; unsigned char Current_RoB_Status; void btnISR(void) { globalCounter = 0; } void rotaryDeal(void) { Last_RoB_Status = digitalRead(RotateBPin); while(!digitalRead(RotateAPin)){ Current_RoB_Status = digitalRead(RotateBPin); flag = 1; } if(flag == 1){ flag = 0; if((Last_RoB_Status == 0)&&(Current_RoB_Status == 1)){ globalCounter ++; } if((Last_RoB_Status == 1)&&(Current_RoB_Status == 0)){ globalCounter --; } } } int main(void) { if(wiringPiSetup() < 0){ fprintf(stderr, "Unable to initialize wiringPi:%s\n",strerror(errno)); return 1; } pinMode(SwitchPin, INPUT); pinMode(RotateAPin, INPUT); pinMode(RotateBPin, INPUT); pullUpDnControl(SwitchPin, PUD_UP); if(wiringPiISR(SwitchPin, INT_EDGE_FALLING, &btnISR) < 0){ fprintf(stderr, "Unable to init ISR\n",strerror(errno)); return 1; } int tmp = 0; while(1){ rotaryDeal(); if (tmp != globalCounter){ printf("%d\n", globalCounter); tmp = globalCounter; } } return 0; } |
Python Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#!/usr/bin/env python import RPi.GPIO as GPIO import time RotateAPin = 16 # Define as CLK Pin RotateBPin = 18 # Define as DT Pin SwitchPin = 12 # Define as Push Button Pin globalCounter = 0 flag = 0 Last_RoB_Status = 0 Current_RoB_Status = 0 def setup(): GPIO.setmode(GPIO.BOARD) # Set GPIO pin as numbered GPIO.setup(RotateAPin, GPIO.IN) # Set to input mode GPIO.setup(RotateBPin, GPIO.IN) # Set to input mode GPIO.setup(SwitchPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) def rotaryDeal(): global flag global Last_RoB_Status global Current_RoB_Status global globalCounter Last_RoB_Status = GPIO.input(RotateBPin) while(not GPIO.input(RotateAPin)): Current_RoB_Status = GPIO.input(RotateBPin) flag = 1 if flag == 1: flag = 0 if (Last_RoB_Status == 0) and (Current_RoB_Status == 1): globalCounter = globalCounter + 1 if (Last_RoB_Status == 1) and (Current_RoB_Status == 0): globalCounter = globalCounter - 1 def btnISR(channel): global globalCounter globalCounter = 0 def loop(): global globalCounter tmp = 0 # Rotary Temperary GPIO.add_event_detect(SwitchPin, GPIO.FALLING, callback=btnISR) while True: rotaryDeal() if tmp != globalCounter: print 'globalCounter = %d' % globalCounter tmp = 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() |
Downloads
Download TW700198 Rotary Encoder Datasheet | PDF
Why this C program is consuming almost 100% CPU
Chick the code line While and should be return to 0 ) or perhaps there is a technical issues in your rotary coder.