PID controller

For a project we needed to make a boost converter, after our IC died. We decicded to use a PWM channel and an analog input of our microcontroller (PIC18f22k23).

Now some co-workers pointed us to a PID controller for the feedback line, after some reading I made the followings concept programs.

first I read the analog voltage with the ADC, then I calculate the difference, delta, between the SetPoint and the output voltage, and last the PWM gets incremented with delta devided by a factor K, which increases the output voltage. The factor K is here to prevent an overshoot, theoratically the output voltage will only “aproach” the SetPoint Voltage.

output_V = analogRead(A0);

delta = setPoint - output_V;

pwm = pwm + delta / K;

However It will take a significant time for the boost converter to reach the SetPoint voltage, so when the frequentie is to high, It will overshoot due to pwm being incremented to often. To prevent an overshoot I could either lower the frequentie and/or increase the factor K for better dampening.

I tried to make a better program where factor K is regulated. I calculate K by the substracting the delta by the previous delta. So how higher the output voltage gets, how smaller the differences gets and how larger factor K becomes… atleast that is what I want.

output_V = analogRead(A0); // reads output voltage

delta = setPoint - output_V; // calculates the difference between the setpoint and the output voltage

error = delta - delta_previous; // error will be used to calculate the factor K,

pwm = pwm + (delta / (1024.0 - abs(error))); // A high error results in a low K, which results into a faster time, error should not become negative as it will result in slower correction, and the 1024.0 - K is because the error workes inversed proportional.

delta_old = delta; // store delta in delta_old.

Am I on the right track here? This PID controlling is new for me. I am going to need it for my 2 wheel balance car in the future :wink: and perhaps also for my quadcopter.

Kind regards,

Bas

There's an existing PID library available in the playground unless you're deal set on making your own: PID Library

It would be much easier to use voltage feedback and the built in analog comparator. Boost converters are by nature switching devices, with capacitors to smooth the output. You do not need the sophistication of PID.

You also do not need PWM, that happens automatically if you switch off the output port when the output voltage is too high, and switch it on again when the output voltage is too low.

wildbill: There's an existing PID library available in the playground unless you're deal set on making your own: PID Library

I quote me "of our microcontroller (PIC18f22k23)." We do not use arduino environment. I am just here to ask a question to people who know more of PID then me.

jremington: It would be much easier to use voltage feedback and the built in analog comparator. Boost converters are by nature switching devices, with capacitors to smooth the output. You do not need the sophistication of PID.

You also do not need PWM, that happens automatically if you switch off the output port when the output voltage is too high, and switch it on again when the output voltage is too low.

when I power up the coil for the first time, the output Voltage will not reach the desired 13V... as it never will rise above the 13V it will not switch off. So there won't be any switching at all. You need fast switching in the beginning to reach the desired voltage. I have looked up to make a boost converter with comparators but have you got any idea how big the schematic becomes. you need 2 comparators a memory cell, seperate clock line and several resistors and capacitors arround the comparators. So that is the same as buying a new boost converter IC. It is 10x easier and require infinite less components to use a PWM line, and read in the output voltage via de resistor division, which we already have.

...then I calculate the difference, delta, between the SetPoint and the output voltage...

Surely you mean between the setpoint and the input.

bask185: I quote me "of our microcontroller (PIC18f22k23)." We do not use arduino environment. I am just here to ask a question to people who know more of PID then me.

Take a look anyway - IIRC, there's little or nothing arduino specific in there.

bask185: For a project we needed to make a boost converter, after our IC died. We decicded to use a PWM channel and an analog input of our microcontroller (PIC18f22k23).

Now some co-workers pointed us to a PID controller for the feedback line, after some reading I made the followings concept programs.

first I read the analog voltage with the ADC, then I calculate the difference, delta, between the SetPoint and the output voltage, and last the PWM gets incremented with delta devided by a factor K, which increases the output voltage. The factor K is here to prevent an overshoot, theoratically the output voltage will only "aproach" the SetPoint Voltage.

the output should not be linked to the logic. the output will float to whatever it needs to be in order to get the process to the desired value. one over shoot and one undershoot is often a desired goal in P. if you hunt, your window is too small, or, your speed is too fast, or, your final control device is not stable or accurate enough for the process. the final control device is often the hardest part to accept as the problem. we see people doing silly things like trying to use a gear reduction motor with PID without knowing the characteristics of the device. sounds like you are working some off feed-forward type control. read up on P, on I and on D. you do not state how dynamic the process is. if the process is very dynamic, then you might need to use inverse D. if the process is slow, you can use a simple fuzzy logic. you can use a two step P, one window large to get you into a first stage zone, then a second, narrower and slower window. from that point, most PID control is just I to nudge the value towards setpoint.

dave-in-nj: the output should not be linked to the logic. the output will float to whatever it needs to be in order to get the process to the desired value. one over shoot and one undershoot is often a desired goal in P. if you hunt, your window is too small, or, your speed is too fast, or, your final control device is not stable or accurate enough for the process. the final control device is often the hardest part to accept as the problem. we see people doing silly things like trying to use a gear reduction motor with PID without knowing the characteristics of the device. sounds like you are working some off feed-forward type control. read up on P, on I and on D. you do not state how dynamic the process is. if the process is very dynamic, then you might need to use inverse D. if the process is slow, you can use a simple fuzzy logic. you can use a two step P, one window large to get you into a first stage zone, then a second, narrower and slower window. from that point, most PID control is just I to nudge the value towards setpoint.

If I dont connect the output to the logic, how the F* am I supposed to read the voltage? The point is that the output becomes the same as the setpoint, and I need feedback to measure it. It won't float, where are you talking about??

bask185: However It will take a significant time for the boost converter to reach the SetPoint voltage, so when the frequentie is to high, It will overshoot due to pwm being incremented to often. To prevent an overshoot I could either lower the frequentie and/or increase the factor K for better dampening.

I tried to make a better program where factor K is regulated. I calculate K by the substracting the delta by the previous delta. So how higher the output voltage gets, how smaller the differences gets and how larger factor K becomes... atleast that is what I want.

I'm not a PID expert by any means, but I think you might need to spend more time tuning the loop (a tricky process) before trying to fudge the output by manipulating K. If you rely on just the proportional (P) term to start up the loop, it will take a long time to reach your set point and could overshoot. I believe this is where the derivative (D) term comes in. With a large jump in the input (from zero to full scale at startup) the D term causes a large change in the output value to get it to correct quickly. Then the P term comes into okay to regulate the output, while the integral (I) term adjusts for any drift (to correct for the tendency to asymptotically approach the set point but never actually reach it.) all these terms interact with each other, and depend on the physical characteristics of the system being controlled. Tuning to get fast response without overshoot or oscillation is a complex art.

(While I was typing, Dave-in-nj responded: take the details of his advice over mine, but I believe we are both basically saying the same thing -- understand the dynamics of your system and spend some time tuning. A PID loop is a powerful system, but it is not a pre-formed drop-in solution. There is always tuning involved.)

bask185: If I dont connect the output to the logic, how the F* am I supposed to read the voltage? The point is that the output becomes the same as the setpoint, and I need feedback to measure it. It won't float, where are you talking about??

Yes, you need feedback. I think he's saying to not fudge K according to the output state, let the PID loop handle adjusting the output.

I just re-read your original post, which I had read incorrectly the first time. I took it to be that you had implemented a PID loop, and then were using K to fudge the output of the PID loop into a valid PWM value. But now I think your K calculations ARE the PID loop.

bask185: first I read the analog voltage with the ADC, then I calculate the difference, delta, between the SetPoint and the output voltage, and last the PWM gets incremented with delta devided by a factor K, which increases the output voltage.

This sounds like you are making a basic implementation of the P term of the PID loop: the output is proportional to the input. This is the main adjusting factor: the larger the error, the bigger the adjustment.

theoratically the output voltage will only "aproach" the SetPoint Voltage.

That's what the I term is for: small errors are integrated over time to bring the output in line with the set point, to counter the tendency for the P term to asymptotically approach the set point but never reach it. A small error over a long time will tend to tweak the output value.

However It will take a significant time for the boost converter to reach the SetPoint voltage, so when the frequentie is to high, It will overshoot due to pwm being incremented to often. To prevent an overshoot I could either lower the frequentie and/or increase the factor K for better dampening.

This is where you need the D term, to gracefully handle a large step function change in the error term. (Think of the startup case as the error instantly going from zero to full scale.) The derivative portion gives a large but short adjustment to the output to quickly get it in range. (Think of driving your car: when at speed, you make small adjustments to the accelerator position to maintain speed, but when pulling away from a stop sign you give it much more gas until you get going, else it would take a long time to get up to speed.)

Am I on the right track here? This PID controlling is new for me. I am going to need it for my 2 wheel balance car in the future ;) and perhaps also for my quadcopter.

I think you're heading in the right direction using a PID loop, especially for your follow-on projects. But it looks like you need to spend more effort on the D term, because your existing improvements to adjusting K don't seem to be working for you. You will likely also need an I term, especially for the balancing robot and copter applications.

It looks like you nay gave taken the PID loop concepts, simplified them into your code, and then started tweaking your code to account for the observed behavior. A better first step might be to take an existing full PID loop implementation, and just tweak the tuning parameters (which can be more art than science.) don't try to optimize the code by leaving out parts you don't think you need, that may only cause problems when tuning. For example, if you don't need the integral portion, just set I to zero, rather

han removing that code. It makes it easier to reactivate that portion if it turns out to be needed in the future. With a properly implemented PID loop, you should be able to make a wide range of adjustments by just changing the P, I, and D factors, with no changes to your code. When faced with a situation like this, I store the tuning factors in EEPROM and use a simple command line interpreter that let's me watch the behavior of the loop (seeing the individual P, I, and D contributions to the output value) and lets me change the P, I, and D factors in EEPROM so I can play with different values without loading new code each time. Such a facility may be overkill for your power supply project, but will probably come in very handy when it comes time to tune the loop for your balancing robot and copter (which will likely be much more difficult to tune.)

I would recommend making a generic PID loop that will work in all three cases: the only code that should need to change is determining the error and controlling the output (for your power supply, that means reading the analog input and controlling your switcher frequency.) All other customization should be handled by adjusting P, I, and D.

I'm going to go out on a limb and guess that Dave misread your post the same way I did. That's why we both said to not adjust K according to the error or output state, and why our comments probably made no sense to you. Hopefully this clears things up some?

bask185: If I dont connect the output to the logic, how the F* am I supposed to read the voltage? The point is that the output becomes the same as the setpoint, and I need feedback to measure it. It won't float, where are you talking about??

get in your car, climb under the steering wheel and get to and attain speed by looking at the gas pedal.

in a more common way, no one cares where the output is, they look at the speedometer and then manipulate the gas peddal as needed. going down hill at 60 MPH, going flat and level at that speed, , going up-hill, with a trailer or in a wind, the gas pedal (output could be at the floor, in the middle or all the way up.

the output does not matter, the feedback is the process being measured.

I think there may be some confusion in terms here.

bask185: The point is that the output becomes the same as the setpoint, and I need feedback to measure it.

You're using the term "output" to be the voltage being produced by the boost converter, also known as the process variable.

dave-in-nj: the output does not matter, the feedback is the process being measured.

This usage of the term "output" is the result of the PID loop, which is the PWM command value. (This is the meaning of "output" that I used in my posts above.)


It's important to get the terminology correct so we are all talking about the same thing. The voltage produced by the boost converter is the process variable that is compared to the set point, which results in the error. This is the input to the PID loop. The output from the PID loop is the command used to adjust the system (the new PWM value.) The system response to this new output value is a new voltage. That new voltage (process variable) is then compared again to get a new error value, and the loop repeats.

In this context, the actual "output" value from the PID loop is not directly important. The PID loop is not trying to maintain the output value, it's trying to adjust the output value in order to bring the process variable (the system response's resulting voltage) to the setpoint.

Using the car speed analogy once again:

  • Setpoint is the desired speed
  • Process variable is the actual speed
  • Error is the difference between the actual and desired speeds
  • Output is the accelerator position

The process to maintain speed looks at the difference between the actual speed (process variable) and desired speed (setpoint) to generate an error that is fed through the PID loop resulting in an output (accelerator position) that changes the actual speed (process variable) so that it moves toward the desired speed (setpoint.) While there may be constraints on the output (minimum and maximum accelerator pedal position) the actual position of the pedal (PID loop output) is not really important.

when I power up the coil for the first time, the output Voltage will not reach the desired 13V... as it never will rise above the 13V it will not switch off. So there won't be any switching at all. You need fast switching in the beginning to reach the desired voltage.

You are correct, it is slightly more complicated than I summarized (but not much). You need a short pulse of current to generate high voltage from an inductor, and the on time controls the voltage value, up to a limit depending on the inductance and resistance.

It is easy to use a PWM module to generate the pulse, but that is not necessary. The following example is similar to what I had in mind, but use of the ADC is also not required -- the voltage comparator will do the same job. Note that the writer simply increments or decrements the on time as required to achieve the desired voltage. PID would just over complicate the issue.

http://www.instructables.com/id/Make-a-microcontroller-based-boost-converter/?ALLSTEPS

I solved the problem. Now my code has become what it is now I tend to better understand PID explainations found on the internet 8) .

My code is as follows.

void loop () {

if(Serial.available()) { setPoint = Serial.read() - 48; setPoint = map(setPoint, 0, 9 , 100, 400); }

// setPoint = analogRead(A0); // setPoint = map(setPoint, 0, 1023, 100, 400);

output_V = analogRead(A1) ; //

error = setPoint - output_V; // error = map(error, 0, 1023, 0, 255);

integrator += error; integrator = constrain(integrator, (-255 / Ki), 255 / Ki); // don't really need a coworket pointed me to this

pwm = error * Kp + integrator * Ki; // Kp = 1/2, Ki = 1/4 pwm = constrain(pwm, 1, 255);

analogWrite(3, pwm);

delta is called error now

The outputvoltage gets set up real quick and the overshoot I got, is tuned to a minimal. The program runs at 50Hz. so 50 corrections per second. There is no D control as that is useless for my application, the D can't be used or is not ment to get rid of this overshoot. As such I decided to leave the program for what it is.

My original program was working but it was either to slow or I had an overshoot which gave a lot of problems.

Well tnx for the help all! much learned I have :)

bask185:
much learned I have :slight_smile:

Welcome, you are.

(Are we Yoda?) :grin: