Pages: [1]   Go Down
Author Topic: rotary encoder  (Read 1656 times)
0 Members and 1 Guest are viewing this topic.
austria
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hi there,

i got a rotary encoder from sparkfun which i have connected to a arduino nano. i am using the following code:

Code:
int pulses, A_SIG=0, B_SIG=1;

void setup(){
  attachInterrupt(0, A_RISE, RISING);
  attachInterrupt(1, B_RISE, RISING);
  Serial.begin(115200);
}//setup


void loop(){
   
}

void A_RISE(){
 detachInterrupt(0);
 A_SIG=1;
 
 if(B_SIG==0)
 pulses++;//moving forward
 if(B_SIG==1)
 pulses--;//moving reverse
 Serial.println(pulses);
 attachInterrupt(0, A_FALL, FALLING);
}

void A_FALL(){
  detachInterrupt(0);
 A_SIG=0;
 
 if(B_SIG==1)
 pulses++;//moving forward
 if(B_SIG==0)
 pulses--;//moving reverse
 Serial.println(pulses);
 attachInterrupt(0, A_RISE, RISING); 
}

void B_RISE(){
 detachInterrupt(1);
 B_SIG=1;
 
 if(A_SIG==1)
 pulses++;//moving forward
 if(A_SIG==0)
 pulses--;//moving reverse
 Serial.println(pulses);
 attachInterrupt(1, B_FALL, FALLING);
}

void B_FALL(){
 detachInterrupt(1);
 B_SIG=0;
 
 if(A_SIG==0)
 pulses++;//moving forward
 if(A_SIG==1)
 pulses--;//moving reverse
 Serial.println(pulses);
 attachInterrupt(1, B_RISE, RISING);
}

and, as i am a newbee, i am in trouble smiley   when i start serial monitor i get some numbers coming in and when i turn the encoder also something is happening but not what i want. also numbers are changing when i touch the cables sometimes. so my guess is that i need some kind of pullup oder pulldown resistors somewhere. would someone be so nice and help me out here?

i connected the middle pin of the encoder to gnd on the arduino and the left and right pins to digital 2 and 3. and i do not know much about electronics.

have a nice day!
Logged

0
Offline Offline
Edison Member
*
Karma: 7
Posts: 1411
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sparkfun usually has some documentation and/or sample code for their products (links after the product description).
Did you check there?
Logged

More Cowbell
Offline Offline
Edison Member
*
Karma: 11
Posts: 1030
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I figured out rotary encoders by experimenting with code on this page:

http://www.arduino.cc/playground/Main/RotaryEncoders

I tried several before I got it to work to my satisfaction.  I think the one that worked best for me is under "Another Interrupt Library THAT REALLY WORKS (the Encoder interrupts the processor and debounces like there is no tomorrow)."

I will say, you never do a PinMode(0, INPUT) and PinMode(1, INPUT) which may be necessary.  
Logged

Vexatious Sampler

austria
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i tried several sketches but the one that works for me is :

Code:

/*
(Copy and paste)

Rotary encoder decoding using two interrupt lines.
Most Arduino boards have two external interrupts,
numbers 0 (on digital pin 2) and 1 (on digital pin 3).

Program sketch is for SparkFun Rotary Encoder sku: COM-09117
Connect the middle pin of the three to ground.
The outside two pins of the three are connected to
digital pins 2 and 3
*/


volatile int number = 0;                // Testnumber, print it when it changes value,
                                        // used in loop and both interrupt routines
int oldnumber = number;

volatile boolean halfleft = false;      // Used in both interrupt routines
volatile boolean halfright = false;


void setup(){
  Serial.begin(9600);
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);                // Turn on internal pullup resistor
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);                // Turn on internal pullup resistor
  attachInterrupt(0, isr_2, FALLING);   // Call isr_2 when digital pin 2 goes LOW
  attachInterrupt(1, isr_3, FALLING);   // Call isr_3 when digital pin 3 goes LOW
}

void loop(){
  if(number != oldnumber){              // Change in value ?
    Serial.println(number);             // Yes, print it (or whatever)
    oldnumber = number;
  }
}

void isr_2(){                                              // Pin2 went LOW
  delay(1);                                                // Debounce time
  if(digitalRead(2) == LOW){                               // Pin2 still LOW ?
    if(digitalRead(3) == HIGH && halfright == false){      // -->
      halfright = true;                                    // One half click clockwise
    } 
    if(digitalRead(3) == LOW && halfleft == true){         // <--
      halfleft = false;                                    // One whole click counter-
      number--;                                            // clockwise
    }
  }
}
void isr_3(){                                             // Pin3 went LOW
  delay(1);                                               // Debounce time
  if(digitalRead(3) == LOW){                              // Pin3 still LOW ?
    if(digitalRead(2) == HIGH && halfleft == false){      // <--
      halfleft = true;                                    // One half  click counter-
    }                                                     // clockwise
    if(digitalRead(2) == LOW && halfright == true){       // -->
      halfright = false;                                  // One whole click clockwise
      number++;
    }
  }
}

i found it here : http://home.online.no/~togalaas/rotary_encoder/

just for other ones who have troubles with this. i am solved smiley
Logged

More Cowbell
Offline Offline
Edison Member
*
Karma: 11
Posts: 1030
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Maybe because that example sets the PinMode to input...   smiley-yell
Logged

Vexatious Sampler

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure, you can use 2 interrupts to manage a rotary encoder, but it is a bit of a waste of interrupts. I poll rotary encoders every 1 to 2 milliseconds instead, which also allows me to multiplex them (I've just completed a design that uses 3 rotary encoders multiplexed on to 2 input pins). You can find the code I use at http://miscsolutions.wordpress.com/2011/10/16/five-things-i-never-use-in-arduino-projects/.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

More Cowbell
Offline Offline
Edison Member
*
Karma: 11
Posts: 1030
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure, you can use 2 interrupts to manage a rotary encoder, but it is a bit of a waste of interrupts. I poll rotary encoders every 1 to 2 milliseconds instead, which also allows me to multiplex them (I've just completed a design that uses 3 rotary encoders multiplexed on to 2 input pins). You can find the code I use at http://miscsolutions.wordpress.com/2011/10/16/five-things-i-never-use-in-arduino-projects/.

I have a circuit that uses a couple of flip-flops and a counter that keeps the rotary encoder count without any processor involvement and you can get back to it once a second or once a minute, whatever works for you, but it takes a bunch of extra chips.  My first project I am going to do with a CPLD when I get that figured out is to put this circuit into my CPLD and hopefully give it multiple channels.
Logged

Vexatious Sampler

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1023
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

US Digital sells a chip that connects to the encoder and has a count up, count down output.
Logged

More Cowbell
Offline Offline
Edison Member
*
Karma: 11
Posts: 1030
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

US Digital sells a chip that connects to the encoder and has a count up, count down output.

Damn it, they stole my idea!  Or I stole their idea.  One or the other.  That was going to be my first CPLD project, now it will have to be better than their implementation (larger count or more channels at least) or I need a new project.

Link to this chip?
Logged

Vexatious Sampler

More Cowbell
Offline Offline
Edison Member
*
Karma: 11
Posts: 1030
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Found it.  http://usdigital.com/products/interfaces/ics/lfls7083

Quote
The LSI Computer Systems LFLS7083 allow incremental shaft encoders to drive standard up/down counters. Connect the encoder quadrature outputs to the A and B inputs. The LFLS7083 outputs can connect directly to the up and down clock inputs of counters such as 74193 or 40193.

The next generation Encoder to Counter Interface chips are now available and recommended for new applications (DIP package, LFLS7183 / LFLS7184, or SOIC package, LFLS7183-S / LFLS7184-S ).

Well, that is not super impressive.  This is my circuit, without the 74193 counters.  Which means it is replacing two flip-flops and an inverter.  I think I can do better. smiley
Logged

Vexatious Sampler

Pages: [1]   Go Up
Jump to: