Encoder: number of pulses

Hi:

I'm trying to determine the motor speed using a quadrature encoder attached to said motor. I have this code to determine the number of pulses:

#define encoder0PinA  2
#define encoder0PinB  3

volatile int encoder0Pos = 0;

void setup() { 


  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
  Serial.begin (9600);

} 

void loop(){

  Serial.println (encoder0Pos);
  
}

void doEncoder() {
  /* If pinA and pinB are both high or both low, it is spinning
   * forward. If they're different, it's going backward.
   *
   * For more information on speeding up this process, see
   * [Reference/PortManipulation], specifically the PIND register.
   */
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }

  
}

how can I determine the number of pulses per time (set a sample time) in order to calculate the motor speed?

Edit: I forgot to mention that encoder is 300 CPR!

You can get that with the following code, given your motor is not too fast.

#define encoder0PinA  2
#define encoder0PinB  3

volatile int encoder0Pos = 0;
volatile uint32_t last_micros;
volatile uint32_t speed; // in pulses per second

void setup() { 


  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
  Serial.begin (9600);

} 

void loop(){

  Serial.println (encoder0Pos);
  
}

void doEncoder() {
  /* If pinA and pinB are both high or both low, it is spinning
   * forward. If they're different, it's going backward.
   *
   * For more information on speeding up this process, see
   * [Reference/PortManipulation], specifically the PIND register.
   */
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }
  uint32_t m = micros();
  speed = 1000000L / (m - last_micros);
  last_micros = m;
}

Thanks for the help! Is there any way to show that speed on the serial monitor, every single time I try the variable overflows. Also, is "speed" a reserved word?

Edit: I forgot to mention that encoder is 300 CPR!

void loop(){

  Serial.println (encoder0Pos);
  
}

is incorrect - encoder0Pos in an int so it takes 2 bytes in RAM - thus
the interrupt routine can run inbetween reading each byte leading to
false values. You do this instead:

void loop(){

  noInterrupts () ;
  int copy = encoder0Pos ;  // read the variable atomically, interrupts deferred 
  interrupts () ;
  Serial.println (copy);
  
}

The same goes for any variable changed in an interrupt routine that is more than
one byte.

Thanks for the help! Is there any way to show that speed on the serial monitor, every single time I try the variable overflows.

speed overflows? Did you implement the serial output version of MarkT?

Also, is "speed" a reserved word?

No, why are you asking?

Edit: I forgot to mention that encoder is 300 CPR!

And how many RPMs are your motor capable of? If you divide speed by 5 you get RPM.

Thanks again!

1.- Yes, I implemented Mark's version of Serial.print

2.- Speed appears as an orange word on Arduino IDE 1.0.5

3.- The motor is capable of 4000RPM.

Also, when I manually turn the rotor (using the code you provided) it shows the speed in a good way, unfortunately the speed does not reflect zero when the rotor stops, it keeps showin the previous value.

Also, when I manually turn the rotor (using the code you provided) it shows the speed in a good way, unfortunately the speed does not reflect zero when the rotor stops, it keeps showin the previous value.

That's correct because it's only updated if a new pulse is received. You could store the value of encoder0Pos and if it's value didn't change since the last output, forget the speed value.