# Teensy 4.1 Quadrature encoder combined with PID_V2 for precise speed control

#### brentfinley

##### New member
I am looking at combining the PID library:
https://github.com/imax9000/Arduino-PID-Library
To make a motor controller for a motion picture camera. It needs to ramp up in 0.5 seconds and then lock into a set speed. I anticipate a startup PID, then "at Speed" PID adjustment.
The PID library examples use an Analog pin for the "set point" target.

Does anyone have an example of reading a quadrature encoder at a set interval and calculating speed from that as a reference for the input to the PID algorithm?

Getting speed from the encoder is really easy if you use the QuadEncoder library per the link in your post. You just call enc.Read() at the interval you want, and do the calculation. Here is a T4.x example that assumes encoder A and B signals are on pins 3 and 4.

Code:
``````#include <QuadEncoder.h>

QuadEncoder Enc(3, 4, 5, 0);  // Enc 3 of 4, A(pin4), B(pin5), PullupsReq(0)

#define PPR 1200;            // pulses per rev (*4 for quadrature)
elapsedMillis ms;
uint32_t encNow, encPrev=0, encDelta;

void setup()
{
Serial.begin( 115200 );
delay( 1000 );
Enc.setInitConfig();  //
Enc.init();
ms = 0;
}

void loop()
{
if (ms >= 100) {
encDelta = encNow - encPrev;
encPrev = encNow;
ms -= 100;
float rpm = 60*(10*EncDelta)/(float)(PPR*4);
Serial.println( rpm );
}
}``````

Getting speed from the encoder is really easy if you use the QuadEncoder library per the link in your post. You just call enc.Read() at the interval you want, and do the calculation. Here is a T4.x example that assumes encoder A and B signals are on pins 3 and 4.

Code:
``````...

void loop()
{
if (ms >= 100) {
encDelta = encNow - encPrev;
encPrev = encNow;
ms -= 100;
float rpm = 60*(10*EncDelta)/(float)(PPR*4);
Serial.println( rpm );
}
}``````
Thank you for that. I have something to build from. BTW... I think ms needs an update somewhere outside your if(ms.... above.

Thank you for that. I have something to build from. BTW... I think ms needs an update somewhere outside your if(ms.... above.
If you're not familiar with elapsedMillis, it's a clever little class that encapsulates the commonly-used paradigm of reading millis(), comparing to a start value, etc. Each access to "ms" implies a read of millis() and a calculation of the elapsed time. In the example program, ms is initialized at the end of setup(), just to make sure it's zero on first entry into loop().

If you're not familiar with elapsedMillis, it's a clever little class that encapsulates the commonly-used paradigm of reading millis(), comparing to a start value, etc. Each access to "ms" implies a read of millis() and a calculation of the elapsed time. In the example program, ms is initialized at the end of setup(), just to make sure it's zero on first entry into loop().
Awesome! Thanks