0

I have the following code working correctly except for the Index portion. I am not sure if I have the syntax correct for the hardware. The end result I am looking for is to have the encoder reset to 0 degrees every time the index comes around (360 degrees). I am also looking for any comments on the code as I would like the encoder output to be as accurate and efficient as possible.

Here is the code:

// Wiring connections for my encoder:
// Brown : VCC = 5V
// Blue + Shield : 0V = GND
// Black : ENCODER0PINA, Pin 20
// White : ENCODER0PINB, Pin 17
// Orange : ENCODER0PINI, Pin 19

#define ENCODER0PINA         20      // this pin needs to support interrupts
#define ENCODER0PINB         17      // no interrupt required
#define ENCODER0PINI         19      // this pin needs to support interrupts
#define CLOCKWISE            1       // direction constant
#define COUNTER_CLOCKWISE    2       // direction constant

// variables modified by interrupt handler must be declared as volatile
volatile long encoder0Position = 0;
volatile long interruptsReceived = 0;
volatile byte INTFLAG1 = 0;

// track last position so we know whether it's worth printing new output
long previousPosition = 0;

void setup()
{

  // inputs
  pinMode(ENCODER0PINA, INPUT_PULLUP);
  pinMode(ENCODER0PINB, INPUT_PULLUP);
  pinMode(ENCODER0PINI, INPUT_PULLUP);

  // interrupts
  attachInterrupt(3, onInterrupt, RISING);
  attachInterrupt(4, onReset, CHANGE);

  // enable diagnostic output
  Serial.begin (9600);
  Serial.println("Ready.");
}

void loop()
{
  // only display position info if has changed
  if (encoder0Position != previousPosition )
  {
    Serial.println(encoder0Position, DEC);

    previousPosition = encoder0Position;
  }
}

// interrupt function needs to do as little as possible
void onInterrupt()
{
  // read both directional inputs
  int a = digitalRead(ENCODER0PINA);
  int b = digitalRead(ENCODER0PINB);

  if (a == b )
  {
    // b is leading a (counter-clockwise)
    encoder0Position--;
    if (encoder0Position < 0)
    {
      encoder0Position = (encoder0Position + 360);
    }
  }
  else
  {
    // a is leading b (clockwise)
    encoder0Position++;
    if (encoder0Position >= 360)
    {
      encoder0Position = (encoder0Position - 360);
    }
  }

void onReset()
{
  // read Index input
  int i = digitalRead(ENCODER0PINI);

  if (i = 1)
  {
  encoder0Position = 0;
  }
}
  • 2
    except for the Index portion is not a good description of the observed behavior .... please clarify what that means – jsotola Oct 9 '18 at 0:03
2

In your onReset() function you have an assignment instead of a comparison:

if (i = 1) // This is always true
{
encoder0Position = 0;
}

i = 1 should be i == 1

  • Craig, is that the proper syntax for an Optical Encoder, if (i == 1)? I am not sure if that is the output of the interrupt? – Bkukuk62 Oct 8 '18 at 21:53
  • if (i == 1) is correct. – sa_leinad Oct 9 '18 at 0:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.