Go Down

Topic: making an encoder count backwards (Read 390 times) previous topic - next topic


Hi. I've been playing with bits of code on this page http://www.arduino.cc/playground/Main/RotaryEncoders to get my shiny new optical encoder working as a motor controller.

I started with this one
Code: [Select]
//PIN's definition
#define encoder0PinA  2
#define encoder0PinB  3

volatile int encoder0Pos = 0;
volatile boolean PastA = 0;
volatile boolean PastB = 0;

void setup()

  pinMode(encoder0PinA, INPUT);
  //turn on pullup resistor
  //digitalWrite(encoder0PinA, HIGH); //ONLY FOR SOME ENCODER(MAGNETIC)!!!!
  pinMode(encoder0PinB, INPUT);
  //turn on pullup resistor
  //digitalWrite(encoder0PinB, HIGH); //ONLY FOR SOME ENCODER(MAGNETIC)!!!!
  PastA = (boolean)digitalRead(encoder0PinA); //initial value of channel A;
  PastB = (boolean)digitalRead(encoder0PinB); //and channel B

//To speed up even more, you may define manually the ISRs
// encoder A channel on interrupt 0 (arduino's pin 2)
  attachInterrupt(0, doEncoderA, RISING);
// encoder B channel pin on interrupt 1 (arduino's pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);


void loop()

//your staff....ENJOY! :D

//you may easily modify the code  get quadrature..
//..but be sure this whouldn't let Arduino back!
void doEncoderA()
     PastB ? encoder0Pos--:  encoder0Pos++;

void doEncoderB()
     PastB = !PastB;

which worked well apart from the fact that the direction differed every time I used it, and it seemed to depend on which direction it was turned to begin with. This was not acceptable for motor control!

So I'm now looking at this one -

Code: [Select]
enum PinAssignments {
  encoderPinA = 2,
  encoderPinB = 3,
  clearButton = 8

volatile unsigned int encoderPos = 0;
unsigned int lastReportedPos = 1;

boolean A_set = false;
boolean B_set = false;

void setup() {

  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(clearButton, INPUT);
  digitalWrite(encoderPinA, HIGH);  // turn on pullup resistor
  digitalWrite(encoderPinB, HIGH);  // turn on pullup resistor
  digitalWrite(clearButton, HIGH);

// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);


void loop(){
  if (lastReportedPos != encoderPos) {
    Serial.print(encoderPos, DEC);
    lastReportedPos = encoderPos;
  if (digitalRead(clearButton) == LOW)  {
    encoderPos = 0;

// Interrupt on A changing state
void doEncoderA(){
  // Test transition
  A_set = digitalRead(encoderPinA) == HIGH;
  // and adjust counter + if A leads B
  encoderPos += (A_set != B_set) ? +1 : -1;

// Interrupt on B changing state
void doEncoderB(){
  // Test transition
  B_set = digitalRead(encoderPinB) == HIGH;
  // and adjust counter + if B follows A
  encoderPos += (A_set == B_set) ? +1 : -1;

Which works well but for one thing, when it counts below zero it goes to 65535 rather than -1 (which I need), and is the way the first example works.  Is there a way I can either make the second example count decreasing values below zero as negative numbers, or make the first example count in the same direction every time?

Thanks guys


remove the keyword unsigned at the appropiate place ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up