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;
  }
}

closed as unclear what you're asking by gre_gor, sempaiscuba, Greenonline, MatsK, Juraj Oct 12 '18 at 19:18

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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.