Instructables

Arduino powered Rotary Encoders - I made it at TechShop

Picture of Arduino powered Rotary Encoders - I made it at TechShop
As in some of my past instructables, arduino is all about control. The ability to control certain things like displays, servos, motors, and other electrical mechanical devices in a meaningful way. I've covered using potentiometers to determine position and how to drive 7 segmented led displays. This is continuation of that. This is how to directly control a position and display that position on a led display. A potentiometer might work, but it has large limitation. It has a set range of travel. Using a rotary encoder instead of a potentiometer we have almost no limit to how big a number can be set in the position. This might be helpful if you were trying to determine the position of a motor in rotations.

This also is an intro to interrupts. Interrupts are functions that interrupt the main function when something is triggered. Pressing reset on your computer is an interrupt. It allows for small, fast, or critical functions to work in the background.

This instructable uses shift registers to control the 7 segmented display, but they are covered in detail in another instructable. Visit that one for more info. http://www.instructables.com/id/Arduino-powered-7-seg-LED-display-using-Shift-Regi/

L
ike all my instructables, this one was made at TechShop.
http://www.techshop.ws
 
Remove these adsRemove these ads by Signing Up

Step 1: Materials

Picture of Materials
You will need all the materials from this instructable:
http://www.instructables.com/id/Arduino-powered-7-seg-LED-display-using-Shift-Regi/

PLUS

- A quadrature rotary encoder. (This means that it has 2 outputs. You need two to determine direction)
Here is an example:
https://www.sparkfun.com/products/10932

jduffy541 year ago
I tried this code, but it seems pretty glitchy and only counts full cycles. It does, however, offer a good example for interrupts and grey code (which I had never used before).
This code counts half-cycles AND is much more stable.

//rotary encoder example by jduffy54.
//this picks up rotations of a standard encoder on pins two and seven, and
//transmits the results over serial.
int r = 0;
float pos = 0;
float incr = 1; //the ammount you want it to count per step.
void setup(){
Serial.begin(115200);//set a high communication speed. using 9600 baud
//will cause the program to freeze if the encoder moves too fast
pinMode(2, INPUT);
pinMode(7, INPUT);
digitalWrite(7, HIGH);
digitalWrite(2, HIGH);//sets the pins to HIGH if no signal is present
//if it is pulled low, the pins will register it.

attachInterrupt(0, encoderPos, CHANGE); //go to the new void if pin two changes
//this allows us to double the resolution of the encoder.

}

void loop(){
delay(0.1);//we don't need the loop to do anything, just the interrupts
}


void encoderPos(void){ //this is a state machine to determine the direction of the encoder.
//every half-cycle it counts, effectively doubling the encoder resolution.
r = 1;
if(digitalRead(2) == HIGH){
if(digitalRead(7) == LOW){
while(r == 1){
if(digitalRead(2) == LOW){
r = 0;
} else {
if(digitalRead(7) == HIGH){
pos = pos + incr;
r = 0;
}}}



}
else {
while(r == 1){
if(digitalRead(2) == LOW){
r = 0;
} else {
if(digitalRead(7) == LOW){
pos = pos - incr;
r = 0;
}}}
}
Serial.print(pos);
}else{//same as the above code, but with High-Low reversed.
r = 1;
if(digitalRead(7) == HIGH){
while(r == 1){
if(digitalRead(2) == HIGH){
r = 0;
} else {
if(digitalRead(7) == LOW){
pos = pos + incr;
r = 0;
}}}



}
else {
while(r == 1){
if(digitalRead(2) == HIGH){
r = 0;
} else {
if(digitalRead(7) == HIGH){
pos = pos - incr;
r = 0;
}}}
}
Serial.print(pos);
}}
nice use of interrupts. are you planning on using this rotary encoder in any other projects?
madebyjoe (author)  amandaghassaei2 years ago
Not currently planned for any more instructables, but I am currently using a few in some of my private projects. I particularly like the ones I'm using here though.