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!
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:
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.