0

I have corrected my code for reading the optical encoder index but I am now getting a different calculation error. At the index the encoder reset's to zero but now my readouts are as follows: Index point - resets to zero. - At the 90 degree rotation mark I have a readout of 180 degrees. - At the 180 degree rotation mark I have a readout of 0 because the code has it reset to zero after 359 degrees. - At the 270 degree rotation mark I have a readout of 180 degrees. - At the 0 degree mark it is zero again and that's what I would expect from the index. If I restart the Arduino Mega at the 270 degree mark, the index resets itself to zero like it should. Being new to this, before I had the index working it was working correctly minus the index function, now it seems to be double counting. Any ideas?

// 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

// 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);
  digitalWrite(ENCODER0PINA, HIGH);  // turn on pullup resistor
  pinMode(ENCODER0PINB, INPUT);
  digitalWrite(ENCODER0PINB, HIGH);  // turn on pullup resistor
  pinMode(ENCODER0PINI, INPUT);
  digitalWrite(ENCODER0PINI, HIGH);  // turn on pullup resistor

  // interrupts
  attachInterrupt(3, onInterrupt, CHANGE);  // encoder track A on interrupt 3 - pin 20
  attachInterrupt(4, onReset, CHANGE);  // encoder Index track on interrupt 4 - pin 19

  // enable diagnostic output
  Serial.begin (115200);
  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 onReset()
{
  // read Index input
  int i = digitalRead(ENCODER0PINI);
  if (i == 1)
  {
  encoder0Position = INTFLAG1;
  }
}

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);
    }
  }
}
8
  • please format your code as "code" .... highlight all the code text and click the {} button
    – jsotola
    Commented Oct 31, 2018 at 1:48
  • I did it for him/her.
    – Delta_G
    Commented Oct 31, 2018 at 2:47
  • Thank you, I was wondering how to get the code to format as "code". (him).
    – Bkukuk62
    Commented Oct 31, 2018 at 3:07
  • 1
    What is the encoder that you are using? Does it have a 0.5 degree increment? Commented Oct 31, 2018 at 3:53
  • It is a Omron E6B2-CWZ6C Incremental Rotary Encoder w/Index (360P/R).
    – Bkukuk62
    Commented Oct 31, 2018 at 13:18

1 Answer 1

1

I have figured out my issue, at least I am getting good results. With this code I had to change interrupts from CHANGE to RISING. I want to thank everyone that has made comments on this question. –

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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