PID Controller Basics Using XOD and Arduino

Victorian DeLorean
7 min readMar 16, 2018

--

As a beginning student of the Arduino environment and aspiring maker, you’ve probably done some experiments with interfacing the board to some external hardware, such as LEDs, relays, sensors, or motors. And you’re also likely at least aware of the Arduino’s ability to act as a sensor and data acquisition tool itself via monitoring the voltages produced by external hardware, and digitizing those values for processing via its onboard ADC (analog to digital converter) ports.

But in many situations, as a systems designer, you’ll want to have more control than just the ability to switch an LED or drive a motor into only one of two states. Often you want to be able to select some state in a range of states, somewhere in between the device being shut off and moving at full speed or running at full power, and command your external hardware to enter that state as quickly as possible and maintain it with no deviation once it gets there. In order to, say, build a robot which can successfully pick up an object, follow a line, or balance itself without tipping over, you need a feedback control system in order to hit your target.

The good news is that a general algorithm called “PID” exists to handle control problems of just the kind we’ve been talking about. PID stands for “Proportional, Integral, Differential (control).” It’s a very general algorithm that’s applicable to a wide range of feedback control problems, so one can have some assurance that a design which works with one type of heater, servo, or motor will likely transfer to another type without too much difficulty. And it’s not necessary to be a coding expert to implement it; while there are many software implementations of PID controllers, including code that’s available to download from the stock Arduino IDE’s repositories, I’ll be giving examples in XOD sketches, a powerful new environment for Arduino microcontrollers that allows designers to rapidly prototype hardware control systems with a drag-and-drop GUI interface.

To use an electric heater as an illustrative example, with a heater that can only be fully on or off, the most naive feedback control system that can be devised to attempt to keep the room at a comfortable temperature is called “bang-bang” control. The algorithm is very simple: when the thermostat detects the room temperature has increased a bit beyond the set point, say 75 degrees with a set point of 72, it shuts the heater down. When the thermostat detects the room temperature has dropped a little below the set point, say 68 degrees, it switches the heater back on. That’s it! Bang-bang, on-off, there are only two states and the system can only be in either one or the other.

Mocked up in XOD nodes such a system would look like the sketch above, where the “digital-output” node could be used to switch a relay coil on and off to control power to the heating element.

“Bang-bang” control with no lag time in the response of the system being controlled. The output value slams from one extreme to the other.
A more realistic system which has some lag time between input and output. The output value tries to stay at the set point, but continually wanders around above and below the target value.

A control system like this can sometimes work pretty well; it’s actually the most basic example of “proportional” feedback control: when the software sees a difference between the target and actual value, the actual value should be commanded to move towards the target. But there’s a problem — it can be extremely difficult to get the system you want to control to stay where it needs to be reliably. As the output plots above show, with no lag in the system, the output value shoots from one extreme to another. With some time lag added like you’d find in a real heating element the situation is improved somewhat, but the output wanders and never settles down.

We can do better than this using PID, and the latest versions of the XOD environment (0.18.0 and later) includes an implementation of a PID controller functional block ready to use, located in the xod/core/pid-controller stock patch node directory.

This screen capture shows the patch node “pid-controller” from the installed library added to an empty sketch, and at the bottom left a list of inputs and outputs that can be edited to constant values, or connected to other nodes in a design. At the bottom of the PID controller node is a single output which is used to generate output values fed into the device being controlled and push it towards the target value.

Along the top are a number of inputs. “Input” is used to connect the feedback signal from e.g. a temperature sensor into the control block, to be compared with the desired set point connected to the “Targ” patch point. “Kp”, “Ki”, and “Kd” are coefficients which determine how much proportional term, integral term, and differential term should be generated from the error between the target and input values — how adjusting their values affects the behavior of a PID system will be explained as this article series goes along. And “Upd” and “Rst” are respectively an input for clock pulses that tell the controller when to update its calculations, and a pulse that can reset the PID node to its initial state.

This XOD sketch shows the PID controller node connected to a software “virtual” model of a heater (also implemented in XOD). The “heater-model” node introduces thermal inertia, and a sensor lag, similar to what you would encounter when trying to control a real system.

Proportional control alone. The output approaches the target value, but fails to ever reach it.

It seems reasonable to make a first attempt at controlling this system simply through pure proportional control, by setting the “Kp” parameter to a number between about 0.5 and 1.0, with the others set to zero. The graph shows that the response is quite a bit better than the oscillations that resulted with “bang-bang” control. However there’s a new problem: the temperature doesn’t ever make it to its target. The lag time in the sensor response to a change in input value confuses the purely proportional controller by introducing some uncertainty as to the true state of the output. The controller errs on the side of caution and gives up before the temperature gets to where it needs to be.

Proportional and integral control. The output rapidly adjusts to the target value and stays there.

Increasing the integral coefficient in the PID controller input block up from zero a little bit helps the situation a lot. Leaving the “Kp” parameter the same, the “Ki” parameter has been increased to about 0.2. Integrating (or, roughly speaking, keeping a running average, for those not intimately familiar with calculus) the error term generated by the PID block constantly comparing the target value with the actual value adds a memory effect to the controller, a measure of how much error there was in the past that still remains to be corrected, while the proportional term works at correcting the current error. Adding bit of integral term to the proportional control of the sketch’s heater model eventually eliminates any residual difference between the target and actual value.

Proportional plus a larger amount of integral term — too much integral term causes instability and oscillation.

A little goes a long way; if the integral term is increased too much the system becomes unstable. Here the “Ki” parameter has been increased beyond 1.0 and oscillation and instability is the result. In small doses, the integral term improves accuracy at the cost of slowing the response time somewhat, but for a system like the heater and sensor, it can actually have a destabilizing influence if applied recklessly.

Simple systems with no moving parts like heaters can be stabilized quite well just through experimenting with constant values for the proportional and integral control terms until a set is found that works well, and makes a good introductory example, but isn’t that applicable to more interesting projects directly relevant to robotics involving servos and motors. And we still haven’t looked at the “derivative” portion of the acronym, but in the next article we’ll see how this term becomes relevant to building mechanical control systems that are also able to quickly adjust to a target value.

--

--

Victorian DeLorean

Full-time hardware designer and part-time mad scientist, broadcasting from somewhere deep in the wilderness of the northeast United States.