PymateIO-hysteresis

From pymate.io wiki
Jump to navigation Jump to search


Abstract

A hysteresis cycle has a setpoint and a hysteresis value around that setpoint.

When controling a heater, the room temperature must fall quite under the setpoint before starting the heater and it must heat until it reach a temperature over the setpoint. This difference from the setpoint avoids continuous heater start/stop around the setpoint temperature.

Hysteresis-heater.png

As visible, the state fall over between two states On/Off or High/Low or True/False and follows the hysteresis curve.

The cycle switch either to an active state (On, High, state=True) or an inactive state (Off, Low, state=False) depending on the iteration through the cycle.

The hyst.py library offers two distinct classes:

  • HeatherTh - thermostat controller with hysteresis to manages an heating cycle.
  • CoolerTh - thermostat controller with hysteresis to manages a cooling/ventilation cycle.

Although the two classes are simply opposites, it is more convenient to identify the state of a cooling cycle as "Cooler.state" rather than "not Heater.state".

Heather Controler

The following example do not use a real temperature sensor but simulate a temperature cycle from 10 to 31°C then 31°C down to 10°C (see tcycle enumeration).

Hysteresis-heater.png

Notice:

  • the thermostat.setpoint = 25.6 call to change the setpoint on the fly
  • the call to thermostat.update(temp) to inform the thermostat with the current temperature and get updated with the current thermostat state.
from machine import Pin
from pymate.pymateio import PymateIO
from hyst import HeaterTh
import time

# Output Pin for the Heater
heater = PymateIO( "Out3", Pin.OUT )
heater.write( 0 )

# Simulate the temperature cycle 
tcycle = [i for i in range(10,31)] + [i for i in range(31,9,-1)]

# Create a Thermostat set on 22°C with an Hysteresis of 2.5°C (-1.25°C to +1.25°C)
thermostat = HeaterTh( 22, 2.5 ) 

# Follow the temperature cycle an see how the thermostat reacts
print( "--- SetPoint %f -------------------------------" % thermostat.setpoint )
for temp in tcycle:
	state = thermostat.update( temp )
	heater.write( state )
	print( "[%s] at %i°C heater is %s" % (thermostat.setpoint, temp, "ON" if state else 'off') )
	time.sleep(1)

# Change the setpoint then 
# Follow the temperature cycle an see how the thermostat reacts
thermostat.setpoint = 25.6
print( "--- SetPoint %f -------------------------------" % thermostat.setpoint )
for temp in tcycle:
	state = thermostat.update( temp )
	heater.write( state )
	print( "[%s] at %i°C heater is %s" % (thermostat.setpoint, temp, "ON" if state else 'off') )
	time.sleep(1)

print( "That's all done folks!")

This manipulates the Output 3 and produce the following results on the REPL output (also available as graph).

Hysteresis-heater-graph.png

--- SetPoint 22.000000 -------------------------------
[22] at 10°C heater is ON
[22] at 11°C heater is ON
[22] at 12°C heater is ON
[22] at 13°C heater is ON
[22] at 14°C heater is ON
[22] at 15°C heater is ON
[22] at 16°C heater is ON
[22] at 17°C heater is ON
[22] at 18°C heater is ON
[22] at 19°C heater is ON
[22] at 20°C heater is ON
[22] at 21°C heater is ON
[22] at 22°C heater is ON
[22] at 23°C heater is ON
[22] at 24°C heater is off
[22] at 25°C heater is off
[22] at 26°C heater is off
[22] at 27°C heater is off
[22] at 28°C heater is off
[22] at 29°C heater is off
[22] at 30°C heater is off
[22] at 31°C heater is off
[22] at 30°C heater is off
[22] at 29°C heater is off
[22] at 28°C heater is off
[22] at 27°C heater is off
[22] at 26°C heater is off
[22] at 25°C heater is off
[22] at 24°C heater is off
[22] at 23°C heater is off
[22] at 22°C heater is off
[22] at 21°C heater is off
[22] at 20°C heater is ON
[22] at 19°C heater is ON
[22] at 18°C heater is ON
[22] at 17°C heater is ON
[22] at 16°C heater is ON
[22] at 15°C heater is ON
[22] at 14°C heater is ON
[22] at 13°C heater is ON
[22] at 12°C heater is ON
[22] at 11°C heater is ON
[22] at 10°C heater is ON
--- SetPoint 25.600000 -------------------------------
[25.6] at 10°C heater is ON
[25.6] at 11°C heater is ON
[25.6] at 12°C heater is ON
[25.6] at 13°C heater is ON
[25.6] at 14°C heater is ON
[25.6] at 15°C heater is ON
[25.6] at 16°C heater is ON
[25.6] at 17°C heater is ON
[25.6] at 18°C heater is ON
[25.6] at 19°C heater is ON
[25.6] at 20°C heater is ON
[25.6] at 21°C heater is ON
[25.6] at 22°C heater is ON
[25.6] at 23°C heater is ON
[25.6] at 24°C heater is ON
[25.6] at 25°C heater is ON
[25.6] at 26°C heater is ON
[25.6] at 27°C heater is off
[25.6] at 28°C heater is off
[25.6] at 29°C heater is off
[25.6] at 30°C heater is off
[25.6] at 31°C heater is off
[25.6] at 30°C heater is off
[25.6] at 29°C heater is off
[25.6] at 28°C heater is off
[25.6] at 27°C heater is off
[25.6] at 26°C heater is off
[25.6] at 25°C heater is off
[25.6] at 24°C heater is ON
[25.6] at 23°C heater is ON
[25.6] at 22°C heater is ON
[25.6] at 21°C heater is ON
[25.6] at 20°C heater is ON
[25.6] at 19°C heater is ON
[25.6] at 18°C heater is ON
[25.6] at 17°C heater is ON
[25.6] at 16°C heater is ON
[25.6] at 15°C heater is ON
[25.6] at 14°C heater is ON
[25.6] at 13°C heater is ON
[25.6] at 12°C heater is ON
[25.6] at 11°C heater is ON
[25.6] at 10°C heater is ON

Cooler Controler

The following example do not use a real temperature sensor but simulate a temperature cycle from 10 to 31°C then 31°C down to 10°C (see tcycle enumeration).

Hysteresis-cooler.png

Notice:

  • the thermostat.setpoint = 25.6 call to change the setpoint on the fly
  • the call to thermostat.update(temp) to inform the thermostat with the current temperature and get updated with the current thermostat state.
from machine import Pin
from pymate.pymateio import PymateIO
from hyst import CoolerTh
import time

# Output Pin for the Heater
cooler = PymateIO( "Out4", Pin.OUT )
cooler.write( 0 )

# Simulate the temperature cycle 
tcycle = [i for i in range(10,31)] + [i for i in range(31,9,-1)]

# Create a Thermostat set on 22°C with an Hysteresis of 2.5°C (-1.25°C to +1.25°C)
thermostat = CoolerTh( 16, 2.5 ) 

# Follow the temperature cycle an see how the thermostat reacts
print( "--- SetPoint %f -------------------------------" % thermostat.setpoint )
for temp in tcycle:
	state = thermostat.update( temp )
	cooler.write( state )
	print( "[%s] at %i°C cooler is %s" % (thermostat.setpoint, temp, "ON" if state else 'off') )
	time.sleep(1)

# Change the setpoint then 
# Follow the temperature cycle an see how the thermostat reacts
thermostat.setpoint = 21.3
print( "--- SetPoint %f -------------------------------" % thermostat.setpoint )
for temp in tcycle:
	state = thermostat.update( temp )
	cooler.write( state )
	print( "[%s] at %i°C cooler is %s" % (thermostat.setpoint, temp, "ON" if state else 'off') )
	time.sleep(1)

print( "That's all done folks!")

which manipulates the output 4 (wired to cooler fan) and produce the following REPL result (also render as a graph)

Hysteresis-cooler-graph.png

--- SetPoint 16.000000 -------------------------------
[16] at 10°C cooler is off
[16] at 11°C cooler is off
[16] at 12°C cooler is off
[16] at 13°C cooler is off
[16] at 14°C cooler is off
[16] at 15°C cooler is off
[16] at 16°C cooler is off
[16] at 17°C cooler is off
[16] at 18°C cooler is ON
[16] at 19°C cooler is ON
[16] at 20°C cooler is ON
[16] at 21°C cooler is ON
[16] at 22°C cooler is ON
[16] at 23°C cooler is ON
[16] at 24°C cooler is ON
[16] at 25°C cooler is ON
[16] at 26°C cooler is ON
[16] at 27°C cooler is ON
[16] at 28°C cooler is ON
[16] at 29°C cooler is ON
[16] at 30°C cooler is ON
[16] at 31°C cooler is ON
[16] at 30°C cooler is ON
[16] at 29°C cooler is ON
[16] at 28°C cooler is ON
[16] at 27°C cooler is ON
[16] at 26°C cooler is ON
[16] at 25°C cooler is ON
[16] at 24°C cooler is ON
[16] at 23°C cooler is ON
[16] at 22°C cooler is ON
[16] at 21°C cooler is ON
[16] at 20°C cooler is ON
[16] at 19°C cooler is ON
[16] at 18°C cooler is ON
[16] at 17°C cooler is ON
[16] at 16°C cooler is ON
[16] at 15°C cooler is ON
[16] at 14°C cooler is off
[16] at 13°C cooler is off
[16] at 12°C cooler is off
[16] at 11°C cooler is off
[16] at 10°C cooler is off
--- SetPoint 21.300000 -------------------------------
[21.3] at 10°C cooler is off
[21.3] at 11°C cooler is off
[21.3] at 12°C cooler is off
[21.3] at 13°C cooler is off
[21.3] at 14°C cooler is off
[21.3] at 15°C cooler is off
[21.3] at 16°C cooler is off
[21.3] at 17°C cooler is off
[21.3] at 18°C cooler is off
[21.3] at 19°C cooler is off
[21.3] at 20°C cooler is off
[21.3] at 21°C cooler is off
[21.3] at 22°C cooler is off
[21.3] at 23°C cooler is ON
[21.3] at 24°C cooler is ON
[21.3] at 25°C cooler is ON
[21.3] at 26°C cooler is ON
[21.3] at 27°C cooler is ON
[21.3] at 28°C cooler is ON
[21.3] at 29°C cooler is ON
[21.3] at 30°C cooler is ON
[21.3] at 31°C cooler is ON
[21.3] at 30°C cooler is ON
[21.3] at 29°C cooler is ON
[21.3] at 28°C cooler is ON
[21.3] at 27°C cooler is ON
[21.3] at 26°C cooler is ON
[21.3] at 25°C cooler is ON
[21.3] at 24°C cooler is ON
[21.3] at 23°C cooler is ON
[21.3] at 22°C cooler is ON
[21.3] at 21°C cooler is ON
[21.3] at 20°C cooler is off
[21.3] at 19°C cooler is off
[21.3] at 18°C cooler is off
[21.3] at 17°C cooler is off
[21.3] at 16°C cooler is off
[21.3] at 15°C cooler is off
[21.3] at 14°C cooler is off
[21.3] at 13°C cooler is off
[21.3] at 12°C cooler is off
[21.3] at 11°C cooler is off
[21.3] at 10°C cooler is off
That's all done folks!


PymateIO all right reserved © 2026 - Written by MCHobby for PymateIO