Electronic – How to handle rotary encoder overflow

encoderrotary

I am using a magnetic rotary encoder(AS5048B) to detect the rotation angle of a motor shaft. This is fed to a pid loop to calculate the PWM value for motor position control.
The encoder has a 14Bit output. It gives an output of 0 – 16383 which is then right shifted by 4 to get a range of 0 – 1023.

When we give values closer to 1023 the sensor value goes back to 0 after a complete rotation and the pid error goes to huge values resulting in unstable motor movements. Suppose my current position is 10 and setpoint is 1023. The error is 1023 – 10 = 1013 and the motor starts to move towards 1023 to decrease error. When it reaches 1023 sometimes it overshoots and goes back to a value of 0 which gives us a wrong PWM value of 1023(1023 – 0). Is there any workaround for this issue?

Implementation details:- The experimentation setup consists of a 60RPM geared DC motor, an H bridge(VNH5019) and a magnetic rotary encoder(AS5048B). The H bridge has a PWM input for speed control and 2 other pins for direction control. It is an absolute encoder which gives a 14Bit output corresponding to 0 – 360-degree rotation of the motor shaft and the same act as a feedback signal for the plant. PID update function is written as a periodic timer interrupts with 10KHz frequency. Inside the ISR I read the setpoint from a rotary encoder and the feedback signal from the magnetic encoder. An error is then calculated, corresponding PWM values are generated and sent to the H bridge IC for changing the motor shaft position for that error. Because of the nature of the PID loops the motor starts rotating and when the error approaches zero the PWM value also approaches 0, thus stopping the motor at the set-point. My plan is to make this motor as a 0 – 359-degree position servo for normal applications (and 0 – 180-degree servo for hobby servo applications in the future).

I tried with a P only controller. It works fine at all the positions except the overflow point. Since the error is calculated as the difference between setpoint and input, an overflow makes the error value extremely high. The motor thinks that it needs to apply that much of PWM(which decreases as the error approaches 0) to reach that position. The net result is a motor which goes from 0 – 359 degrees (when the setpoint is a value corresponding to 359 degrees), overflows by 1 degree and goes back to 359, thus repeating the process infinite times.

Best Answer

Use modulo arithmetic.

// Pseudo-code
// error
error = (setPoint + 512 - currPos) % 1024 - 512;

This code shifts the setpoint from {0 .. 1023} to {512 .. 1535}, subtracts the actual position and gets the modulus. The answer will be in the range 0 - 1023 but will have a positive offset of 512 which is subtracted out. The resultant error will be in the range {-512 .. 511}.

Suppose my current position is 10 and setpoint is 1023. The error is 1023 - 10 = 1013 ...

error = (setPoint + 512 - currPos) % 1024 - 512;
// Calculation
error = (1023 + 512 - 10) % 1024 - 512
      = 1525 % 1024 - 512
      = 501 - 512
      = -11

Update 1.

It seems that you want the geared output to run from 0° to 360° but that the assembly could overshoot slightly at 360° and, I presume, at 0°. The only way to handle this with your proportional control is to convert your encoder in software into a multi-turn encoder. This means keeping track of your revolutions and allowing your "total" value to run from, say, -90° to +450°.

enter image description here

Figure 1. Flowchart for 0° transition testing.