Prevent climate control from yo-yo-ing between heating and cooling

I have a programming question. I’m building a climate controlled box (old fridge) to ferment saucages. I have a heating element and a cooling element I can control plus a temp. sensor. Now if the box is to cold and i want it at 35 celcius the heating will kick in and stop at 35 celcius. But the temperature in the box rises a bit more do to lag in reading sensors etc, so it gets to hot and now the cooling kicks in. But on the way back to 35 celcius the same thing happens, the temperature overshoots to 34 or 33 and so the heating starts. So the two systems start yo-yo-ing. Is there a logical way to prevent this from happening. At the moment i have this logic. Anybody got a suggestion to improve this?

int maxTempDiff = 2;
int maxTemp = tempSet + maxTempDiff ; 
int minTemp = tempSet - maxTempDiff ;
if ((heatingState == 0) and (intTemp < minTemp)) { 
        digitalWrite(relayHeating, HIGH); 
        heatingState = 1;
if ((heatingState == 1) and (intTemp >= tempSet)) {  
        digitalWrite(relayHeating, LOW); 
        heatingState = 0;
if ((coolingState == 0) and (intTemp > maxTemp)) { 
        digitalWrite(relayCooling, HIGH); 
        coolingState = 1;
if ((coolingState == 1) and (intTemp <= tempSet)) { 
        digitalWrite(relayCooling, LOW); 
        coolingState = 0;

Smart HVAC thermostats typically will stop heating or cooling at a certain point, and only switch modes once the temperature goes a few degrees higher or lower than the setpoint. They also include a timer to prevent the cooling cycle from kicking in more than every 15-20 minutes to prevent wear on the cooling system.


To add to what @picsil mentioned, they may also use PID-type controlling which includes the hysteresis (+/- temperature zone around setpoint). There is a LOT of stuff on the web you can find for Arduino I suspect.


@peekay123 What I was trying to say, but you said it more elegantly. :slight_smile: Thanks for the added detail.


There is a PID (proportional integrated derived) control library in the community libraries- best to understand the theory behind these control algorithms first though.

Temperature control is like water sloshing around in a tank as you let it in or out - you will have to wait a while for the “level” to settle before taking measurements and reacting to them - in your use case time is probably not that critcal and a 5 or 10 minute settle time probably wont affect the outcome much - so as a simple start point, before getting lost in “PID” - I would use some timer delays to space out your measurement cycles and see how it goes.


+1 to @shanevanj’s sugestion.

For a test, turn off your heater and see how far the cooling will overshoot.
Then turn off your cooling and see how far the heating will overshoot.
Use that info to create (2) “OFF” thresholds (one for each).
IE: if the enclosure temp continues to rise 2 degrees after the heater is turned OFF during your test, then you would know to stop Heating ~2 degrees short of the target temp.

You could also add some thermal mass (sealed gallon jugs of water, etc) inside to help slow down the temperature swings and stabilize the system.


Your system is essentially unstable because your inputs ( heating /cooling) are too powerful for the measurement lag.
I suggest to do your heating or cooling in timed bursts - eg 10 seconds - then monitor temperature and the rate of change, and respond accordingly.
So if you wanted to heat the chamber you would turn on the heater for 10 seconds, then monitor the temperature. So long as the temperature is still rising (you will have to pick a minimum rate), don’t turn the heater on again. If the temperature is no longer rising and is still too low, then add another burst of heat.
The same (but in reverse of course) applies to cooling.

If you want to get a bit more sophisticated you could make the heating/cooling burst length proportional to the temperature error - so as you get closer to the target you heat or cool for a shorter burst. Obviously this is a basic proportional controller.