Quadrature Encoder and interrupts

Hi everyone,
I am relatively new to the Arduino community, and out of curiosity I decided to play around with a quadrature encoder, which is attached to a motor. I know there are a bunch of encoder libraries out there already. However, I wanted to try creating a simpler version on my own as I thought it might give me a better understanding of what the other libraries have already done.

Background information on my project:

• As of right now I’m not controlling the motor, I just attempting to move the shaft to produce a change in state of the encoder readout.
• The problem that I am having now is with the interrupts (I think), I believe I have implemented them correctly. But I’m not getting a change in state in my code. Or if the state does change it goes from 5 to 3 but then stays on 3 and does not change state again or at all.
• The code inside of the “encoderRead” function was originally inside the void loop and it worked, but without the interrupts it would occasionally skip out of sequence or count the number of state changes inconsistently.
• The board I’m using is an Arduino mega 2560.

• What I am trying to do, is implement the code in the function.

// encoder with intterupts

const int encoderA = 0;// reading from pin 2 on the mega…interrupt should be refranced as their # not postion onthe board ?
const int encoderB = 1; // reading from pin 3 on the mega…interrupt should be refranced as their # not postion onthe board ?

volatile int value = 5 ;
int stateA = 3; // reading from pin 3 on the mega
int stateB = 2; // reading from pin 2 on the mega
int valueA = digitalRead(stateA); // collecting input data from pin 3… the same pin as the interrupt ?
int valueB = digitalRead(stateB); // collecting Input data from the pin 2… the same pin as the interrupt ?

void setup() {
pinMode( encoderA, INPUT);
pinMode( encoderB, INPUT);
Serial.begin(9600);
////
attachInterrupt(encoderA,encoderRead,CHANGE); // setting up the interrupt, by specify the interrupt I want to use.
attachInterrupt(encoderB,encoderRead,CHANGE); // setting up the interrupt, by specify the interrupt I want to use.
}

void loop() {
Serial.println(value);
}

void encoderRead(int valueA, int valueB){ ///fucntion my interrupt is using
if (valueA == 1){
if (valueB == 1){
value = 1;
}
else if (valueB == 0){
value = 4;
}
}
if (valueA == 0){
if (valueB == 1){
value = 2;
}
else if (valueB == 0){
value = 3;
}
}
}

encoder_ experiment.ino (1.3 KB)

Did you try : pinMode(encoderA, INPUT_PULLUP);
pinMode(encoderB, INPUT_PULLUP);

It could help, depending on the circuitry for driving the encoder.

Otherwise, use a volatile counter variable .... eg ... pulsecount ..... for your ISR.
And in your loop .... get the code to read that counter value every 2 seconds.

Eg...

unsigned long ref_time;
volatile int pulsecount;

in the loop...
   ref_time = micros();

   if (micros() - ref_time >= 2000000){
   noInterrupts();     //disable interrupts temporarily here .... to prepare for reading 'volatile' data that has more than a 8 bit (1 byte) format.
   Serial.Println(pulsecount);
   interrupts();  //turn on interrupts
  }
void encoderRead() // right-motor, not on usb socket side : This interrupt service routine will execute at a falling edge of State A encoder signal. When motor is constant speed, then time difference between encoder edges will relate to the rotational speed if 
{
    pulsecount++;
    //Serial.println(pulsecount);
}

I haven't checked the code above for typing errors.... but that's the idea.

Please use code tags </> for presenting code.

Please read and understand the documentation on attachInterrupt(). Interrupt numbers and pin numbers differ, and an ISR cannot take parameters.

You should use the digitalPintoInterrupt() function to turn Arduino pin numbers into interrupt numbers. Then you don't have to remember if pin 3 is interrupt 1 or interrupt 2. Make the compiler do it. Then your code is much more portable when you get a different Arduino for your birthday.