PLC Code help to control fan for a shower

tparvais

Member
Hello

I would like my WC board PLC to control my house fan. I have a humidity detector in the aspiration air conduct.

I can control my fan wihh 3 speeds by sending a small pulse (0.3s) on TTL1, TTL2, TTL3, TTL4 : low / medium & high + 4th position = max_speed for 10min.

I would like to accelerate higher speed my fan automatically when humidity >80% and decrease to normal speed when humidity <70%

I tried the following code, but this is not good because it will send continuously pulse command VMC_3 every xx ms. I can't do this. I need to send pulse control to fan only when this is needed.

Code:
START   
TSTGT H1 80 
CALLSUB VMC_3  
TSTLE H1 70 
CALLSUB VMC_1 
END   
VMC_1:
SET OP1 1 
DELAY 5
SETO OP1 0
RET   
VMC_3:
SET OP3 1
DELAY 5
SET OP3 0
RET

Any idea ?

Thank you

Thomas

PS: why should i use pulse command ? Because my fan is radio controlled with a small emitter with 4 push buttons (=pulse). I hack these push buttons on the emitter to control them via TTL output of my WC board.
 
TSTGT H1 80
CALLSUB VMC_3
should only be called when H1 > 80

Could you please add a line before TSTGT H1 80 a debug statement like
SET VAR1 H1
to see from web browser what H1 is reading?
 
I tried the following code, but this is not good because it will send continuously pulse command VMC_3 every xx ms. I can't do this. I need to send pulse control to fan only when this is needed.
Any idea ?


Why do people get so hung up on subroutines? They don't really add anything to the logical flow of a program, they don't save code space unless they are actually called from multiple places, and I'm sure they add an unnecessary overhead to the processor every time it has to push stuff on the stack.

Code:
START
TSTGT H1 80 OP3 # turn op3 on if H1>80, else turn off
DELAY 200			 # Short pause. around 0.2 seconds
SET OP3 0	 # turn output off if it was on

TSTGT H1 70 OP1 # turn on op1 if H1>70, else turn off
DELAY 200			 # short pause.
SET OP1 0			 # turn output1 off if it was on.

DELAY 1000			 # must have some delay otherwise the pulses will merge into levels
END

But given your application, even the above code isn't really what you want - just showing you it can be far shorter if you think ahead.

I don't get quite what all the button options are - is op1 "off", op2 "low", op3 "med", op4 "high"?
If so... off the top of the head I'd do something more like this:

Code:
START
	 VAR1=99	 # first time, ALWAYS send a pulse to set appropriate state on startup.

LOOP:
    TSTGT H1 80	 # If over 80%
    SET VAR2 4

    TSTLE H1 80	 # If under 80%
    SET VAR2 3	 # medium if not really humid

    TSTLE H1 60	 # if under 60%
    SET VAR2 2	 # low speed if nearly dry

    TSTLE H1 40	 # if less than 40%
    SET VAR2 1	 # speed off.

    TSTEQ VAR1 VAR2 # Same speed setting as before?
    GOTO LOOP			 # Yes, so ignore

    TSTEQ VAR2 1 OP1 # Set output 1 if var2=1 
    NOP
    TSTEQ VAR2 2 OP2 # Set low speed if var2=2
    NOP
    TSTEQ VAR2 3 OP3 # Set medium speed if var2=3
    NOP
    TSTEQ VAR2 4 OP4 # set high speed
	 NOP

	 DELAY 250			 # Wait quarter second
	 SET OP1 0			 # and turn off all outputs
	 SET OP2 0
	 SET OP3 0
	 SET OP4 0
	 SET VAR1 VAR2	  # remember current speed
	 DELAY 5000			 # don't change fan speed more than every 5 seconds.
	 GOTO LOOP
END

Note - this is not good code, it doesn't include any hysteresis. If your humidity is hovering around say 80/81% you will constantly be switching speeds.
 
Hello

I really appreciate your help and support. I'm learning a lot from your proposal as newbie.

Here is some more info on my "fan".
  • The fan runs all the time (to refresh permantely house air) , impossible to switch off (except via central switch in basement)
  • The Fan has 3 working speed: low / medium / high
  • There is a radio command to control fan speed with 4 push buttons (pulse) for
    • 3 buttons for low / medium /high (set permanentely the fan speed until next change via push on the button)
    • 1 push button to setup fan at high speed for 10 min (internal fan timer)
  • the last action on the radio command has always the highest priority: if for example I Press button 4 (high speed 10min), then after button 1, finally the fan will run low speed.
I think we have to update the code you propose.


The WC board does not know the current speed status as there is two radio command in the house:
  • one in the bathroom for human action,
  • and one connected to WC Board in the basement near the fan to be able to control the fan speed via the webcontrol board ("hack the radio command").
to include hystersis or at least avoid going full speed if humidty increases for a second over the threshold , can we use the following test:

TSTGT H1[30] 80

if humidity > 80% longer than 30seconds, then...

Thank you

Thomas
 
The fan runs all the time (to refresh permantely house air) , impossible to switch off (except via central switch in basement)
    • 1 push button to setup fan at high speed for 10 min (internal fan timer)
I think we have to update the code you propose.

OK. The logic above is still sound. You just need to adjust the thresholds. I commented the code so you can see what's what. Should be easy to adapt to your requirement.

The WC board does not know the current speed status as there is two radio command in the house:
  • one in the bathroom for human action,
  • and one connected to WC Board in the basement near the fan to be able to control the fan speed via the webcontrol board ("hack the radio command").

If it does not know what the human override has been, obviously it can not do anything. Lets say it is very humid and the WC has turned on high fan speed, but a human walks in and turns the fan to slowest speed, the WC will not know and will "think" it is still on high speed. The WC will still send a "medium" speed command if the humidity drops below 80%.

The "fix" to this would be to make the WC send updates every (say) 10 minutes regardless of a change-of-state. That is easy enough to achieve too. Do you want code for that?


to include hystersis or at least avoid going full speed if humidty increases for a second over the threshold , can we use the following test:

TSTGT H1[30] 80

if humidity > 80% longer than 30seconds, then...

First, the [30] in your example is only 30 MILLISECONDS. You would need [30000] for 30 seconds.
Secondly, I have about 50 WC boards - but I keep discovering bugs in their code. None of mine actually work properly with the timer code as you show, they are intermittent. CAI have confirmed code prior to I think 3.12 or 3.13 do not do this test properly. So I tend to use other ways to achieve these tests.
 
I think if you really want human override, you could add few button switches connected to the TTL input, add PLC logic for those TTL input to override the PLC automated logic.
 
The "fix" to this would be to make the WC send updates every (say) 10 minutes regardless of a change-of-state. That is easy enough to achieve too. Do you want code for that?
...

First, the [30] in your example is only 30 MILLISECONDS. You would need [30000] for 30 seconds.
Secondly, I have about 50 WC boards - but I keep discovering bugs in their code. None of mine actually work properly with the timer code as you show, they are intermittent. CAI have confirmed code prior to I think 3.12 or 3.13 do not do this test properly. So I tend to use other ways to achieve these tests.

yes please, if you have both codes for these Two ideas

Thank you very much I appreciate a lot

Thomas
 
yes please, if you have both codes for these Two ideas

Are you able to graft code together? Here's my ideas:

Code:
loop:
    set ram1 CS		    # Get second
    tsteq ram1 cs		  # changed yet?
    goto loop			    # no.
								    # we execute code from here on once every second
   incr ram2				  # bump our update counter
   tstge ram2 600		 # 600 seconds = 10 minutes
   set var1 99			   # force an update of the outputs

.... (previous code goes here)

then at the end change the code to read:

   set var1 var2		    # remember current state
   set ram2 0			    # reset update timer
   goto loop


As for adding hysteresis, I've had probably one glass of scotch too much tonight. Let me answer in the morning when my head is clearer :)
 
Well, I thought about it and for your application, the complexity of implementing actual hysteresis on the humidity input seems excessive.
Even if the internal timer logic worked properly, I'm not sure your suggested

TSTGT H1[30] 80

would work, since H1 will be varying and may NEVER meet the delay criteria.

So, I offer you two pieces of code. Neither has been tested. Comments obviously don't get put into the WC board, they're just there so you can understand my logic. The first one is basically the original code, with a hack to tweek the humidity up or down 2% in the threshold detector code. It's not elegant, but it should work.

Code:
START
	 VAR1=99				 # first time, ALWAYS send a pulse to set appropriate state on startup.

LOOP:
	 SET RAM1 CS			 # Get second
	 TSTEQ RAM1 CS		 # changed yet?
	 GOTO LOOP			 # no.
							 # we execute code from here on once every second
	 INCR RAM2			 # bump our update counter
	 TSTGE RAM2 600		 # 600 seconds = 10 minutes
	 SET VAR1 99			 # force an update of the outputs

	 SET VAR2 4			 # Assume worst case
	 set ram3 H1			 # get current humidity
	 tsteq var1 var2		 # if fan speed is currently this
	 add ram3 2 ram3		 # add 2% for low end hysteresis
	 tstlt var1 var2		 # or, if speed is currently lower
	 sub ram3 2 ram3		 # reduce 2% for upper-end hysteresis
	 TSTLE RAM3 80		 # If under 80%
	 DECR VAR2			 # set next lower speed

	 set ram3 H1			 # get current humidity
	 tsteq var1 var2		 # if fan speed is currently this
	 add ram3 2 ram3		 # add 2% for low end hysteresis

	 tstlt var1 var2		 # or, if speed is currently lower
	 sub ram3 2 ram3		 # reduce 2% for upper-end hysteresis
	 TSTLE RAM3 60		 # if under 60%
	 DECR VAR2			 # set next lower speed

	 set ram3 H1			 # get current humidity
	 tsteq var1 var2		 # if fan speed is currently this
	 add ram3 2 ram3		 # add 2% for low end hysteresis
	 tstlt var1 var2		 # or, if speed is currently lower
	 sub ram3 2 ram3		 # reduce 2% for upper-end hysteresis
	 TSTLE RAM3 40		 # if less than 40%
	 DECR VAR2			 # set next lower speed

	 TSTEQ VAR1 VAR2		 # Same speed setting as before?
	 GOTO LOOP			 # Yes, so ignore


	 TSTEQ VAR2 1 OP1	 # Set output 1 if var2=1
	 NOP
	 TSTEQ VAR2 2 OP2	 # Set low speed if var2=2
	 NOP
	 TSTEQ VAR2 3 OP3	 # Set medium speed if var2=3
	 NOP
	 TSTEQ VAR2 4 OP4	 # set high speed

	 NOP

	 DELAY 250			 # Wait quarter second
	 SET OP1 0			 # and turn off all outputs
	 SET OP2 0
	 SET OP3 0
	 SET OP4 0
	 SET VAR1 VAR2		 # remember current speed

	 SET RAM2 0			 # reset update timer
	 GOTO LOOP
END


The second solution which I think is easier to understand and should work perfectly well uses debounce type logic. It will require the system to consistently decide on the same fan speed for 30 seconds (easily changed) before it will actually change the fan speed. It will still send periodic "refresher" signals every 10 minutes regardless. The code is more elegant, shorter and easier to read and understand.

Code:
START
LOOP:
	 SET RAM1 CS			 # Get second
	 TSTEQ RAM1 CS		 # changed yet?
	 GOTO LOOP			 # no.
							 # we execute code from here on once every second
	 INCR RAM2			 # bump our update counter
	 TSTGE RAM2 600		 # 600 seconds = 10 minutes
	 GOTO SEND			 # Send speed update regardless

	 SET VAR2 4			 # Assume worst case
	 TSTLE H1 80			 # If under 80%
	 DECR VAR2			 # set next lower speed

	 TSTLE H1 60			 # if under 60%
	 DECR VAR2			 # set next lower speed

	 TSTLE H1 40			 # if less than 40%
	 DECR VAR2			 # set next lower speed

	 TSTNE VAR2 VAR3		 # check speed change for jitter
	 SET RAM3 0			 # reset timer
	 SET VAR3 VAR2		 # save for next time
	 INCR RAM3			 # bump timer
	 TSTLT RAM3 30		 # has to maintain required speed for 30 sec before changing
	 GOTO LOOP
	 TSTEQ VAR1 VAR2		 # Has the speed actually changed?
	 GOTO LOOP
	 SET VAR1 VAR2		 # set new speed
SEND:
	 TSTEQ VAR1 1 OP1	 # Set output 1 if var2=1
	 NOP
	 TSTEQ VAR1 2 OP2	 # Set low speed if var2=2
	 NOP
	 TSTEQ VAR1 3 OP3	 # Set medium speed if var2=3
	 NOP
	 TSTEQ VAR1 4 OP4	 # set high speed
	 NOP

	 DELAY 250			 # Wait quarter second
	 SET OP1 0			 # and turn off all outputs
	 SET OP2 0
	 SET OP3 0
	 SET OP4 0

	 SET RAM2 0			 # reset update timer
	 GOTO LOOP
END
 
TSTGT H1[30] 80
does not work. Non-blocking delay only work on TTL input and output, and VAR. No other I/O has non-blocking delay.
 
TSTGT H1[30] 80
does not work.

So my doubting it would work was a good call.
Do you see anything fundamentally wrong with either of my two proposed alternatives? Is either a "better" solution to this problem? (I only ask, as you have probably a better knowledge of what you're doing 'under the hood' to see if one or the other is a superior solution)
 
Hello
I come back on this.
I implement the following, with some parameters changes:  
-analysis every 120seconds
-Maintain same speed for 30s
-Only 3 speed: max-medium-low  
 
So when I start a shower, the fan will go max speed 2 minutes after begining of the shower ? Can I reduce this timer to 15s (to ventilate faster after shower start) and increase duration of same speed from 30 to 120s ?  
 
Thank you   Thomas
 

START
LOOP:
SET RAM1 CS # Get second and write to RAM1
TSTEQ RAM1 CS # changed yet?
GOTO LOOP # no.
# we execute code from here on once every second
INC RAM2 # bump our update counter
TSTGE RAM2 120 # 120 seconds = 2 minutes
GOTO SEND # Send speed update regardless

SET VAR2 3 # Assume worst case - High speed
TSTLE H1 90 # If under 90%
DEC VAR2 # set mid speed

TSTLE H1 70 # if under 70%
DEC VAR2 # set lower speed

TSTNE VAR2 VAR3 # check speed change for jitter
SET RAM3 0 # reset timer
SET VAR3 VAR2 # save for next time
INC RAM3 # bump timer
TSTLT RAM3 30 # has to maintain required speed for 30 sec before changing
GOTO LOOP
TSTEQ VAR1 VAR2 # Has the speed actually changed?
GOTO LOOP
SET VAR1 VAR2 # set new speed
SEND:
TSTEQ VAR1 1 OP1 # Set output 1 if var2=1
NOP
TSTEQ VAR1 2 OP2 # Set low speed if var2=2
NOP
TSTEQ VAR1 3 OP3 # Set medium speed if var2=3
NOP

DELAY 400 # Wait quarter second
SET OP1 0 # and turn off all outputs
SET OP2 0
SET OP3 0

SET RAM2 0 # reset update timer
GOTO LOOP
END


 
 
Thomas Parvais said:
Hello
I come back on this.
I implement the following, with some parameters changes:  
-analysis every 120seconds
-Maintain same speed for 30s
-Only 3 speed: max-medium-low  
 
So when I start a shower, the fan will go max speed 2 minutes after begining of the shower ? Can I reduce this timer to 15s (to ventilate faster after shower start) and increase duration of same speed from 30 to 120s ?  
 
Thank you   Thomas
 

START
LOOP:
SET RAM1 CS # Get second and write to RAM1
TSTEQ RAM1 CS # changed yet?
GOTO LOOP # no.
# we execute code from here on once every second
INC RAM2 # bump our update counter
>>>>> TSTGE RAM2 120 # 120 seconds = 2 minutes
GOTO SEND # Send speed update regardless
 
I've highlighted the bit that determines when the update is done. Changing this from 120 seconds to 15 seconds will probably achieve what you want.
 
Hi Thomas,
 
could you please disclose the remote control, if it is based on 12V?
many thanks in advance
 
PS: regarding hysteresis I think the humidity sensor is widely to slow to allow real time control, as others have proposed just add kind of fuzzy control- if humidity is high then put the fan at medium speed, if the humidity is increasing further for some time, then increase the speed further...
 
Back
Top