As a means for implementing feedback control systems, PID is an important concept in electronics engineering. In this article, Stuart explains how PID can be applied and explains the concept by focusing on a simple circuit design.
So, what is PID? Well, it’s an acronym for Proportional, Integral, Derivative. But that’s not much help, is it? PID is a means of implementing feedback control systems. This article is about a simple circuit that will help you understand PID control. There is quite a bit of math involved in control system theory, but instead I’ll focus on concepts here. For the math, go seek out a graduate-level course in the subject, if you’re interested.
Many processes—ranging from the furnace and air conditioning units that heat and cool your house, to industrial processes, to medical laboratory instruments—need to control some outcome. That might be the temperature in your house, the temperature of an industrial furnace, or the speed of your car when you are using cruise control.
Some processes are simple to control You might have a motor with a fixed load that needs to run at a fixed speed—or a series of fixed speeds. In a case like that, you might be able to just drive the motor with a specific voltage for a given speed. As long as nothing upsets the system, you can get the speed you want just by knowing the relationship between voltage and speed.
Things get a little more complicated when the relationship between voltage and speed isn’t constant. Your motor might be driving a belt in an industrial process where the load varies because of the weight of material on the belt. To maintain a constant speed, you must adjust the drive voltage. Or your car’s cruise control has to maintain speed when you are driving up a hill. Those changes require feedback so that the controller can adjust the output appropriately.
Feedback allows a control system to monitor the output of a system and adjust the control input—voltage, in our motor example—to keep the output at a desired value. The desired output is called the setpoint. In the motor example, you might measure the motor speed directly. But maybe what you really want to do is control the amount of material (by weight or volume or something else) that is fed into the process. So maybe you want to measure motor speed, but maybe you really want to measure whatever it is you are trying to regulate. Maybe the motor speed is a good proxy for that. Maybe it isn’t.
Using the example of the car cruise control, the speed of the car is what you want to control, but it is controlled by opening the throttle (electronically or mechanically) to increase the gas flow into the engine. You could measure the electrical signal to the throttle, or the amount of gas flowing, but what you really want to measure is speed in MPH or KPH. Everything else is just a means to that end.
All feedback control systems consist of some kind of controller that reads the actual value being controlled, compares it to the desired value (setpoint) and then adjusts the drive—voltage, current, valve position, whatever—to raise or lower the output so it matches the setpoint.
Figure 1 shows the schematic of a simple circuit that can be used to simulate a control system for experimentation. It doesn’t do anything useful, it’s just a learning tool. The circuit consists of a Texas Instruments TM4C1233H6PM microcontroller (MCU) and some support components. Resistor R7 and capacitor C10 comprise a simple simulator of a system that has to be controlled by the MCU.
The R7/C10 network makes a low pass filter. It is driven by a PWM output of the MCU and the “output” (the junction of R7 and C10) connects to an analog-to-digital (ADC) input to the MCU. The R7/C10 circuit has many of the characteristics of a real control system in that it exhibits lag (delay) from the time when the input changes to when the output catches up, and it has a linear relationship between the input and the output. The PWM output of the MCU PB7 (port B bit 7) output is filtered by R7/C10, producing a DC voltage at the ADC input on PE3.
The voltage at the ADC input is proportional to the duty cycle of the PWM signal driving R7. If the PWM duty cycle is 50% (half on and half off), the voltage at the ADC input will be about half the 3.3 V drive voltage, or 1.65 V. If the duty cycle is 20% (high 20% of the time, low 80% of the time), the ADC voltage will be about 0.66 V. Since the ADC is 12 bits, the input voltage is converted to a 12- bit word ranging from 0 to 4095. So, half the supply voltage, 1.65 V, will be converted to a numerical value of 2048.
Transistor Q1 is driven by port PE0 of the MCU, and when PE0 is high, the 22 kΩ resistor RL is switched into the circuit in parallel with C10. This simulates a step increase in the load so as to compare how different PID parameters affect recovery from a step change. Resistor RL is shown as 22 kΩ, but it is actually socketed so that different values can be used.
The serial port is connected to J2 and is used to send the ADC voltage readings back to a host PC so they can be captured and plotted. An external RS-232 converter is used for the connection to the host serial port, as described in my article “Debugging Embedded Systems with Minimal Resources” (Circuit Cellar, July 2016). The waveform could also be captured on an oscilloscope. The tutorial circuit was used to generate the waveforms used in the rest of this article.
The simplest control method, as mentioned, does not use feedback at all. It just assumes that a given input (PWM duty cycle in the case of the simulator circuit) will always produce the same output, otherwise known as open-loop control. Figure 2 shows the output of such a case, where the circuit drives the PWM duty cycle to 50% and the R/C circuit output (graphed in ADC values) goes to 2,048. The x-axis at the bottom is sample intervals. The MCU firmware updates the output 500 times per second, so each interval on the graph is 2 ms. The parameters in the figure caption are the control parameters used to create the waveform. These will be explained later.
The ADC voltage ramps up when the input is applied until it reaches the setpoint of 2,048—representing 1.65 V, or half the supply voltage. This ramp is because of the delay introduced by the R/C circuit. You can also see a problem in the second half of the graph, where the voltage drops significantly.
The voltage drop occurs because I selected parameters that switched the 22 kΩ step load resistor, RL, across C10, 250 ms after the run started. This simulates a sudden change in the load presented to the system, such as an increase in the load on the motor discussed earlier. In open-loop control, the change in voltage is not fed back to alter the drive voltage, so the output drops when the load is applied. This is the problem with open-loop control systems. They only work if the relationship between input and output doesn’t change. Another disadvantage to fixed controllers is the slow ramp time. Since the controller just has one control voltage for one desired output (speed, voltage whatever), the ramp to the target value can be very slow.
The simplest feedback control system is on-off control, sometimes called bang-bang control. This is usually how your oven, air conditioner and furnace are controlled. The controlled element—heater in the oven, for example—only has two states: full on and full off. If the temperature in the (electric) oven is below setpoint, the heating coil turns on. If it is above setpoint, the heating coil turns off.
On-off control is used in systems such as this because implementing a variable control, where the heater is just a little bit on, is expensive. It is also unnecessary. All these examples have a slow ramp between activation of the controlled element (heater, A/C unit and so on) and actual change in the desired output. For example, when the temperature in the oven goes too low, it takes many seconds or minutes for the heating coil to get hot enough to start raising the temperature and for the thermostat to react to the change. This causes the temperature to continue dropping for a bit even after the coil is energized. The same thing happens in reverse when the heat is turned off. It takes some time before the coil cools enough that it is no longer heating the oven, so the temperature continues to rise for a short time.
Figure 3 shows the simulation circuit configured to control the setpoint, again at a value of 2,048, using on-off control. As you can see, the output does reach the setpoint but it oscillates around the setpoint quite a bit. This is one of the characteristics of on-off controllers. They need to have enough power to handle the maximum for which they are designed, but that means they have too much power most of the time.
Your furnace and oven won’t oscillate as much as shown in the example; this example shows what it would look like to have a mismatch between the power available and the power needed. A very small oven with a large heating cool might do this. This example does illustrate the limitation of on-off control. This is why the HVAC system in your house is sized to the house and the climate in which you live. You don’t want the system constantly switching on and off. If C10 in the tutorial circuit were changed to, say, 20 µF, there would be much less oscillation and it would more closely represent a typical system using this type of control.
PID (proportional, integral, derivative) control provides smoother operation of a control system with better tracking of the setpoint. The PID system uses the following parameters:
Error: The difference between the setpoint and the actual output.
Proportional gain: A value that is proportional to the error.
Integral gain: A value that is represents to the integral (sum) of the previous error values
Derivative gain: A value that measures how fast the error is changing.
Now, let’s look at proportional terms, integral terms and derivative terms in more detail.
Proportional term: The simplest PID control uses the proportional term only. Figure 4 shows the simulator with only proportional feedback. You can see a ramp toward the setpoint, similar to the open-loop drive but with a little overshoot where the output goes a little above the setpoint.
Proportional-only control provides faster ramp to the target value than the fixed output does. The proportional value is proportional to the error term, so the further the output is from the setpoint, the higher the drive voltage will be. Although both methods are going to end up with about the same output level, during the ramp up, the proportional control system will drive the system with a voltage higher than the fixed-output controller will, reducing the drive level as the output nears setpoint. This ramps the system toward the target faster than the fixed output drive does.
It’s not obvious from the figure, but if you looked at the raw data, you would see that the voltage stabilizes a bit below the setpoint. This is a problem with proportional-only controllers; they tend to have a little offset because when the output gets very close to the setpoint, the error gets very small and the proportional term is too small (zero or close to it) to move the output any closer to the setpoint. Figure 4 also shows the 22 kΩ load switched into the circuit; the proportional controller doesn’t have enough gain to overcome the load change.
Integral term: The integral term fixes the offset problem. The integral term is the accumulation of error values over time, so the longer the output is different from the setpoint, the more the integral term grows. Eventually, it gets large enough to push the output closer to setpoint.
Figure 5 shows the simulator with P and I terms. You can see the integral term causes a larger overshoot. But the final output stabilizes around the setpoint with just a small oscillation. In the firmware on the tutorial board, integration doesn’t start until a few samples after the ramp starts; this prevents excessive overshoot due to the large initial error.
You can see that the integral term manages the 22 kΩ load change; you can see the undershoot when the 22 kΩ load is applied and then the controller pulls the voltage back to the setpoint. When the load is removed there is again a small overshoot as the load returns to the steady state. A larger amount of integral gain will recover more quickly from the step change, but it also produces larger overshoot values.
If you looked at the PWM duty cycle during this time, see it go from about 50% duty cycle to about 70% duty cycle when the 22 kΩ load is applied. The controller will increase the drive voltage, by increasing the PWM duty cycle, to maintain the setpoint.
Derivative term: The derivative term is not used as often in control systems as proportional and integral. Derivative measures the difference in the error over a short period of time to get the slope or rate-of-change of the error. The idea is that if the error is changing rapidly, more “push” is needed to bring the output to the setpoint. In the simulator circuit, I limited the derivative to the difference between the current sample and the previous sample. But depending on what you are trying to achieve, you might use a larger time scale or you might want to filter the derivative term.
The effect of the derivative term is to adjust the drive based on how fast the error is changing. As the output nears the setpoint, the error gets smaller, making the derivative negative. This offsets some of the integral effect, reducing the initial overshoot. Figure 6 shows the same waveform as before, but with a somewhat aggressive derivative added and the proportional term reduced. You can see more oscillation around the setpoint, however. For this simple control system, the derivative doesn’t add much benefit.
PID systems generally require tuning to match the response to the application. This includes not only the desired output, but the amount of load the system will handle and how fast it responds to changes in the load or in the setpoint. For example, in a biomedical application, you might be heating biological samples and you can’t let the temperature get too high because it will kill whatever you are culturing. In that case, you might tune for minimum overshoot. In another situation, such as an industrial oven, you might need fast response and you can live with some initial overshoot to get to the setpoint faster.
Tuning also involves adjusting for the lag in the system. In the simulator, the lag is the time constant of the resistor and capacitor values. Some industrial processes might have lag times of seconds, minutes, or even hours.
Tuning can also include a bias value. This is an offset that is the starting point for any desired offset. The PID terms are added to this bias to generate the desired drive voltage (PWM) output. In the simulator, the unloaded output is proportional to the PWM duty cycle. I just set the bias to 90% of the desired setpoint value. That is, if the setpoint is 50% of the maximum value, I set the bias to 45%. Other systems, especially non-linear systems, will need to be tuned by determining what drive value results in what setpoint value. This is typically done with the feedback turned off so the system operates open loop. Of course, if the specifications for whatever you are controlling includes the open loop input-to-output correlation, then you can avoid that step.
There are various methods for tuning a PID system, including Ziegler-Nichols method, Relay method and others. Commercial PID systems can be tuned using software that optimizes the parameters. I didn’t tune the examples used in this article for any specific requirements; I picked arbitrary values that exhibited what I wanted to show. But if you are trying to simulate something specific, then you will need to be more precise about the values you use.
Like a real-world control system, the simulator has limitations. I used a fixed 22 kΩ resistor to simulate a step change to the load, and I used the same value for all the step change examples to compare the differences. But like any control system, there are limits to the load change the simulator can handle. The smallest value of resistor you can apply as a load is about 10K for 50% setpoint, about 5K for 30% setpoint, and so on. Below those values, the output can’t be driven to the setpoint even with 100% duty cycle.
You can see the same thing in the furnace in your house. If you leave every door and window open on the coldest day of a Michigan winter, the furnace won’t be able to keep the house comfortable even though it will run constantly. I don’t really recommend this experiment, though.
Some factors to consider:
Fixed lag: The simulator has a fixed lag, controlled by the R/C values. So, you can’t simulate a system with variable lag unless you add additional circuitry.
PWM frequency: Like any PWM-driven system, if the frequency of the PWM period gets so low that it is close to the system lag, you will get strange results. The PWM signal as programmed in the firmware is 10 KHz. You can change that if you want to experiment with the effect of PWM frequency on control accuracy.
Precision: The simulator firmware, as written, limits PWM duty cycle changes to integral percent (50%, 51% and so on). The TM4C timer that produces the PWM output has more resolution than that, so you could increase the precision. But in a real system, noise can affect the measurements; additional precision in the controller might not translate to better control of the actual system.
Firmware for the system is written in C, using TI’s Code Composer Studio software. The firmware includes a simple-minded console that accepts serial commands as follows:
Mx: Set operating mode x; 0 = on-off control, 1 = PID, 2 = Open loop
Fx: Set open-loop drive percent; 1 = 10%, 2 = 20%, etc.
Px: Set proportional factor to x (0-99)
Ix: Set integral factor to x (0-99)
Dx: Set derivative factor to x (0-99)
Lx: Step load control. 0 = no step load. 1 = apply load after 0.25 sec, hold for 0.25 sec. 2 = apply load after 0.5 sec, hold for 0.25 sec.
Rx: Run system for x seconds (1-9)
Ox: Output selector. O0 = send hex ADC values to host. O1 = send duty cycle values to host.
These are the parameters that are described for the figures. You can reproduce the waveforms shown by using the same parameters. You will need a serial terminal/console program to use the tool, something like Hyperterminal. I used a simple Python terminal application that I wrote for another project years ago.
The scaling factors in the firmware for the P, I and D values aren’t scaled to a specific transfer gain. They are just scaled so the 0-99 range of gain factors produced a reasonable range to demonstrate the concepts.
When the system runs, the ADC values are sent back to the host PC as 4-dight hex numbers, separated by spaces (0x0751 0x078A …). To produce the graphs shown here, I used a simple Python program to convert the hex values to decimal, then pasted them into an Excel spreadsheet. Of course, nothing keeps you from writing an application to capture the output in real time and graph it any way you want. You can also select output of the duty cycle as 2-digit hex values using the “O” command.
Jumper W1 enables firmware download. To program the MCU, reset (using S1) or power on the board with W1 shorted. The MCU will enter boot mode and the TI LM Flash Programmer application can be used to program the device via the serial port. Then remove the short on W1 and reset the board again.
Variable setpoint: All the examples I used here have a setpoint of 50% of the maximum voltage (ADC value of 2,048). That value is defined as a constant in the firmware, but there is no reason you can’t make it a parameter that is set by the operator.
Using a development board: I constructed the circuit on a piece of perforated board by soldering the TM4C MCU to a breakout board. But you could also implement this with one of the TI TM4C Launchpad boards. These boards are inexpensive and easy to use. In fact, you can use a development board for almost any MCU, as long as it has a PWM output and ADC input. But using a TM4C board will allow you to use most of the C code as-is since configuration of the peripherals is already written for the TM4C parts. I used the circuit in Figure 1 because I have other plans for this board, but it certainly is easier to use a development board. Note that if you use a Launchpad board, you may have to change some of the ports or timers because the specific ports and timers used in my design may already be dedicated to something else on the Launchpad board. Figure 7 shows the schematic for the RS-232 converter circuit that plugs into connector. Full details are in my July 2016 article.
The tutorial circuit is a simple concept that provides a simulation of a control system. You can use this circuit to experiment with PID control methods, altering the parameters to see their interactions. This won’t turn you into a controls engineer, but if you haven’t worked with PID before, it provides a hands-on experimentation tool using real parts.
Wikipedia has a good article on PID control: https://en.wikipedia.org/wiki/PID_controller
TM4C1231233H6PM datasheet: http://www.ti.com/lit/gpn/tm4c1233h6pm
Texas Instruments | www.ti.com
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • JUNE 2019 #347 – Get a PDF of the issueSponsor this Article
Stuart Ball recently retired from a 40+ year career as an electrical engineer and engineering manager. His most recent position was as a Principal Engineer at Seagate Technologies.