[TriEmbed] Quadrature encoder help

Rodney Radford ncgadgetry at gmail.com
Mon Sep 12 22:45:31 CDT 2016


I am adding a quadrature encoder to a project I am working on, but having a
problem understanding why this is not working.

I have used quadrature encoders before, implementing them with 0, 1, and 2
interrupt lines.  In this case, I only have one interrupt line available so
I am interrupting on one channel and checking the other.

I know this is possible, but I have a bug in the code below and I can't
seem to find it.

What am I missing?


/*
 * Simple quadrature encoder implementation.  I only have one interrupt
available (as I
 *    am using the other for another purpose on this project), so I can
only watch one
 *    of the two encoder pins.  While this reduces the number of
transitions per revolution
 *    that is okay for this purpose.
 *
 * When running this, I only see a stream of 0 and 1 values for the
encoderValue - what am
 *    I doing wrong?
 */
#include "Arduino.h"

int encoderA = 3;   // This one is an interrupt pin
int encoderB = 4;   // This is a standard (not interrupt) pin

volatile int  lastB = 0;
volatile long encoderValue = 0;

void updateEncoder(void);

/*
 * Setup the input pins and attach our interrupt vector
 */
void setup() {
   Serial.begin(9600);

   // Set both quadrature channels to input and turn on pullup resistors
   pinMode(encoderA, INPUT);
   pinMode(encoderB, INPUT);
   digitalWrite(encoderA, HIGH);
   digitalWrite(encoderB, HIGH);

   // invoke interrupt routine on each falling edge of encoderA
   attachInterrupt(1, updateEncoder, FALLING);
}


/*
 * Simply print out the encoder value (at a reasonable rate)
 */
void loop() {

  Serial.println(encoderValue);
  delay(100);
}


/*
 * This interrupt routine is called on each falling edge of encoder channel
A. We
 *   look at the B edge to to determine if we are counting up, down, or
staying in
 *   the same location.
 * Note if we only looked at the current B (and not the previous B), we
would get
 *   duplicate up/down counts on every transition due to non-debounced
quadrature
 *   signals.
 */
void updateEncoder(void) {

  // read the current encoderB value
  int newB = (digitalRead(encoderB) & 0x1);

  // create the 'transition' variable - show both old and new states - if
00 or 11
  //    this is a duplicate falling edge (not moved), but if 01 or 10, we
have moved
  int transition = (lastB << 1) | newB;

  // are we counting up, down, or staying the same location?
  switch (transition) {
      // transitioned from a 0 -> 1 edge, so counting up
      case B01:
           encoderValue++;
           break;
      // transitioned from a 1 -> 0 edge, so counting down
      case B10:
           encoderValue--;
           break;
  }

   // Save current encoderB value for next transition variable
   lastB = newB;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.triembed.org/pipermail/triembed_triembed.org/attachments/20160912/143668e5/attachment.htm>


More information about the TriEmbed mailing list