Arduino PID Library

Class? The only thing I recall about class is that if your late too often you could receive saturday detention. :wink:

Lefty

Brian:

psyber is using the library in a way I never even considered. Most people will take the pid library and use it right in their Arduino program, the way my example illustrates.

the way I understand it, psyber encountered a problem trying to embed a pid within a library of his own creation. On the library creation side, the rules are a little different. To make it work, he needed to -very lightly- massage the pid library code. His suggestion was aimed at saving the next guy some trouble.

Lefty: This is all I know about class :wink: : Sidney Poitier - IMDb

Brett

Here is another vote for making it easier to embed the PID library in another class. I was in the process of creating a motor control class which would embed a PID controller to set the PWM signal to the motor when I saw psyber's post.

Edit:
It may not be necessary to add a default constructor. I haven't tested this yet but it does compile.

test.pde

#include<PID_Beta6.h>
#include "foo.h"

foo myFoo;

setup()
{
}

loop()
{
}

foo.h

class foo
{
public:
   foo();

   PID myPID;
   double Input;
   double Output;
   double Setpoint;
}

foo.cpp

#include "PID_Beta6.h"
#include "foo.h"

foo::foo() : myPID(&Input, &Output, &Setpoint,2,5,1)
{
   // initialize foo
}

I had to look up initialization lists, in my real life I've never used them. In another environment I'd include a pointer to a PID object in my class and use new to create it in the constructor.

I has use this libary to control angle of robot arm, it work as well on fixed setpoint.

if my setpoint is change it will not go to setpoint, it have offset. i try to increase D parameter, i would not help.

i guess my problem is my motor start moving at PWM 80%. when is start moving it's very fast and on next sampling it already overshoot.

anyone have some idea to slove this. :wink:

on next sampling it already overshoot. anyone have some idea to slove this.

you can use the SetSampleTime() function to make the pid sample more quickly. (Arduino Playground - PIDLibraryAdvancedMethods)

Brett

I want to make a motor controller that uses distance as the target but is able to accelerate until reaches a certain speed (sometimes is max speed), continue with that speed until almost at destination and decelerate until it reaches the target distance and stops. Sometimes I need to make small adjustments and speed never reaches the set speed and needs to decelerate because it reaches the destination.
Any advices on how to do that?
Thanks.

Can this PID library include a function to accelerate from 0 to SetSpeed and continue at that speed until the SetPoint is reached (because it will automatically decelerate before reaching the SetPoint)?

I have tried to do a function that accelerates until Speed = SetSpeed and only then activate the PID controller, but sometimes I need to make small corrections so the Speed never reaches SetSpeed. Can this be done in the PID controller?

I don't think so. the pid is a "simple" control element whose job is to make Input = Setpoint. once you want to do more complicated things, you'll need to make the pid part of a larger control strategy. it sounds like that's what you're trying to do anyway, so let's talk about that.

First, I'm not sure I completely understand your application. You use both SetSpeed and SetPoint in your question. I'm would assume that Speed is the output from the pid, and Setpoint is the value you want the PID Input to achieve. I'm not sure though.

I don't want to give you bad advice at this point. Could you give a description of what it is you're trying to do in the real world (i.e. "I've got this thermonuclear jetpack, and I'm tyring to control take-off velocity. my inputs and outputs are...") I'll be able to give better advice once I know what it is you're trying to do.

Brett

foo.cpp
Code:

#include "PID_Beta6.h"
#include "foo.h"

foo::foo() : myPID(&Input, &Output, &Setpoint,2,5,1)
{
// initialize foo
}

I had to look up initialization lists, in my real life I've never used them. In another environment I'd include a pointer to a PID object in my class and use new to create it in the constructor.

Nice! I figured there was some way to do it without monkeying around with the original library. I just wish there was a more intuitive method as my C/C++ is extremely rusty. I don't think this is covered in any of my old textbooks either. >:(

br3ttb:
As for the middle ground solution, I see no difference between you adding the code and then commenting it out, and having a developer simply add the code. In either case someone still has to edit the class and rebuild the library.

I hate to resurrect this old thread, but it is a good one, and the PID software looks really good.

Before finding this thread, I wrote my own. I was particularly interested to see how wind-up was handled. I saw that the Integral term was not incremented when the output was maxed.

This seems like a great idea, but doesn't it cause a bit of a glitch when the output drops down from max? Maybe the integral term is well below the value resulting in maximum output due to some other factor such as the differential.

Is this really going to make much of a glitch under these circumstances? I suspect that a "properly" tuned loop will not have such odd behaviour that the differential can push the output that far up/down.

I attempted to limit wind-up by not allowing the integral term to exceed the value that results in full output on its own. Is this not good enough?

-Tony

doesn't it cause a bit of a glitch when the output drops down from max?

I haven't noticed this. the inclusion of the (err>0) and (err<0) are supposed to (and seem to) keep this from happening

limit wind-up by not allowing the integral term to exceed the value that results in full output on its own. Is this not good enough?

the short answer is "yes." It's not as simple with the form of the pid I'm using, because I have a bias term in the mix. I'm in the process of migrating the library toward the method you describe.

Brett

Brett, nice library and easy to use and tidies up my code nicely. Any news on the 'lite'version for basic functionality?

Cheers,
Mike

Any news on the 'lite'version for basic functionality?

I've actually decided to ditch the idea of a lite version. Instead I'm working on reducing the footprint of the full version. The next revision of the library is almost done. it uses integer math throughout, so it's about half the size and 10X faster.

Brett

[edit]On second thought I may be able to add some preprocessor flags to remove a lot of the extra functionality, resulting in a lite library. I'll see what I can do[/edit]

Sounds brill! Look forward to using it.

Mike

Before everything... It's just an advice,I don't want to look pretentious... :-[
I don't understand why you have problems making your PID faster....maybe because I've never used it :stuck_out_tongue: . Sometimes the measurement is not at the same frequency than the Computing frequency, maybe you can't achieve the maximum speed because you are not using timer interrupts, and almost every PID ready-to-use software made by big companies uses timer interrupts. When you use timer interrupts the only limit is the clock speed and the timer's pre-escalator, ahh one last thing, the common acronyms are:
Set Point, (SP)
input: PV (Present Value)
output: MV(manipulated variable)
error
dt : (delta t) that's what you call calc period
Kp
Ki,Ti (I prefer Ki than Ti, where Ki=Kp/Ti)
Kd,Td (same with Kd, Kd=Kp*Td)

EDIT: PV: process variable

input: PV (Present Value)

I was taught that PV = Process Variable

Lefty

I was taught that PV = Process Variable

Ditto.

Of course you are right, PV is process variable, there is a present value, but that is not it. :wink: LOL

I don't understand why you have problems making your PID faster

the issue isn't with when the computation occurs, it's with how long the computation takes when it's excecuted. the computation fires at whatever interval the user desires (set by the SetSampleTime function) the interrupt idea is interesting. I'll have to look into that.

what I was talking about when I said "faster" was the computation itself. the fewer processor cycles it takes to perform its calculation, the more time the arduino has to do other things. and, just as a point of pride, I want the pid to be as efficient as possible.

as far as abbreviations, some are certainly more common than others, but they do vary from manufacturer to manufacturer. off the top of my head:
Process Variable: PV, ME
SetPoint: SP, SV
Controller Output: CO, CV, OUT, OT, OP.

dt is commonly used. I settled on SampleTime (which is also commonly used) because I felt it was easier to understand.

at any rate, give the library a shot! I'd love to hear any more suggestions you might have.

Brett

I've just looked at the source, and it looks very well, I can see that you have done something to prevent windup, I also preffer the Ideal form of the PID algorithm, everything is done efficiently (computing time-speaking), maybe millis() is taking too much, I don't see where else the code could be made more efficient, I will try to do it with interrupts and I will let you know if it works better, also I'm going to implement a kalman filter, so maybe that will be my first contribution to the arduino project, for those who don't know what I'm talking about, a kalman filter must be used with accelerometers and many other sensors..

Thanx for an splendid lib, just the interrupt part missing for me to be 100% satisfied :sunglasses: and maybe a Tracking value/Tracking active.

By the way PV is often referred as "Process Value" in engineering terms ::slight_smile: