Arduino PID Library

Thanks!

I think nag might be a little strong. I've taken it as a gentle reminder. :slight_smile:

I'm working on the integer (or "lite") form. I'll release it bundled with the pid library, and on both I'm planning on renaming it as "SampleTime", in keeping with the industry standard.

-Brett

ok, so I finished (or thought I finished) the integer form, and I wasn't happy. it was only 1k smaller and 30% faster. not good enough. I'm going to keep working on it, but unfortunately it's going to be a while.

in the mean time, the 0.5 beta has been sitting there with it's flaws. So... I've decided to upload the next version of the beta (v0.6) without the promised integer library. sorry about that.

at any rate, with the bad news out of the way, let's talk about the good news. updated pid library! bonus! I took care of the obvious (and less obvious) snags with the library, and added a very powerful advanced feature.

"snag" fixes:

  • CalcFrequency has been changed to SampleTime. finally.
  • The library now has a version-specific name: <PID_Beta6.h> This way, you can put up your code, and even 4 years (and 20 revisions) from now, everyone will know which version of the library you used.
  • I felt that SetIOLimits was a bit confusing, since for the most part, the input limits will never be changed. I decided to split it into two functions: SetInputLimits and SetOuputLimits. The output limit function was left on the standard function page, while the input limit function is now hidden on the advanced page.

advanced feature:
Feed Forward. good lord is this powerful. essentially it lets you add your own knowledge to what the pid is doing. so, if you know that the controller is about to get hit with a major disturbance, you can help it along, and address the disturbance far more effectively than using just pid alone.

take a second to look at the updated wiki (Arduino Playground - PIDLibrary) and let me know if I missed anything!

Brett

Thanks for your effort on this. One question I have is how would one best invoke a reverse action control function, as required in industrial controllers for working with fail open and fail close control valves?

Thanks
Lefty

how would one best invoke a reverse action control function, as required in industrial controllers for working with fail open and fail close control valves?

change the sign of the P_Param. (I know you know what this means Lefty, but for the benefit of others reading...)

if your P_Param is 3.2 say, and the controller seems to be going in the wrong direction,( i.e. opening when it should be closing,) you would want to change that to a -3.2.

usually it is really obvious that this needs to be changed. the output starts to go the wrong way, which makes your input get farther from setpoint, which makes your output go FARTHER in the wrong direction. the cycle continues until your output is pegged at one of the limits.

I was teaching a class on pid and asked "what happens if you set this wrong?" expecting the answer above. the answer I got was much better: "you get a nickname"

Brett

I have plans to design an autopilot for my boat and have read this post with great interest. Before starting I should want to ask you two questions that has puzzled me:

  • I have seen that some boat autopilots does not need a rudder feed-back. I suppose that all PID regulators do need some sort of feed-back. Do you have any idea how they can do this?
  • Some autopilot claims that they are adaptive. They can learn the characteristics of the boat. I know you cannot give us an adaptive controller, you told us that, but can you hint to me how this is done. Is it still a PID regulator that is used with some other program tuning the parameters or do they use some other type of controller?

"I have plans to design an autopilot for my boat and have read this post with great interest. Before starting I should want to ask you two questions that has puzzled me:

  • I have seen that some boat autopilots does not need a rudder feed-back. I suppose that all PID regulators do need some sort of feed-back. Do you have any idea how they can do this?
  • Some autopilot claims that they are adaptive. They can learn the characteristics of the boat. I know you cannot give us an adaptive controller, you told us that, but can you hint to me how this is done. Is it still a PID regulator that is used with some other program tuning the parameters or do they use some other type of controller? "

Well all closed loop controllers need some kind of feedback measurement(s) to function, otherwise it is 'open loop' control, kind of like a steering wheel, where it's up to the human operator to know where the car is aimed at and make adjustments or not.

In the Classic PID controller the feedback is called the 'PV' for process variable. It is the actual measured temperature in a temperature controller, or the actual level measurement in a level controller. For you autopilot steering the feedback would either have to be something that can measure actual heading like a electronic compass or a GPS heading, etc. Measuring the actual rubber angle would work to a degree but wind and current variables could cause a change in heading regardless of the rudder angle. I'm not sure what the standard measurement used in for boat auto pilot controllers. Interesting applications and I would favor GPS but autopilots have been around longer then GPS so there must be other effective measurements.

Lefty

An autopilot use heading information from a fluxgate compass so of course that will be used as a feed-back. However in my understanding of an autopilot it usually consists of two cascaded loops. The first one for heading and the other one for setting the rudder position. The first one use heading as feed-back and the last one a "rudder feed-back unit". Some autopilot manufacturer has taken away the need fro that last unit and I just wander how that can be done.

An autopilot use heading information from a fluxgate compass so of course that will be used as a feed-back. However in my understanding of an autopilot it usually consists of two cascaded loops. The first one for heading and the other one for setting the rudder position. The first one use heading as feed-back and the last one a "rudder feed-back unit". Some autopilot manufacturer has taken away the need fro that last unit and I just wander how that can be done.

Now I understand your question. Yes cascade control where the rubber has it's own PID control function allows one to optimize the controller tuning settings for the rudder controller and the heading controller independently such that the heading controller outputs a 'desired setpoint' to the rubber controller as it's PV measurement.

In such a configuration the rubber controller is said to be the slave controller and the heading controller the master controller. It gives better controllability. However with more the powerful control possibilities with a microprocessor this can all be done inside the micro and could take advantage of feed-forward or adaptive or other 'smart' control algorithms. So I guess it's a trade off, saving the cost of the hardware needed to generate a rudder position measurement while still having good control behavior by compensating by using more advance software control features.

As a hardware guy, I would prefer having actual rubber feedback measurement in that it then is easy to add additional alarm functions if say the rubber linkage was to break and the actual rubber commands were not being performed.

Lefty

  • Some autopilot claims that they are adaptive. They can learn the characteristics of the boat. I know you cannot give us an adaptive controller, you told us that, but can you hint to me how this is done. Is it still a PID regulator that is used with some other program tuning the parameters or do they use some other type of controller? "

I don't think you need an adaptive controller for this situation per se. I'm assuming that what they mean when they say "Adaptive" is that you can put it in a big boat or a small boat, and it will figure out if it needs to control aggressively or conservatively. once the controller dials in on what type of control it needs, I would guess that it doesn't do much adapting. this is good news for you. you can use a pid controller and have a tuning period. "this control is a little too aggressive, let me back it off" or whatever. after that, you should be all set.

  • I have seen that some boat autopilots does not need a rudder feed-back. I suppose that all PID regulators do need some sort of feed-back. Do you have any idea how they can do this?

ok, first let me put both single-loop and cascade into words.
single loop: "I'm not on heading. let me adjust my signal to the rudder until I get the heading I need"
cascade: "I'm not on heading. I need the rudder to be 5degrees off center. rudder controller, look at the rudder position and adjust until I get what I asked for"

so what's the difference? well, in the first situation, there's no guarantee that you'll get the same rudder position every time you send, say, 50%. actually, it's likely that you won't, because of "slop" or play in the rudder. in the second situation, we have a dedicated controller whose job it is to make sure we get exactly what the heading controller asks for.

so the cascade is more precise because you get the rudder position you want really quickly. does that mean that it won't work the other way? nope. in the single-loop setup, the heading controller is going to keep adjusting it's output until it gets what it wants. so if sometimes centered is 50%, and other times it's 55%, it doesn't really matter. the controller will eventually find the output that gets it what it wants.

the problem is that it will have more trouble getting to the desired heading than the cascaded way. so cascade is more complicated, but if done right it gives you better control.

(a note on nomenclature. the cascaded controllers can be referred to as Master-Slave, Outer-Inner, or Primary-Secondary depending on who you ask.)

hope this helps

Thank you very much br3ttb for your answer. The more expensive autopilots are really adaptive in a way that they automatically figure out the boats characteristics and adjust for that. They can even adjust for changing weather conditions. So my question is do they still use a PID controller with some intelligent program to change Kd, Ki and Kp or do they use some completely different controller? What is exactly an adaptive controller?

So my question is do they still use a PID controller with some intelligent program to change Kd, Ki and Kp or do they use some completely different controller? What is exactly an adaptive controller?

adaptive control is an umbrella term for a controller that changes its behavior on the fly. how do they do this? I have no idea. they could use a neural network and it would fit this definition! (although fitting one on a microcontroller would be an impressive task)

the pid library has been designed with adaptive control in mind. Example 2 on the wiki uses a form of adaptive control, switching between aggressive and conservative tunings on the fly.

so, while I don't know how they do it, I have a feeling you could use pid. as long as you're ok with some experimentation you should be fine. "I know that THESE parameters work well in calm seas, while these work well in 5ft swells. I'll automatically switch between them, or even interpolate between them, depending on the situation I'm in." if that isn't enough you can even bring in some Feed Forward control, but it's probably better to cross that bridge when we come to it.

now I should add here that I'm not a seaman, so I have very limited knowledge of "changing weather conditions" and how they affect the navigation of the boat. my intuition is that the pid library should give you
the tools you need. if not, you've spent 0$ and learned a little about control. :wink:

Hi guys, I am a newcomer to the Arduino and this is my first post. I purchased one to do a few chores as part of a Car PC installation and have just about got the main hardware and software elements sorted out enought to actually start putting some stuff together.

I was actually thinking about addng a climate control system to my car while driving earlier today and new there were some intergrative vcontroller solutions out there and now I have found one for the Arduino! By the sound of this thread, this is exactly the sort of software I would need to add climate control.

However, in the case of airconditioning, there are two parameters to adjust, one is the temperature setting and the other is the fan speed. Could this library be adapted to control two variables in unison? to achieve the desired temperature setting?

However, in the case of airconditioning, there are two parameters to adjust, one is the temperature setting and the other is the fan speed. Could this library be adapted to control two variables in unison? to achieve the desired temperature setting?

I don't see why not. you would probably just need to do some Post-Processing on the output. so the pid would still be computing one number, but you would massage it a little. the easiest example of this would be to take the output of the controller and send it to BOTH the fan speed and temp setting. so as the pid output gets larger, you ask for colder air and more of it, simultaneously.

SO:

void setup()
 {

   pid.SetOutputLimits(0,255); //tell the PID to range the output from 0 to 255 (this is the default range, so this really isn't necessary( 
   Output = 0; //start the output at ALL off and vary from there
   pid.SetMode(AUTO); //turn on the PID
 }


 void loop()
 {
   //give the PID the opportunity to compute if needed
   Input = //cabin temp
   Setpoint = //desired temp
   pid.Compute();

   FanSpeed = Output;
   TempSetting = Output;
 }

note, you could also set this output massaging to first speed up the fan, then adjust the temp, or vice-versa, but that would make tuning the controller (finding the right P_Param, I_Param, D_Param) a bit more difficult.

Brett

Thanks Brett I am going to give this some consideration. If I left the fan with only 4 speeds as the original is rather than using a infinitely variable speed controller, would that make things easier or harder? Would your feed forward technique help?

Neurasonic asked for a story on PID control. Here's my take.
PID stands for proportional, Integral, differential. What do THEY stand for? Start with comparing what you have with what you want with what you have. The difference is called the error signal. If you use only this error signal to drive the output, you have a proportional controller (if the error signal is linear or proportional). This can be OK, but there HAS to be an error to keep driving the output, so it's never exactly right.
OK, how about toting up the small difference, time after time, when you are as close as you can get with the proportional circuit, and driving the output with THAT too? That can work and hit the desired output on the nose.
Now what about if we next want a step change in output?
If we grow restless with a fast start, and a slower slower approach to the desired output, we can get bold. By monitoring the rate that the error signal changes we reduce the time to reach the target value, and (hopefully) minimize the over shoot and hunting chances.
Having said all that PID controllers can be a pig to tune. Some people find fuzzy logic controllers are much easier to understand and to set up.

Brian Whatcott
Altus OK

Having said all that PID controllers can be a pig to tune. Some people find fuzzy logic controllers are much easier to understand and to set up.

Having worked before retiring in a oil refinery I can agree that loop tuning a PID controller can sometimes be a challenge. It's not so much that it is difficult but rather it can be so time consuming that people lose patience.

One problem is that there can be such a process time delay, especially for temperature loops, that it takes some time to see if a specific tuning change made an improvement or made it worst. Some controller manufactures have added auto-loop tuning features into their PID controllers and a few I worked with worked pretty well.

Lefty

Hi Brett

Thanks for the great library! It's been flawless on my project.

I noticed in a few of your posts you mentioned you didn't think SetInputLimits would be used much. I just wanted to let you know that without it, I couldn't have used the library so easily. My process input is actually a value I'm reading on RS232 and converting to a weight from 0-0.5 grams. I was able to set in input limits to 0, 0.5 and it works perfectly.

My next project will probably use one of the Maxim thermocouple to digital chips, and I'll once again use the setinputlimits function. I vote to keep this in the code!

Thanks for your contributions,
Nigel

So many replies, so little time:

RodW - using 4 speeds is probably the safest way to go from an equipment standpoint. in that case, the easiest thing to try first might be an output divider. whatever the pid is asking for, divide by the fan speed(1-2-3-4) and send that to the temp setting. as the temp setting (not the pid output) gets close to the max, bump up your speed to the next level. if it gets close to the min, drop the speed down one. dividing the output will have a Feedforwardesque (totally a word) effect. the signal to the temp setting will instantly be changed when the speed changes.

Brian - I thought it stood for Proportional, Integral, Do not use. :wink:

Brian & Lefty - I find that the blessing and the curse of the PID is it's ease of configurability. you can get a control loop to "good 'nuf" pretty quickly. the problem is that sometimes that's a ways away from "good." I'd say, as far as arduino is concerned, simple fuzzy logic is the right place to start. that can get real complicated real quickly though, and at that point it's time for this library (IMO)

Nigel - Fear Not! I'm not getting rid of Input Limits by any means. I just separated them out into a separate function (SetInputLimits) to help the uninitiated. this is already complicated enough.

Brett

br3ttb,

You might want to include a default constructor in your next build. This might be my lack of experience with this platform but the following would not compile:

include <WProgram.h> 
include<PID_Beta6.h>
class foo{
public:
PID myPID;
}

Apparently it would not compile b/c it could not find a matching function call to PID();

I am new to this particular platform, so I could be missing something, however to get this to work in my class I had add the default constructor to your code and recompile.

Otherwise your package looks good.

I never considered that people would be embedding my class into another class. COOL!

The reason I didn't go with a default constructor is that for the pid to run correctly, it HAS to have the things specified in the current constructor (input, output, setpoint, tuning parameters.) I figured that would be a gentle way to get people to specify them.

maybe a middle of the road option would be to include a default constructor but have it commented out? if you're writing a new class you'll likely have the know-how to find/ uncomment. if you're the standard Arduino user you'll notice no change. thoughts?

Brett