Language: EN


Arduino Control Theory - All-or-Nothing Control with Hysteresis

We continue with the series of posts dedicated to automatic control systems with a processor like Arduino, aimed at presenting control systems theory in an intuitive way without formulas.

In the previous post we saw some generalities about what an automatic control system is. We saw what a plant, a controller, a closed loop, and its importance in the system’s behavior.

We ended with the example that you are going to act as the controller and you have woken up in a room. You know that you are controlling the building’s heating system through a lever, and you have displays that show the measured temperature and the setpoint.

Other than that, you absolutely don’t know how your plant is or what is happening. You also don’t know the effect of pressing the lever in front of you, you only know that it increases or decreases the power applied to the building’s heating.


How do you control the system? That is, what strategy do you follow to move the lever based on the indicators you see?

In this post, we will see the simplest and probably most widespread form of control of a system, the all-or-nothing controller and its variant with hysteresis.

What is an all-or-nothing control?

As its name suggests, all-or-nothing control consists of applying all possible action when the measurement is below the setpoint, and not taking any action at all when it is above (or vice versa, depending on the actuator’s effect on the measurement).

In our example, if the setpoint is 24º, it would mean raising the lever to the maximum if the temperature drops below 24º, and lowering it completely if we are above.

Certainly, it can’t be simpler. But logically, this simplicity has its consequences. Thus, the all-or-nothing control has significant limitations that result in a rather poor response, as we will see next.

Output of all-or-nothing control

Let’s imagine that, with a setpoint of 24º, when you wake up you have 18º, and according to the norm, you turn the heating up to the maximum. You go to 20º, 22ºC, 24ºC… and then stop abruptly.

If your system’s response were instantaneous, the moment you stop, the temperature will drop. When it reaches 23.999…ºC, you will turn it on to the maximum. It will rise to 24.00…01 ºC and then stop again.

This will repeat, you will have infinite turn-ons the moment you reach the setpoint for the first time. Since it’s impossible to press the lever infinite times per second, the universe will fix it by breaking something (usually the actuator).

Fortunately for you (and your wrist) many systems have a certain inertia, so you won’t have infinite turn-ons. When you reach 24ºC for the first time, you have the heating on at full power, you’re going all out! And even if you stop, you’ve applied so much power that the temperature will continue to rise for a while, even though you have removed the action.

Well, you haven’t broken your wrist, but now you have an overshoot of the setpoint that you can’t control, because your only way of control is to turn on at full power or stop completely.

Despite the system’s inertia, you will still have to turn your system on many times to maintain a constant temperature. In addition, the possible measurement noise and disturbances (for example, small internal air currents in the building) will contribute to these frequent turn-ons.

All of this results in poor behavior and a shortening of your system’s life. Something that we can improve with hysteresis control, which we will see next.

All-or-nothing control simulation

Let’s illustrate the above with a small simulation. Below, we have the response of an all-or-nothing control applied to a plant with a certain inertia. The setpoint is fixed at 1.0, then it changes to 0.5, and finally back to 1.0.

The only parameter we can vary, K, is the action executed by our controller. In an all-or-nothing control, it is not a parameter of the controller, it is fixed by the system, but here we can vary it to see its influence on the system.


As we can see, at the moment we reach the setpoint, we have multiple short turn-ons, and a “sawtooth” pattern appears in the controlled variable. If the actuator’s power (K) increases compared to the system’s inertia, we have a lower number of turn-ons at the expense of a greater deviation from the setpoint.

All-or-nothing control with hysteresis

We have established that all-or-nothing control has the problem of causing many actuator turn-ons. The solution is simple, we define a range of acceptable values or hysteresis.

In our example, we decide to turn on the heating if we drop below 22ºC, and turn it off if we reach 26ºC. This way, we give the system more time and reduce the number of turn-ons.

Logically, this also has negative consequences, the main one being that in reality we are no longer trying to reach the setpoint but we settle for being “more or less close” to it.

The wider the range we accept (for example, turn on at 20ºC and turn off at 28ºC), the fewer turn-ons we will have, but we are increasing the system’s oscillation range (in this example, an 8º temperature difference is a lot for a heating system!)

In general, when we talk about all-or-nothing control, we refer to all-or-nothing control with hysteresis. However, consider that the case without hysteresis is a special case of this, with the range of values +-0.

All-or-nothing control with hysteresis simulation

Now we will see the response of all-or-nothing control with hysteresis applied to the same system and setpoint evolution as before. This time we have two more parameters, the upper threshold and lower threshold.




We can see that as we increase the threshold range of control, we reduce the time between turn-ons, and they are longer. In return, logically, the oscillation around the setpoint increases.

When to use all-or-nothing control?

If the system’s behavior is so “tight,” then why is it used so much? Case in point, the thermostat in your house is an all-or-nothing control. So in many cases it is used because it is easy to implement and, although its behavior is not the best, it generally always works.

Furthermore, it is the only option when you have a digital sensor, even if you have an analog actuator. For example, imagine that you have a light bulb that turns on if you are above 24º, and turns off if you are below.


You have no other options but to apply an all-or-nothing control, because when the light turns off, you don’t know if you are above 1º, or 20º. And if you know nothing about the plant or the environment, any other strategy is very risky.

Similarly, if you have an analog sensor, it is also the only controller if you have a pure digital actuator. In our example, a button instead of a lever.


If the actuator allows, we could play with making small presses on the button to adjust the action (that is, apply a PWM). This case could be considered analog, not digital. But not all digital actuators allow for a pulsed control.

In summary, if you have a digital sensor, or a pure digital actuator and you don’t know the plant or the environment, you can’t do much more than use all-or-nothing control.

But if you have an analog sensor and an analog (or pseudo-analog) actuator, using all-or-nothing control is a bit lazy. Although, well, it is a simple and functional option.

Implementing all-or-nothing control in Arduino

As we said, simplicity is one of the strong points of all-or-nothing control. Therefore, it is easy to implement in a microprocessor like Arduino.

In fact, we saw how to implement all-or-nothing control in this post. And in addition, you have the Arduino Threshold library to make it even easier.

System limitations

All-or-nothing control (or its evolution, all-or-nothing control with hysteresis) has significant limitations and, in general, a poor response.

The reason is that the system has little information compared to an analog system, which results in the lack of ability to modulate the output against the input error. For example, all-or-nothing control applies the same action if we are at 23.8º as if we are at 12ºC.

In summary, what are the limitations of an all-or-nothing controller with hysteresis.

First, we are going to have multiple turn-ons around the setpoint, which contributes to a shortened actuator’s lifespan.

On the other hand, due to its operation, we will never be able to smoothly reach the setpoint, and we will have to settle for being within an “acceptable range” around it.

Moreover, the behavior will always be oscillatory (in general, similar to a sawtooth), as a result of having to act at the maximum, and then let the system “fall”.

A good example is a line-following robot that only has two infrared sensors. You will see how they continuously oscillate around the line, because they have to “sweep” to see the line.

In general, it is not a comfortable system for the user, although, as always, it depends on the system’s characteristics. It may be tolerable for a climate control, but it is not a controller you want to have control the speed of your car.

Imagine a car that accelerates to the maximum to reach the cruising speed, and then lets the speed drop, and accelerates to the maximum again, giving small jerks around the setpoint.

Fortunately, we have better analog controllers. In the next post, we will see the undisputed king, the PID controller.