I've seen calculations for PID in a microcontroller but I'm thinking
something is missing.. or perhaps I'm misunderstanding something.
So if Derivative = current_error - previous_error then it's just effective
for one cycle. It seems like it should be the change over a period of time,
not necessarily one pass through the loop.
One way would be to have an array of error[xx] and take the difference in
change over a period of time involving several of times through the loop.
Also, I've seen some PID that the I adjustment is in units of time.
This might not be a big deal if there is a real high resolution, but if you
have a temperature control that is heating for a 5 degree error, chances are
the derivative term isn't going to have much effect if it's calculated every
millisecond. If it's calculated over a longer period, for example how much
change in the last 10 minutes, it would be more meaningful.
I know a way to do this but I'm just looking for better ideas, perhaps more
efficient memory usage.
Derivative is concerned with the error's rate of change, which given a
time base your calculation does. Its primary use is to reduce
overshoot in systems with a lot of lag, like an oven temperature
It's also the last thing to fool with if you're tuning the controller.
For any fast acting loop, like flow or mass control, turn that damned
derivative off. And if you see an oven approach setpoint then dip
before it gets there, then oscillate gradually toward setpoint, cut it
As a matter of fact, the best thing that ever happened to me for
temperature loops, extruder barrels, that kind of thing, were
auto-tuning controllers. I used discreet auto-tuning controllers,
either Eurotherm or Omega, for barrel zones, just sent them setpoints.
Auto tuning algorithms for use in the RSLogix type control software
was coming out about the time I retired, but didn't work that well
Fast, low lag loops were easy to tune. A little p, lots of i, and
adjust either by factor of 2. Small changes are a waste of time. When
you drive it to oscillation, cut that parameter in half. Or if you
really don't want to oscillate the loop (really large motors, etc.),
sneak up on it a little slower.
Maybe I've been sleeping under a rock, didn't know this.
I've been fighting a buzzing at stop in my Galilmc.com controlled AMC
servo amps and DC servos. 9 out of 10 times the servo will stop
smoothly, the tenth it will oscilate about 1 or 2 encoder counts so
rapidly it makes a buzzing noise.
Adding the low pass filter to PID helped (see below for manual
description) but i ended up reducing P,I and D by huge amounts to stop
it. Now the system is sluggish. FWIW, Galil has servo tuning software
to automatically tune your system. that worked for many years till
this issue popped up.
The PL command adds a low-pass filter in series with the PID
compensation. The digital transfer
function of the filter is (1 - n) / (Z - n) and the equivalent
continuous filter is A/(S+A) where
A is the filter cutoff frequency: A=(1/T) ln (1 / n) rad/sec and T is
the sample time.
To convert from the desired crossover (-3 dB) frequency in Hertz to
the value given to PL, use the
n is the argument given to PL
fc is the crossover frequency in Hertz
n 0 0.2 0.4 0.6 0.8 0.999
On Tue, 23 Sep 2014 19:20:17 -0500, Karl Townsend wrote:
<< user's manual excerpt snipped >>
The low-pass filter and reduced gains sound an awful lot like a bandaid,
not a solution.
If it worked for years and now it doesn't, then something has worn or
broken, or something got "upgraded", or it's been doing it all along and
you only just now noticed. Control systems only work as well as the
plants that they're driving -- they can't do magic if something is worn
What's attached to the servo motors? If it's a ballscrew or some bolted-
up assembly, my first guess would be that over time slop has developed in
the system that allows the motor to wiggle a bit before it comes on to
the load. I base this both on the fact that it used to work and doesn't
now, and the fact that backlash and slop can be a position-dependent
It could also be something electrical -- a broken ground connection
between the Galil board and a motor, or a power supply whose capacitors
have dried out and allow motor current to couple in to the supply
voltage, or worn-out brushes on a motor.
Either that or you've added something with a bit of spring, or you've
taken off some bracing that lets the motors or their loads "twang" a
bit. Resonances like that can be death to a stable control system.
So as tedious and pointless as it sounds, you may want to go over
whatever backlash adjustment you have, loosen and re-tighten all mounting
bolts, check for loose bearings, reverse any "improvements" you made
about the time the singing started, check operation with a different
power supply (or hang an oscilloscope off the power supply and see what
happens to the power rail when it's "singing"), and all that due
For a while I was viewed as a sorcerer by the FLIR Systems service
department, because nine times out of ten I could fix a control system
problem just by having them replace one magic bearing. Then I confessed
that you had to disassemble most of the bolted joints in the assembly to
get to the bearing, and in the process of reassembly you tightened them
all to spec, with Loctite. After that I got summoned to service a lot
less often, but the problems they presented me with were a lot more
(You couldn't just say "tighten all the bolts", because that made no
sense to them. So they'd tighten what they could reach and claim to have
done them all. But replacing a bearing -- that's real.)
(Soon after, the jerks upstairs decided that engineers shouldn't be
allowed to talk to service, and visa-versa. I hate big companies.)
Keep in mind that I'm shooting in the dark here, because I know almost
nothing about your setup. But you know that something has changed; now
you just need to figure out what it is, and change it back.
That depends on a number of factors, including but not limited to sampling
rate, the amount of noise in the system, your desired settling time, and
the settling time that you can actually achieve.
That's a BAD way to do it. It's what's known in the more esoteric corners
of the trade as a non-minimum phase filter, which basically means that the
filter has more delay than necessary for the amount of amplitude shaping
vs. frequency. Delay is a Bad Thing in a control loop, and is to be
It would be perfectly meaningful if the system noise were low enough, and
if there weren't any unexpected, fast paths from heater to thermostat.
You want a band-limited derivative term. The best way to do this is
pretty simple, too (calculate this as one hunk-of-code each sample time):
derivative = (current_error - average_error);
average_error = average_error + k * (current_error - average_error);
Here "derivative" is the answer you want, "average_error" is a number that
you carry from sample to sample (a so-called "state", like your integrator
state), and k is a gain from 0 to 1 that determines the dynamics of the
differentiator. The bigger k is the faster the derivative action, so the
more noise it passes through and the more it helps fast settling. The
smaller k, the less noise, and the less helpful the derivative action is
when you're trying for high speeds.
If you need to mess with band-limited derivative terms then you really
should be doing frequency-domain design at least, but you can sometimes
make things work with seat of the pants tuning. As a rule of thumb, set k
to (10) * (sampling interval) / (settling time), where you know the
sampling interval and, the settling time is what you're trying to
achieve. If you end up computing a k greater than 1, then you need to re-
think your sampling interval or your desired settling time.
The link on my website to the article you want to read is currently
broken: send me an email and I'll reply with a pdf.
I don't necessarily agree that it's a bad way because you can look up how
much time since the last change, for example using slow 100ms loop times and
a 1 degree change in temperature, at the instant of the change, rate was 1
degree per 100ms, this would trigger a strong response, next loop, one deg
per 200ms, next would be 1 degree in 300ms... and so on, decaying every loop
until further change. I think this would be similar to difference in
average error. I like the average error calculation you showed me because
it does (nearly?) the same thing without the array of previous error data.
Thanks Tim, I figured you'd have a better way of doing what I'm wanting to
do. There is a huge relative speed difference in applications, for example
changing a room temperature at 1 degree per minute is fast but a motor
moving at 1 encoder count per minute would be very slow for a 500 line
encoder. The calculations I have seen before is amount of changer per time
period and what I thought would be more useful is amount of time per change,
or low rates of change.
Interesting demonstration on YouTube:
Raffaello D'Andrea_ The astounding athletic power of quadcopters
Well, if what you want to do is find a fascinating array of subtle and not-
so-subtle pitfalls, then by all means give it a whirl.
<< snip >>
I forgot to mention that if you're really going to sample at 1kHz and
close a loop with a settling time of a minute, then your 'k' value is
going to be damned small -- like on the order of 1/6000.
This, in turn, means that you are exposed to your "average_error" term not
having enough precision to keep track of changes. If your current_error
is good to 12 bits, then your current_error * k must be good to 25 bits or
so. That's barely within the ability of a single-precision floating point
number to keep track. Even if you're only measuring temperatures with 8-
bit ADCs, you're beyond the ability to keep track with 16-bit integers.
With modern processors, at a 1kHz sampling rate, you can take care of this
by using double-precision floating point numbers (with something like a 53-
bit mantissa). If you're using an older processor, using 32-bit numbers
and playing lots of scaling games will work.
Speaking of subtle pitfalls.
I didn't like my idea because of the memory usage and processing of the
array on every loop, but I don't think it would necessarily be bad due to
responsiveness because you can respond strongly to the results of the last
loop, I like your way with the average error much better though, less
processing and less memory usage.
But here's some reasoning that I feel is valid, though it wouldn't
necessarily demand a large array. Lets say the application was a room
temperature control and the maximum rate of change was no more than 1 degree
per minute. So if it used the change for the last minute or so, it could
give the strongest response needed for the rate of change, any faster rates
of change would just be from noisy readings.
Another weird thought I had was using the reading array data to calculate
mean and standard deviation to have weak response to ~ +/- 3 sigma and
stronger response to readings representing real change. If I used something
like that in a R/C helicopter gyroscope, the noise level could also be an
indication of out of balance blades, vibration levels that would be more
harmful the the model and the controls. Of course not responding to noise
would also reduce battery drain and wear on the servos.
<< snip >>
What got me thinking about this was Allen Bradley's PID control, I believe
the motion control cards close the loop in the card itself, but the PID in
the processor uses an I time and a D time instead of Ki and Kd. On a
temperature controller or other slower systems, measurements would be more
like a little change over a longer period of time instead of quite a bit of
change in a short period of time.
I'm hoping to use the info in some temperature control applications as well
as some R/C model stabilization applications. I bought some 3 axis gyro + 3
axis accelerometer modules from HobbyPartz for a reasonable price. I had
the Arduino reading the data but I haven't done anything interesting with it
yet. Thought I might start out by trying to get my boe-bot to operate on 2
I'm going to have to slide into discussing this in the frequency domain
-- sorry about that, but I don't know a different way to express it that
doesn't boil down to BS and hand-waving. The thing that you're trying to
avoid here is a control loop that, when a signal starts at any one point
in the loop and goes all the way around, it comes back to the same point
looking the same. If that happens, then your system will oscillate.
Doing stability analysis in the frequency domain is basically an exercise
in making sure that for sine-wave signals, the condition holds that when
the signal goes around the loop and back to the same point, it is either
phase shifted, or smaller, or under some limited circumstances (and this
is hard to get intuitively, but it's true) bigger.
The basic problem you struggle with in a derivative element in a PID
filter is that the positive phase shift you get from differentiation is
good, but gain at high frequencies is bad. You've got the "reduce gain
at high frequencies" part covered with your scheme, but you're ignoring
the effects of phase shift.
This is a type of plot called a Bode plot. It shows the gain and phase
shift of two different differentiators as a function of frequency. Your
proposed differentiator is in black, mine is in blue. To keep the math
from getting awkward, I chose to average over one second at a sampling
rate of 1kHz, rather than one minute -- this doesn't change the basic
results, it just makes the plot easier to look at.
As a rule of thumb, figure that the differentiator is doing good as long
as its phase is above +45 degrees. This is hard to pin down (it depends
on what you're trying to control), but it'll serve to illustrate what I'm
talking about. I jiggered the numbers on my differentiator so that it has
the same gain and +45 degree crossing point as yours.
Now notice two differences between these differentiators: phase shift and
My differentiator never has a phase shift less than 0 degrees. This
means in the worst case, at high frequencies my differentiator acts like
a pure gain, nothing more. Your differentiator, on the other hand, has
phase shift going all the way to -180 degrees. If your plant has enough
gain at a frequency where your phase shift is high, your system will
Your differentiator has about the same high frequency gain as mine on
average, but it has about twice as much gain in the peaks. This extra
gain, even in the absence of the excessive phase shift, could cause
oscillation in certain cases. Add in the excess phase shift, and the
potential for oscillation just gets worse.
The sum total of these two differences is that you just can't crank your
differentiator up to the same gain that I can crank up mine, and maintain
robust system stability. The fact that my differentiator is simpler to
implement is just a bonus.
Here's an old and somewhat terse paper on using the frequency domain in
control systems design, written with a software guy in mind:
You're describing a nonlinear controller. It turns out that doing this
sort of thing makes formal design and performance analysis much more
And, if your performance criterion is to reduce the root-mean-squared
response to noise, it's not the best approach. Given a heavy-duty enough
math background, you can prove that for a linear plant and Gaussian
noise, that the best controller to achieve minimum RMS noise response is
Your scheme will reduce the response to _sensor_ noise, but it'll make
the craft less responsive to small wind gusts and other environmental
If your plant isn't very linear (no real-world plants are wholly linear),
or if your performance criteria aren't to minimize RMS error, then the
"best control is linear" proof is so many horse turds -- but the system
will still be a pain to design for and analyze with the nonlinearities.
<< snip >>
A lot of industrial control applications like to describe the PID
controller in terms of the time constants of the PD and the PI portions
of the controller. This isn't an inherently bad way to do it, but it's
different from how I usually approach things.
The RC model stabilization stuff should be fun. If you start with quad
copters, you can tether them to minimize crash damage while you're tuning.
Polytechforum.com is a website by engineers for engineers. It is not affiliated with any of manufacturers or vendors discussed here.
All logos and trade names are the property of their respective owners.