Go Down

Topic: Rotary encoder on UNO and interrupts issue (Read 75 times) previous topic - next topic

pat333

Oct 30, 2014, 02:05 pm Last Edit: Oct 30, 2014, 07:23 pm by pat333
Hello,

This question is regarding a project using Arduino UNO.

I have one of these quadrature rotary encoders: https://www.sparkfun.com/products/11102

I'm using a slightly modified version of the code from this article:

http://www.hessmer.org/blog/2011/01/30/quadrature-encoder-too-fast-for-arduino, which uses a library called digitalwritefast (https://code.google.com/p/digitalwritefast/)

My version of the code is below - I modified to use different pins for the UNO and a single encoder.

Code: [Select]

#include <digitalWriteFast.h>  // library for high performance reads and writes by jrraines
 
#define c_LeftEncoderInterrupt 0
#define c_LeftEncoderPinA 2
#define c_LeftEncoderPinB 3
 
volatile bool _LeftEncoderBSet;
volatile long _LeftEncoderTicks = 0;
 
void setup()
{
  Serial.begin(115200);
  pinMode(c_LeftEncoderPinA, INPUT);     
  digitalWrite(c_LeftEncoderPinA, LOW);
  pinMode(c_LeftEncoderPinB, INPUT);
  digitalWrite(c_LeftEncoderPinB, LOW);
  attachInterrupt(c_LeftEncoderInterrupt, HandleLeftMotorInterruptA, RISING);
}
 
// Interrupt service routines for the left motor's quadrature encoder
void HandleLeftMotorInterruptA()
{
  _LeftEncoderBSet = digitalReadFast2(c_LeftEncoderPinB);   // read the input pin
  _LeftEncoderTicks -= _LeftEncoderBSet ? -1 : +1;
}
 
void loop()
{
  Serial.print(_LeftEncoderTicks);
  Serial.print("\n");
  delay(20);
}


When running the above, I am attaching output A of the encoder to pin 2 and output B to pin 3.

This setup works fine and I can detect turns in both directions, but my problem is, if I set pin B to any other pin (and c_LeftEncoderPinB accordingly), I get positive direction only (regardless of the direction in which the encoder is turned) - as if pin B isn't plugged in at all

I'm assuming that this is something to do with pin 3 being the only other interrupt pin on the UNO (I can't see anything else unique about that pin). Yet I don't know why because the interrupt is on pin A (we're reading the value of pin B in that interrupt, though)

Any ideas?

Thanks

Paulcet

I don't see this:
Code: [Select]
    #else
_LeftEncoderTicks += _LeftEncoderBSet ? -1 : +1;

in your code.

I believe your code on pastebin only goes one direction.

pat333

#2
Oct 30, 2014, 03:21 pm Last Edit: Oct 30, 2014, 03:48 pm by pat333
Hi Paulcet,

That's line 24:

 _LeftEncoderTicks -= _LeftEncoderBSet ? -1 : +1;

The code works for both directions, but only if output B is attached to pin 3. Any other pin, and it doesn't work.

EDIT: Just noticed your code was +=, not -=. Whether ticks adds or subtracts is conditional on the ternary operator (it subtracts if B is HIGH, adds otherwise). It doesn't need a separate +=

cattledog

#3
Oct 30, 2014, 06:50 pm Last Edit: Oct 30, 2014, 06:54 pm by cattledog
pat333

I see that you are new to the forum, and the first word of advice is to post your actual code within the code tags
Code: [Select]
which are found at icon with <>which is second from the right in the tool bar. You can modify your initial post to do this. You will get many more people looking at your code than when they have to follow a link off site to pastebin.

Here's some thoughts on your problem.

1). I see that you are configuring your pins as INPUT, and then writing them LOW which means that you should be using external pullup or pulldown resistors. Have you switched the pull up/down hardware to the new pin? You may want to consider using INPUT_PULLUP. 

2). I would try your sketch using the standard digitalRead and see if it still has problems with your using a pin which is not Pin3.

3) Please post the exact code you are using which does not recognize the alternate to pin3.



Go Up