Stationeers

Stationeers

View Stats:
Etsijä Jan 9, 2019 @ 12:48am
Greenhouse thermostat IC - setting up the hysteresis optimally
I'm writing IC code for my greenhouse thermostat. I've got the first version of it working correctly, it reads in the temperature and has parameters Min and Max. Heaters kick in when Temp < Min, coolers kick in when Temp > Max. Simple but not optimal (?).

Now I'm thinking of adding some hysteresis to the heaters and coolers with a Schmitt Trigger, but am wondering what would be an optimal solution for that. My current thinking is this (the numbers are an example only; they are in Celcius):

Min = 20
Max = 35
Delta = (Max-Min)/3 = 5
MidLow = Min+Delta = 25
MidHigh = Max-Delta = 30

My system would try to keep the greenhouse temperature between the sweet spot [MidLow, MidHigh] ie. between 25 and 30 degrees, which is right in the middle of the Min-Max range, and both my heaters and coolers would have a hysteresis range of 5 degrees around this sweet spot.

Pseudocode for this (HeaterHysteresis and CoolerHysteresis are booleans which indicate the temperature being on the respective hysteresis area):

HeaterHysteresis = FALSE;
CoolerHysteresis = FALSE;

# Heaters
IF HeaterHysteresis == FALSE
IF Temp > MidLow
Heaters OFF;
HeaterHysteresis = TRUE;
END IF
ELSE
IF Temp < Min
Heaters ON;
HeaterHysteresis = FALSE;
END IF
END IF

# Coolers
IF CoolerHysteresis == FALSE
IF Temp > Max
Coolers ON;
CoolerHysteresis = TRUE;
END IF
ELSE
IF Temp < MidHigh
Coolers OFF;
CoolerHysteresis = FALSE;
END IF
END IF

Questions:
1) Am I overcomplicating things here?
2) Does my pseudocode look correct?

And yes, I am aware of the implementation of the Schmitt Trigger with logic chips (Reader, Compare, Select, Writer), but really want to do this programmatically, since I want to learn to code in MIPS.
< >
Showing 1-12 of 12 comments
Etsijä Jan 9, 2019 @ 6:26am 
Got it working as expected and as in the above pseudocode. For anyone interested, here is the IC code for the thermostat (with separate, non-overlapping hysteresis regions for the heater and cooler, as explained above):

https://stationeering.com/tools/ic#eyJwcm9ncmFtIjoiIyBEZXZpY2VzXG5hbGlhcyBkU2Vuc29yIGQwXG5hbGlhcyBkTWluIGQxXG5hbGlhcyBkTWF4IGQyXG5hbGlhcyBkSGVhdGVyIGQzXG5hbGlhcyBkQ29vbGVyIGQ0XG5cbiMgUmVnaXN0ZXJzXG5hbGlhcyByVGVtcCByMFxuYWxpYXMgck1pbiByMVxuYWxpYXMgck1heCByMlxuYWxpYXMgckhlYXRlciByM1xuYWxpYXMgckNvb2xlciByNFxuYWxpYXMgckRlbHRhIHI1XG5hbGlhcyByTWlkTG93IHI2XG5hbGlhcyByTWlkSGlnaCByN1xuYWxpYXMgckhlYXRlckh5c3QgcjhcbmFsaWFzIHJDb29sZXJIeXN0IHI5XG5cbiMgTWFpbiBsb29wXG5zdGFydDpcblxuIyBMb2FkIGRldmljZXMgaW50byByZWdpc3RlcnNcbmwgclRlbXAgZFNlbnNvciBUZW1wZXJhdHVyZVxuc3ViIHJUZW1wIHJUZW1wIDI3My4xNVxubCByTWluIGRNaW4gU2V0dGluZ1xubCByTWF4IGRNYXggU2V0dGluZ1xuXG4jIERlYnVnXG5zIGRiIFNldHRpbmcgclRlbXBcblxuIyBDYWxjdWxhdGUgbmVlZGVkIHBhcmFtZXRlcnNcbnN1YiByRGVsdGEgck1heCByTWluXG5kaXYgckRlbHRhIHJEZWx0YSAzXG5hZGQgck1pZExvdyByTWluIHJEZWx0YVxuc3ViIHJNaWRIaWdoIHJNYXggckRlbHRhXG5cbiMgTWFpbiBsb29wOiBnbyB0aHJvdWdoIGFsbCA0IHBvc3NpYmxlIGFjdGlvbnNcbnBoYXNlXzE6XG5iZXF6IHJIZWF0ZXJIeXN0IGhlYXRfc3RvcFxucGhhc2VfMjpcbmogaGVhdFxucGhhc2VfMzpcbmJlcXogckNvb2xlckh5c3QgY29vbFxucGhhc2VfNDpcbmogY29vbF9zdG9wXG5cbmhlYXRfc3RvcDpcbiMgSGVhdGVycyBvZmYsIHN0YXJ0IGhlYXRlciBoeXN0ZXJlc2lzXG5iZ3QgclRlbXAgck1pZExvdyBoZWF0ZXJzX29mZlxuaiBwaGFzZV8yXG5cbmhlYXQ6XG4jIEhlYXRlcnMgb24sIG5vIGh5c3RlcmVzaXNcbmJsdCByVGVtcCByTWluIGhlYXRlcnNfb25cbmogcGhhc2VfM1xuXG5jb29sOlxuIyBDb29sZXJzIG9uLCBzdGFydCBjb29sZXIgaHlzdGVyZXNpc1xuYmd0IHJUZW1wIHJNYXggY29vbGVyc19vblxuaiBwaGFzZV80XG5cbmNvb2xfc3RvcDpcbiMgQ29vbGVycyBvZmYsIG5vIGh5c3RlcmVzaXNcbmJsdCByVGVtcCByTWlkSGlnaCBjb29sZXJzX29mZlxuaiByZXN1bWVcblxuaGVhdGVyc19vZmY6XG5zIGRIZWF0ZXIgT24gMFxubW92ZSBySGVhdGVySHlzdCAxXG5qIHBoYXNlXzJcblxuaGVhdGVyc19vbjpcbnMgZEhlYXRlciBPbiAxXG5tb3ZlIHJIZWF0ZXJIeXN0IDBcbmogcGhhc2VfM1xuXG5jb29sZXJzX29uOlxucyBkQ29vbGVyIE9uIDFcbm1vdmUgckNvb2xlckh5c3QgMVxuaiBwaGFzZV80XG5cbmNvb2xlcnNfb2ZmOlxucyBkQ29vbGVyIE9uIDBcbm1vdmUgckNvb2xlckh5c3QgMFxuaiByZXN1bWVcblxucmVzdW1lOlxueWllbGRcbmogc3RhcnQiLCJyZWdpc3RlcnMiOnsiaW8iOlt7IlRlbXBlcmF0dXJlIjozMDB9LHsiU2V0dGluZyI6MjB9LHsiU2V0dGluZyI6MzV9LHsiT24iOjB9LHsiT24iOjB9LHt9LHsiU2V0dGluZyI6MjYuODUwMDAwMDAwMDAwMDIzfV0sImlvQ29ubmVjdGVkIjpbdHJ1ZSx0cnVlLHRydWUsdHJ1ZSx0cnVlLHRydWUsdHJ1ZV0sImludGVybmFsIjpbMjYuODUwMDAwMDAwMDAwMDIzLDIwLDM1LDAsMCw1LDI1LDMwLDEsMCwwLDAsMCwwLDAsMCwwLDBdLCJpb1Nsb3QiOlt7fSx7fSx7fSx7fSx7fSx7fSx7fV0sImlvUmVhZ2VudCI6W3t9LHt9LHt9LHt9LHt9LHt9LHt9XX0sInJ1bkFmdGVyUmVnaXN0ZXJDaGFuZ2UiOmZhbHNlLCJydW5XaXRoRXJyb3JzIjpmYWxzZX0=
Maireen Jan 9, 2019 @ 6:59pm 
label d0 sensor
label d1 LoMem
label d2 HiMem
label d3 cooler
label d4 heater

start:
l r0 d0 Temperature
sub r0 r0 273.15
l r1 d1 Setting
l r2 d2 Setting
sub r3 r2 r1
div r3 r3 3
add r4 r1 r3
sub r5 r2 r3

slt r6 r0 r7
select r7 r6 r4 r1
s d4 On r6

sgt r8 r0 r9
select r9 r8 r5 r2
s d3 On r8

yield
j start
Etsijä Jan 10, 2019 @ 2:39pm 
@Maireen: today I ended up with exactly the same solution as yours. Very elegant indeed! (I prefer to use aliases also for the registers, so that I can read my code at a later stage :) )
Etsijä Jan 10, 2019 @ 2:59pm 
I noticed as well that you actually do not initialize r7 and r9 anywhere before the start loop. First I thought this would lead to false operation, if the IC starts operating outside the min-max range. Then I figured that this only happens during the first tick - after that, select takes care to set the heating and cooling thresholds properly!
Adam De Beers Jan 10, 2019 @ 6:39pm 
Originally posted by Maireen:
label d0 sensor
label d1 LoMem
label d2 HiMem
label d3 cooler
label d4 heater

start:
l r0 d0 Temperature
sub r0 r0 273.15
l r1 d1 Setting
l r2 d2 Setting
sub r3 r2 r1
div r3 r3 3
add r4 r1 r3
sub r5 r2 r3

slt r6 r0 r7
select r7 r6 r4 r1
s d4 On r6

sgt r8 r0 r9
select r9 r8 r5 r2
s d3 On r8

yield
j start


nice code overthere!
Etsijä Jan 11, 2019 @ 1:46am 
Actually, there is a bug in your code, Maireen. Let me run an example for you:

1. Initial state:
Temp=31, Min=25, Max=35
=> MidLow=28.33, MidHigh=31.67
Temperature lies on the "sweet spot", heaters off, coolers off
Heater threshold = 25 (Min), cooler threshold = 35 (Max)

2. I change Min=30, Max=40
=> MidLow=33.33, MidHigh=36.67

Now, since Temp=31 which is less than the newly calculated MidLow, heaters should go on, trying to heat up till (the new) MidLow.

BUT: Heater threshold stays at Min due to the select not working in this case, and the heaters stay off.

The reason select is not working in my case is because slt r6 r0 r7 evaluates as FALSE, since r0=31 but the heater threshold still stays in 25.
Last edited by Etsijä; Jan 11, 2019 @ 1:48am
Etsijä Jan 11, 2019 @ 2:14am 
I thought a picture tells more than a thousand words. Hope this can be seen (not sure of OneDrive).

https://1drv.ms/u/s!AiqBTMIm6FgM90C7jzINMj4rEI_3
Soondead Jan 11, 2019 @ 4:28am 
Has anyone looked into implementing a proper PID controller for this sort of thing?
Etsijä Jan 11, 2019 @ 6:39am 
@Maireen: come to think of it, I probably was wrong. The "bug" I described above probably isn't a bug, it is more like a feature of the Schmitt Trigger. When the thresholds Min, Max are changed, the system (ie. temperature in my case) needs to visit outside the Min-Max range in order for the IC to reset itself properly to the new thresholds. This doesn't effect the ST's capability of keeping the temperature on Min-Max range.
Maireen Jan 11, 2019 @ 8:27am 
You can even use switch dials for d1 and d2 if you like to fiddle around the temperature min/max ranges instead of memory chips.
Adam De Beers Jan 11, 2019 @ 9:03am 
Originally posted by Maireen:
You can even use switch dials for d1 and d2 if you like to fiddle around the temperature min/max ranges instead of memory chips.

Using dials
Etsijä Jan 11, 2019 @ 11:24am 
Originally posted by Soondead:
Has anyone looked into implementing a proper PID controller for this sort of thing?

This is a very interesting topic, and I'm currently trying to memorize my university studies from almost 30 years ago...I have a specific problem where would ve very interested in trying to solve it with PID controller:

Currently, my greenhouse athmospheric and pressure control is as follows:
- N2, O2 and CO2 pipes in, volume pumps in each (set to 5 litres), no regulators
- one waste pipe out with a volume pump set currently to 100 litres
- no regulation whatsoever on input: the IC just keeps turning on/off each of the volume pumps to achieve the correct corresponding gas ratio
- pressure regulation is on the output, done also with an IC; it is a Schmitt Trigger. When pressure is over the limit, output volume pump is opened, and since its volume 100l is far more than input's volume 5+5+5=15l, it regulates pressure quite efficiently

Overall, the system I'm using works great: my athmosphere is neatly controlled, so is the pressure. It does take a lot of fine tuning though, since I have to manually try to balance the input and output volume pumps.

A volume pump is also pretty power-hungry: it is 8W/liter/tick, so power consumption ranges from 8 to 800W.

I think this is the place where a proper PID controller would be interesting to try out. It could for example try to manage the system, not only by turning the input and output pumps on and off, but by also tuning the volumes of the pumps so as to minimize power consumption.
Last edited by Etsijä; Jan 11, 2019 @ 11:26am
< >
Showing 1-12 of 12 comments
Per page: 1530 50

Date Posted: Jan 9, 2019 @ 12:48am
Posts: 12