PID Without a PhD, Finally

You might want to give that section a better title than "The Complete Controller", with the program description "Here is the full text of the PID controller code" :-) Perhaps a big warning in red that this is example code to get started.

In a good many systems, double is not good enough either - it will be too slow. The developer needs to use some sort of scaled integers to get 32 bits of precision (especially in the integrator), and may even need to use 64-bit integer arithmetic for intermediary results.

It would be nice if there were some equivalent to that defined types like float32_t and float64_t, but there isn't one. There are some macros in defining aspects of floating point types, but they are a bit ugly - and since you are always going to have 32-bit IEEE floats and 64-bit IEEE doubles (unless your compiler cheats by using 32-bit doubles, as you sometimes see on small micros), there is nothing there worth checking. If 32-bit IEEE is not good enough, just write "double" - and make a note that it has to be a /real/ double, not a non-standard 32-bit version.

Reply to
David Brown
Loading thread data ...

So is the use of the title "Differential" correct or not? I'm a bit confused. Above you say "Derivative" is the term for use with continuous time systems and "Differential" is for sampled time systems. Here you say "Differential" is the correct term for use with continuous time systems and "Difference" is used with sampled time systems.

--

Rick
Reply to
rickman

assert(sizeof(real_t) >= 8);

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs 
Principal Consultant 
 Click to see the full signature
Reply to
Phil Hobbs

I should make sure that the speed problems with double are pointed out -- I think I mention it, but I may have been so totally focused on just showing the implementation in the simplest way possible that I forget.

32 bit fixed-point is more than adequate for nearly anything, although you do sometimes have to take care with the integrator to make sure that this holds up with real code. If you need more, and you're not building LIGO-III, then you may well be sampling horrendously faster than you need to.

My preference if I'm doing a complicated control system is to use a fractional arithmetic type, where the underlying storage is twos compliment integers but the functional type has values that range from almost -1 to almost +1. You grab integer data, scale it to a fractional, do all the control calculations in fractional, and then convert back to integer to apply to a DAC or PWM generator or whatever. Implementation can be in either C or C++, although you can make more readable code with C

++.

I cover various data types (including ints, fractional, and the pitfalls of floating point) in my book. There's enough to fill a chapter. You do need to have a good understanding of what's happening to the data under the hood if you're going to do controls or signal processing.

Which reminds me -- at some point I remember seeing that fractional arithmetic was a suggested type for C, but I never kept track of whether it went someplace useful or is a dead end.

For all that, there are useful control loops to be closed out there that can profitably use double-precision floating point on a PIC or an 8051 -- just not too many of them.

--
Tim Wescott 
Wescott Design Services 
 Click to see the full signature
Reply to
Tim Wescott

That would give a false alarm on some DSP chips, because sizeof returns the number of characters your variable or type fits into, and if the processor can't handle data in chunks as small as 8 bits a character is bigger (usually 16 or 24, but I believe that it was 32 or 64 in some Cray machines).

Fortunately, in a compliant compiler this is captured in CHAR_BIT:

assert(sizeof(real_t) * CHAR_BIT >= 64)

I oversaw the introduction of the TMS320F2812 into a product line where we had code that had worked for YEARS, which broke because of the implicit assumption that the number of bits in a character was 8.

--
Tim Wescott 
Wescott Design Services 
 Click to see the full signature
Reply to
Tim Wescott

A differential equation uses derivatives.

A difference equation uses delays, but relies heavily on the concept of a first difference (x_n - x_{n-1}) if you're modeling real-world phenomenon.

Please don't blame me for the terminology -- folks have been using this since before I was born, I'm just the messenger.

--
Tim Wescott 
Wescott Design Services 
 Click to see the full signature
Reply to
Tim Wescott

Am 15.04.2016 um 20:48 schrieb Phil Hobbs:

That won't actually work reliably. Remember that sizeof's result is in "bytes", as in: whatever size "unsigned char" is on the target platform. Which might be bigger than the usual 8 bits, particularly on DSPs. Not all the world's a VAX, and a byte is not 8 bits everywhere.

So if your goal is to insist on a 64-bit floating-point 'real_t', you'll really have to say

assert((sizeof(real_t) * CHAR_BIT) >= 64u);

and maybe, while at it, also make sure it's a floating-point type:

assert(0 != (real_t)0.1);

And for good measure, better make those static_assert()s so they trigger at compile time, instead of trying to abort at run time with a message--- which in an embedded system often has nowhere to go.

Reply to
Hans-Bernhard Bröker

D'oh -- why, of course I'll include an appendix or something on how to do this with op-amps. It should have occurred to me immediately.

--
www.wescottdesign.com
Reply to
Tim Wescott

I am familiar with the terminology, you seem to be using the terms irregularly. What you say here is correct, but it doesn't clarify the confusion of your other statements. Here you use both differential and derivative in the continuous time domain. Elsewhere you have used the term differential for the discrete (sampled) time domain.

--

Rick
Reply to
rickman

Most of my embedded systems will at least make a light blink oddly when you hit an assert -- but that's not a Good Thing normally.

--
www.wescottdesign.com
Reply to
Tim Wescott

Well, I'm of the old school, where you define NDEBUG in your production code, rather than using assert() as a shorthand for fatal runtime errors.

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs 
Principal Consultant 
 Click to see the full signature
Reply to
Phil Hobbs

formatting link

;)

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs 
Principal Consultant 
 Click to see the full signature
Reply to
Phil Hobbs

I think derivative is better, it is about the first derivative of the feedback signal after all. Since it is the result of differentiation "differential" gets in use but in electronics differential is used a lot as in "differential signalling", which has little to do with that. Unless I got it totally wrong this is what causes some confusion (not much though, anyone who wants to dig into it and understand what you are teaching will figure it out and if not it will be hopeless anyway).

Dimiter

Reply to
Dimiter_Popoff

I think this is the best approach anyway. Whoever will be reading your pdf will not be an idiot and will think of such implications. I went through the thing - for may be 5 minutes - and never did I stop and think "this should have been done otherwise".

Flooding it with less relevant details will harm it I think.

Then the speed implication is not always true - on one FPU I am familiar with multiplication costs 2 cycles vs. 1 (dual vs. single). On another core I am considering at the moment it is 1 cycle in both cases. Well if the FPU is some 32-bit only cripple and using

64-bit fp will result in some emulation which takes forever things are much worse of course, but you are teaching PID with the paper, not the basics of programming.

Dimiter

Reply to
Dimiter_Popoff

What data type to use when is actually not a trivial decision, and it pretty much boils down to benchmarking candidates on your target system.

--
Tim Wescott 
Wescott Design Services 
 Click to see the full signature
Reply to
Tim Wescott

Then there is no point in including it is there? I run into this sort of thing in reviewing presentations. An item is inserted, but not clearly. I point out the shortcoming and get the reply that it isn't important to the presentation. I ask them why it's in there then.

I'm not trying to duplicate the examples, I'm trying to understand them. The math, presented in a clear way, helps.

It doesn't have to be exhaustive, but it at least needs to be clear. Including equations that can't be easily found other places with an explanation only confuses the matter. Or did I miss some sources I should have found?

--

Rick
Reply to
rickman

I want to thank all who have commented. I've incorporated some of your suggestions, allowed other suggestions to color what I've done, and chosen not to implement others.

But all of your suggestions were considered, and I'm grateful for your help.

--
Tim Wescott 
Wescott Design Services 
 Click to see the full signature
Reply to
Tim Wescott

I would have thought that derivative is just differential as dt->0. When dt > 0 you have a difference equation, as in digital control. If you implement PID in analog and have a true derivative, call it that.

Clifford Heath.

Reply to
Clifford Heath

A port of C to the Control Data CDC Cyber used the entire 60-bit word for a character. I thought it was terribly wasteful at the time, but now it's obvious that if you were stupid enough to want to write a word processor for one, you'd write code that packed 10 6-bit chars into a word solely for bulk text.

Clifford Heath.

Reply to
Clifford Heath

A very tiny nit in the opening sentences:

"I both consult and teach in the area of digital control. Through both of these efforts..."

May I suggest:

I consult and teach in the area of digital control. Through these efforts...

Reply to
John S

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.