Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Embedded PI Controller

Status
Not open for further replies.

Xavier Pacheco Paulino

Junior Member level 1
Junior Member level 1
Joined
Nov 8, 2015
Messages
18
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
188
I'm designing an embedded PI controller using a STM32 Nucleo board. In the PWM configuration, a 0 means 0% duty and 800 means 100% duty. The objetive is to regulate the speed of a PMDC motor, i.e, to keep the RPM under load variations. I'm not sure yet if this would work. Does the code keep the RPM when the output has reached the setpoint, so error signal is zero? Tell me your suggestions. I still don't have the PI gains, I just want to make sure the algorithm is correct. This is what I have:

Code:
int error=0;
int target_RPM=0;
int current_RPM = 0;
int duty_cycle=0;
float Kp = 0;
float integral = 0;
float Ki = 0;

while {
//Main program
}

//10 ms LOOP with TIM6 Interrupt

//Get current RPM
current_RPM = read_RPM();

//Get the error
error = target_RPM - current_RPM;

//Calculate the integral
integral = integral + (Ki*error);
if (integral > 800) // check for integral windup and correct for upper limit
integral = 800;
if (integral < 0)//check for integral windup and correct for lower limit
integral = 0;

//Calculate the Control Variable
duty_cycle = (Kp*error) + integral;

//Limit the Control Variable to within 0-800
if(duty_cycle>800){
	duty_cycle = 800;
}
else if (duty_cycle<0){
	duty_cycle = 0;
}

htim1.Instance->CCR1 = duty_cycle;
 

The PI algorithm is basically correct. How are you reading speed, can the measurement keep up with the 100 Hz controller sample rate?
 

The PI algorithm is basically correct. How are you reading speed, can the measurement keep up with the 100 Hz controller sample rate?

For the speed measurement I'm using a 6 pulses per rev reflective sensor. The range of speed I want is from 0 to 3000 RPM. How do I know if the measurement can keep up with the sample rate?

Also, I would like to understand better the code. For example, if the setpoint is reached and the error is zero or near zero, does the routine keep the duty cycle? I thought if the error iz zero the duty would be zero, and the motor would be off, which is not intended (and that's the case of position control, not speed control).
 

When the error is zero the integral term stays unchanged (and p is zero) so the output stays at the same value.

That’s what the I term does for you. P only would mean zero error gives zero output.

A position control PI still might not go to zero if some holding force was required to hold a given position.

The pi looks good with anti-windup being a key feature.
 
I thought if the error is zero the duty would be zero
Why? integral is keeping the duty cycle.

Problem with speed measurement is the dead time. Below 1000 RPM, the update rate is lower than the controller sample rate.
 
Why? integral is keeping the duty cycle.

Problem with speed measurement is the dead time. Below 1000 RPM, the update rate is lower than the controller sample rate.

So do you suggest to lower the controller sample rate?
 

I see the bigger problem is the general loop bandwidth issues with the low feedback rate.

For example if you want 100hz loop bandwidth but you're only getting 10 updates per second at low RPMs that will pose a fundamental challenge (output oscillations or thrashing on your power stage for example). But only you know whether you need good performance at low RPM's. If you don't try to regulate there it may not matter.

I wouldn't lower the PI sample rate because it doesn't solve that problem. Having the PI 'oversample' is fine. The key parameter here is the PI corner frequency and having a PI sample rate about 10X that corner frequency
 
I will try it to see what happens. I have another basic question about understanding the code. If my setpoint is 500 RPM, and then I lower it to 300 RPM, then the error would be e=300-500 = -200, a negative error. Here again is the I term which compensates for the negative error? As the duty cycle should be between 0 and 800.
 

Hi,

The P part will cause immediate reaction on your input change.
It will be multiplied with a value smaller than 1 I assume.

Lets assume it is multiplied with 0.5 then the P output becomes -100.

But still there is the I output. You may consider it to be unchanged for the first response.
So if the I ouput was 400 befor the setponit change... then the overall output will be:
400 + (-100) = 300 (for the duty cycle value)

But for sure you should prevent the duty cycle value to become negative.

Klaus
 

Well immediately following that step the P term will reduce by 200*kp and the I term will decrease at a rate proportional to ki. The bottom line is that both terms will contribute to the PWM output reducing causing the motor to slow.

This is the nature of a PI. Each term contributes a response that causes different behaviors over time. The P term causes instant changes while the I term corrects error over a longer period of time. All fancy control loop theory boils down to 'how will the system respond over time'.


Note that a slightly improved implementation in my opinion wouldn't clamp the I term to 0-800 but would only clamp the output to 0-800 (as you're doing). Then within the if-then-else that clamps the final output to 0/800 generate max_saturated and min_saturated signals that are used to stop the integrator from 'winding up'.

Because it's theoretically ok to have a negative integrator term if at the same time a positive P term (or other term such as a feed-forward) is keeping the final output positive.
 
Last edited:

Hi,

in my opinion wouldn't clamp the I term to 0-800 but would only clamp the output to 0-800
From my experience this won't work.

You need to limit the I value. In both directions to meaningfull values.

Consider this situation.
The setpoint is 100%
But due to heavy load - even at full duty cycle - it does not get the desired RPM.
The speed is continously too low, causing the I part to increase.
Only time or a variable overflow limits the value of I.
So a 16 bit value may become 32,000 ....
Or even more: 32765, 32766, 32767, (overflow) -32768, -32767, -32766 ....
And suddenly the duty cycle becomes 0 and the motor stops....and nobody knows why .... maybe after hours of running ...

Klaus
 

You need to limit the I value. In both directions to meaningfull values.

Changing the math could shift values of the output if compared to the expected standard PI model, once this would change the PI model itself. In fact, it is usual to apply a saturation function to the error value, but this will somewhat change overall PI model, althought most often with a negligible impact. What I see here is the lack of a functional simulation of the whole process, which could give a better clue of the fine adjustements necessary to tune the control dynamics.
 

Yes, integrator limits are mandatory for anti-windup. It can be implemented in different ways. Simple PI controllers often use the "velocity algorithm" where integrator and controller output are identical, so it can be easily limited.

As for the speed sensor dead time, it tends to cause control loop instability at low RPM. It can be handled by reducing the controller gain at low speed.
 

Hi,


From my experience this won't work.

You need to limit the I value. In both directions to meaningfull values.

Consider this situation.
The setpoint is 100%
But due to heavy load - even at full duty cycle - it does not get the desired RPM.
The speed is continously too low, causing the I part to increase.
Only time or a variable overflow limits the value of I.
So a 16 bit value may become 32,000 ....
Or even more: 32765, 32766, 32767, (overflow) -32768, -32767, -32766 ....
And suddenly the duty cycle becomes 0 and the motor stops....and nobody knows why .... maybe after hours of running ...

Klaus

I simply think you didn't follow the second part of what I said.

When its detected that less than 0 or more than 800 was requested you use that knowledge to prevent windup. The point is that in a more generalized approach the modulator and the error amplifier are distinct. The modulator knows the limits of the system and tells the eamp things are 'saturated_pos' or 'saturated_neg'. The eamp then uses that knowledge to prevent windup in its accumulator(s).

if (integrator_input>0 & saturated_pos) 'don't run integrator'
if (integrator_input<0 & saturated_neg) 'don't run integrator'

Again this is relevant if for example you have a feed-forward term bypassing the eamp. Now the eamp may need to contribute a positive or negative signal.

Or you may have multiple integrators/polls in a TypeII or TypeIII system where the values of the intermediary accumulators don't map directly to the output.
 

Hi,

if (integrator_input>0 & saturated_pos) 'don't run integrator'
if (integrator_input<0 & saturated_neg) 'don't run integrator'
Now I understand. Makes sense.

Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top