Différences entre versions de « Mydin-UseCase-Basic-Thermostat »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
 
(6 versions intermédiaires par le même utilisateur non affichées)
Ligne 14 : Ligne 14 :
 
[[Fichier:MyDin-3modules-usage.jpg]]
 
[[Fichier:MyDin-3modules-usage.jpg]]
  
#  * DS18B20 is connected to 1Wire port
+
* LED 1 reflect the Rel 1 state (so heating state).
#  * Rel 1 control the Heater
+
* LED 2 is lit while a FORCED forced is currently active
* LED 1 reflect the Rel 1 state.
+
* LED 3 will blink once to acknowledge T° increase.
#
+
* LED 4 will blink once to acknowledge T° decrease.
* Button 1 invert (force) the state of the relay.  
+
* BUTTON 1 reverse (force) the current state of the relay.<br />When the relay is ON then it switch it off.<br />When the relay is OFF then is switch it on.
* Forced state is canceled with the thermostat state reach the forced state
+
* BUTTON 2 cancel the forced state.
# * Forced state is canceled when the button 2 is pressed.
+
* BUTTON 3 will decrease the setpoint T° of 1 degree.  
# * LED2 is lit while a forced state do applies
+
* BUTTON 4 will increase the setpoint T° of 1 degree.
# * button 3 will decrease the setpoint . Led 3 will blick once to acknowledge.
+
 
# * button 4 will increase the setpoint T°. Led 4 will blink once to acknowledge.
+
Current temperature, setpoint temperature and relay state is displayed in the REPL session.
 +
 
 +
=== Hysteresis ===
 +
 
 +
A thermostat allows to define the target temperature called the setpoint (eg: 25°C) and use an hysteresis range (EG: 2.5°C) to avoids continuous state change around the target temperature.
 +
 
 +
[[Fichier:heater-hysteresis.jpg]]
 +
 
 +
With the hysteresis, the heater starts heating from 25-2.5 = '''22.5°C''' and will stop heating when the temperature raised above 25+2.5 = '''27.5°C'''. The temperature will slowly decrease and the heater will start again when temperature falls under 22.5°C.
 +
 
 +
=== Forced Mode ===
 +
 
 +
From the previous example here upper
 +
 
 +
Lets say the heater already reached 27.5°C and the heather stopped.
 +
 
 +
The temperature is now 25°C and you are already frozen... unfortunately the heater will not restart before the temperature falls under 22.5°C.
 +
 
 +
Pressing the '''Forced''' button will restart the heating process and the forced state will automatically disabling when the temperature is reached.
 +
 
 +
{{underline|Remarks:}}<br />Forced state can also be used during a normal heating process to stop it. In such case, the forced state will get disabled when the lower temperature is reached.
 +
 
 +
== The code ==
 +
 
 +
Here is the code of [https://github.com/mchobby/micropython-mydin/blob/main/examples/backplanes/TwoRelay3Mod/async-thermostat2.py thermostat2.py] available in the repository.
 +
 
 +
<syntaxhighlight lang="python" line>
 +
from mydin import configure
 +
from mydin.pico import Pico3Mod
 +
from mydin.backplane.relays import TwoRelay3Mod
 +
from hyst import HeaterTh
 +
import time, sys, asyncio
 +
 
 +
# Which Controler + Backplane to use
 +
din = configure( Pico3Mod, TwoRelay3Mod )
 +
thermostat = HeaterTh( 25, 2 ) # Thermostat
 +
forced = None # Forced state (High=True,Low=False,None=None)
 +
last_print = 1
 +
 
 +
# === OneWire bus & DS18B20 ===================
 +
# When running DinControler asynchronously, a task
 +
# is created to capture the DS18B20 temperature!
 +
# The AsyncIO task is scheduled every  60 seconds
 +
# (see pico.py; DS18B20_UPDATE_TIME)
 +
 
 +
async def loop( din ):
 +
  """ called again and again (like Arduino) """
 +
  global thermostat, forced, last_print
 +
  if din.temp_ds18b20==None:
 +
    await asyncio.sleep( 2 )
 +
    return
 +
 
 +
  # User Force state change ?
 +
  if din.was_pressed( 0 ):
 +
    forced = not(din.rel1.value())
 +
 
 +
 
 +
  # Ask to reset forced state ?
 +
  if din.was_pressed( 1 ):
 +
    forced = None
 +
 
 +
  # Increate / decrease setpoint
 +
  if din.was_pressed( 2 ):
 +
    thermostat.setpoint -= 1
 +
    print( 'setpoint @ %i °C' % thermostat.setpoint )
 +
    din.led2.on()
 +
    await asyncio.sleep_ms( 300 )
 +
    din.led2.off()
 +
  if din.was_pressed( 3 ):
 +
    thermostat.setpoint += 1
 +
    print( 'setpoint @ %i °C' % thermostat.setpoint )
 +
    din.led3.on()
 +
    await asyncio.sleep_ms( 300 )
 +
    din.led3.off()
 +
 
 +
  # IF forced THEN apply forced state
 +
  if forced != None:
 +
    heat = forced
 +
    # Should we auto-reset the forced state
 +
    if (forced == thermostat.update( din.temp_ds18b20) ):
 +
      forced=None # Reset forced state
 +
 
 +
  # IF not forced THEN follow thermostat
 +
  if forced==None:
 +
    heat = thermostat.update( din.temp_ds18b20 )
 +
 
 +
  din.led1.value( forced!=None )
 +
  din.led0.value( heat )
 +
  din.rel1.value( heat )
 +
 
 +
  # print status once every 2 seconds
 +
  if time.ticks_diff( time.ticks_ms(), last_print )>2000:
 +
    print( "[%s] %s °C - %s - %s" % (thermostat.setpoint, din.temp_ds18b20, "Heat" if heat else "...", "(forced)" if forced!=None else "") )
 +
    last_print = time.ticks_ms()
 +
 
 +
  await asyncio.sleep_ms( 100 )
 +
 
 +
 
 +
din.setup( setup=None, loop=loop )
 +
din.run()
 +
</syntaxhighlight>
 +
 
 +
== Improve it ==
 +
 
 +
In house, thermostat are associated with a scheduler used to define one or more day-time hours range for heating (the remaining being the night-time).
 +
 
 +
Some advanced thermostat can defines a day temperature and night temperature.
 +
 
 +
In such case, the forced mode could be used to switch between day-time and night-time (with the corresponding temperature).

Version actuelle datée du 30 avril 2025 à 21:25

Basic Thermostat

This project implements a basic temperature control system from a 3 modules MyDin made of:

 

The temperature sensor takes the room temperature and the heater is controled by the relay 1.

 

  • LED 1 reflect the Rel 1 state (so heating state).
  • LED 2 is lit while a FORCED forced is currently active
  • LED 3 will blink once to acknowledge T° increase.
  • LED 4 will blink once to acknowledge T° decrease.
  • BUTTON 1 reverse (force) the current state of the relay.
    When the relay is ON then it switch it off.
    When the relay is OFF then is switch it on.
  • BUTTON 2 cancel the forced state.
  • BUTTON 3 will decrease the setpoint T° of 1 degree.
  • BUTTON 4 will increase the setpoint T° of 1 degree.

Current temperature, setpoint temperature and relay state is displayed in the REPL session.

Hysteresis

A thermostat allows to define the target temperature called the setpoint (eg: 25°C) and use an hysteresis range (EG: 2.5°C) to avoids continuous state change around the target temperature.

 

With the hysteresis, the heater starts heating from 25-2.5 = 22.5°C and will stop heating when the temperature raised above 25+2.5 = 27.5°C. The temperature will slowly decrease and the heater will start again when temperature falls under 22.5°C.

Forced Mode

From the previous example here upper

Lets say the heater already reached 27.5°C and the heather stopped.

The temperature is now 25°C and you are already frozen... unfortunately the heater will not restart before the temperature falls under 22.5°C.

Pressing the Forced button will restart the heating process and the forced state will automatically disabling when the temperature is reached.

Remarks:
Forced state can also be used during a normal heating process to stop it. In such case, the forced state will get disabled when the lower temperature is reached.

The code

Here is the code of thermostat2.py available in the repository.

 1 from mydin import configure
 2 from mydin.pico import Pico3Mod
 3 from mydin.backplane.relays import TwoRelay3Mod 
 4 from hyst import HeaterTh
 5 import time, sys, asyncio
 6 
 7 # Which Controler + Backplane to use
 8 din = configure( Pico3Mod, TwoRelay3Mod )
 9 thermostat = HeaterTh( 25, 2 ) # Thermostat
10 forced = None # Forced state (High=True,Low=False,None=None)
11 last_print = 1
12 
13 # === OneWire bus & DS18B20 ===================
14 # When running DinControler asynchronously, a task 
15 # is created to capture the DS18B20 temperature! 
16 # The AsyncIO task is scheduled every  60 seconds 
17 # (see pico.py; DS18B20_UPDATE_TIME)
18 
19 async def loop( din ):
20   """ called again and again (like Arduino) """
21   global thermostat, forced, last_print
22   if din.temp_ds18b20==None:
23     await asyncio.sleep( 2 )
24     return
25 
26   # User Force state change ?
27   if din.was_pressed( 0 ):
28     forced = not(din.rel1.value())
29 
30 
31   # Ask to reset forced state ?
32   if din.was_pressed( 1 ):
33     forced = None
34 
35   # Increate / decrease setpoint
36   if din.was_pressed( 2 ):
37     thermostat.setpoint -= 1
38     print( 'setpoint @ %i °C' % thermostat.setpoint )
39     din.led2.on()
40     await asyncio.sleep_ms( 300 )
41     din.led2.off()
42   if din.was_pressed( 3 ):
43     thermostat.setpoint += 1
44     print( 'setpoint @ %i °C' % thermostat.setpoint )
45     din.led3.on()
46     await asyncio.sleep_ms( 300 )
47     din.led3.off()
48 
49   # IF forced THEN apply forced state
50   if forced != None:
51     heat = forced
52     # Should we auto-reset the forced state
53     if (forced == thermostat.update( din.temp_ds18b20) ):
54       forced=None # Reset forced state
55 
56   # IF not forced THEN follow thermostat
57   if forced==None: 
58     heat = thermostat.update( din.temp_ds18b20 )
59   
60   din.led1.value( forced!=None )
61   din.led0.value( heat )
62   din.rel1.value( heat )
63 
64   # print status once every 2 seconds
65   if time.ticks_diff( time.ticks_ms(), last_print )>2000:
66     print( "[%s] %s °C - %s - %s" % (thermostat.setpoint, din.temp_ds18b20, "Heat" if heat else "...",  "(forced)" if forced!=None else "") )
67     last_print = time.ticks_ms()
68 
69   await asyncio.sleep_ms( 100 )
70 
71 
72 din.setup( setup=None, loop=loop )
73 din.run()

Improve it

In house, thermostat are associated with a scheduler used to define one or more day-time hours range for heating (the remaining being the night-time).

Some advanced thermostat can defines a day temperature and night temperature.

In such case, the forced mode could be used to switch between day-time and night-time (with the corresponding temperature).