nativebird
New member
I am having an issue utilizing a high resolution quadrature rotary encoder in a high-speed application. Up to about 1700 RPM, everything works fine, the Teensy 4.0 tracks the pulse count properly. However, beyond that speed, the count is not updated. The encoder has 2000 pulses per revolution, and the max speed needed is about 2000 rpm, which should give a signal frequency of about 67khz. The encoder itself (link below) is rated for 6000 rpm, and I've confirmed with the oscilloscope that it is outputting the proper signal at 2000 rpm and above. Is the Teensy not fast enough to keep up with this sort of input?
I'm using interrupts to track the pulses from the encoder. I also tried using dedicated encoder libraries but had the same issue.
Here is the code:
I've also included some screenshots with the serial monitor output: here you can see the encoder tracking properly at lower rpms, with about a 20k-50k difference in the count from one sample to the next, depending on speed and acceleration.
Here you can see where the counter abruptly cuts off and stops updating, somewhere between 1800 and 1900 rpm.
Here is the link to the encoder:
Encoder
Any thoughts? Thank you for your help.
I'm using interrupts to track the pulses from the encoder. I also tried using dedicated encoder libraries but had the same issue.
Here is the code:
C++:
// Encoder pins, Phase A and B for the quadrature signal, Phase Z pulses once per rev.
const int encA = 15;
const int encB = 14;
const int encZ = 16;
const int encoderPulsesPerRev = 2000;
//Counters
long counter = 0; //Encoder counter
long lastCounter = 0;
long revs = 0; //Encoder revolutions (Z output)
long lastRevs = 0;
long currentRevs = 0;
long diff;
//Time tracking for calculating RPM
long currT = 0;
long prevT = 0;
int sampleT = 1000;
float rpm;
void setup() {
Serial.begin(9600);
pinMode(encA, INPUT_PULLUP);
pinMode(encB, INPUT_PULLUP);
pinMode(encZ, INPUT_PULLUP);
attachInterrupt(encA, isrA, RISING);
attachInterrupt(encB, isrB, RISING);
attachInterrupt(encZ, isrZ, RISING);
}
void loop() {
currT = millis();
//Calculating RPM
if(currT - prevT >= sampleT){
rpm = (float(revs-lastRevs)/sampleT)*60000;
prevT = currT;
lastRevs = revs;
diff = counter - lastCounter;
lastCounter = counter;
Serial.print("RPM: ");
Serial.println(rpm);
Serial.print("Pulse Count: ");
Serial.println(counter);
Serial.print("Revolutions: ");
Serial.println(revs);
Serial.print("Difference: ");
Serial.println(diff);
Serial.println();
}
}
//Interrupt routines
void isrA() {
if (digitalRead(encB) == LOW){
counter++; }
else {
counter --;}
}
void isrB() {
if (digitalRead(encA) == LOW) {
counter --; }
else {
counter ++; }
}
void isrZ() {
revs ++ ;
}
I've also included some screenshots with the serial monitor output: here you can see the encoder tracking properly at lower rpms, with about a 20k-50k difference in the count from one sample to the next, depending on speed and acceleration.
Here you can see where the counter abruptly cuts off and stops updating, somewhere between 1800 and 1900 rpm.
Here is the link to the encoder:
Encoder
Any thoughts? Thank you for your help.