encoder CPR vs PPR and DC motor, PID control values,

Hello Members,

First - thanks to this forum, it is very helpful - particularly posts by jremington and cattledog.

I have my motor work under PID control using the PID_v1 library by Brett Beauregard.

But, I still have questions - I have discovered that encoder counts (and or CPR values) affect the way the motor responds with setpoint, input, output, Kp, Ki, and Kd. I am using an encoder with (supposedly) 100 PPR, but after looking at the vendors web site (U.S. Digital Products) the encoder I have is speced by them as 100 CPR, the motor vendor speced the encoder as 100 PPR. It there any way to determine which value is correct, etc. The encoder does have an index signal, I suppose I could set two timers on my arduino - and start a counter with the index pulse, and use another timer (or the interrupt vector) to count pulses - perhaps a pinchange intp for one channel only. Any suggestions here?

One last question has to do with the stability of the output/input value - if I choose a very low setpoint - like 5, the input varies a lot, and the output varies a little as well. I use a formula that converts the encoder count to a "speed" based on the number of encoder counts multiplied by the gear ratio, a 100 ms time window, and 1000 divisor for a "seconds" value. This value is the actual rotation of the motor, and is compared to the setpoint for error, etc. At higer setpoint values - the values are more stable. I am using pretty low values for Kp (0.15) and Ki (.3)

Thanks for the help in earlier posts.

ewholz

ewholz

The encoder does have an index signal, I suppose I could set two timers on my arduino - and start a counter with the index pulse, and use another timer (or the interrupt vector) to count pulses - perhaps a pinchange intp for one channel only. Any suggestions here?

The idea of counting encoder increments between index pulses is a good one. Here's some test code on how to do this while using your existing pin change interrupts to count the quadrature changes.

Set up an external interrupt (attachInterrupt(0, trigger, RISING) on pin2 connected to the index pulse. Set up an array saveCount[] to hold the values of the encoder counts.

The pseudo code for the ISR , which will save the encoder counts for 10 index pulses on that interrupt, could look like this. Discard the first value because it will not be a full revolution. Size the array for 11 elements.

void trigger(){
static byte triggerCount;
  if (triggerCount<=10){
    noInterrupts();//will disable pin change interrupts on encoder A/B
    saveCount[triggerCount] = //your encoder count;
    //set the encoder count to zero;
    triggerCount++;
    interrupts();//reenable the pin change interrupts on encoder A/B
    
  }
    else{
      detachInterrupt(0);
  }
}