This post follows earlier discussion in another category/topic: see Understanding IF statements)
I am struggling to grasp how to avoid line-number branching from IF-THEN statements as recommended by Maurice.
Rather than looking at just 3 or 4 lines of code covering a single decision, I would find it more instructive to consider a slightly larger section which involves a bigger series of inter-related decisions and actions.
This example concerns whether to start a central heating system in a block of apartments. Each apartment has an individual thermostat controlled zone valve. At mid-range outdoor temperatures the zone valves may be closed meaning no heat is required.
Plain language functional description:
A) Pre-conditions: Start heating only if all the following conditions are satisfied (collectively PRECONDS):
- hot water priority flag not set by earlier program (HWPRIORT = off)
- heating mode is selected (IN3 switch closed)
- the heating circulator has no fault (IN4 switch closed)
B) Operation also based on Outdoor Air Temperature (IN1_OAT):
- IN1_OAT > 16degC - Heat not required (HEATREQ flag off)
- IN1_OAT < 8degC - Heat is required (HEATREQ flag on)
- IN1_OAT between 8 to 16 deg - Heat required if circulating flow is above a
defined value eg 5). Otherwise no heat required, circulator off
C) Minimum low test using circulator pump as follows: (SUBROUTINE)
- start PUMP
- allow 10sec for flow to stabilise
- measure circulating flow IN2_ FLOW.
- If flow IN2 < 5, TESTFAIL - HEATREQ flag off, stop PUMP
- If flow IN2 > 5, Test passed - HEATREQ flag on (leave pump running)
D) If test failed and while preconditions remain satisfied, recheck every 15 minutes if OAT is still within 8-16deg range and, if so, repeat flow test (ie repeat C) above)
E) Commence heating: HEATREQ flag acted on by subsequent program
My original code effort used a number of “GOTOs” ie “skip to End” and also a jump-back to repeat the flow test which could potentially create an endless loop. I have reviewed this for many hours and have developed a revised code below.
Maybe I just dont have sufficient ability to restructure this the right/preferred way - I would greatly appreciate further review and assistance.
To allow for repeating the flow test, I put it into a subroutine - called once initially and repeated as required. I dont know if variables used by both main program and subroutine must be global or if local will work.
10 REM ** HEATING DECISION
15 REM ** HWPRIORT AND HEATREQ ARE GLOBAL VARIABLES
20 IF HWPRIORT AND IN3 AND IN4 THEN PRECONDS = 1 ELSE PRECONDS = 0
30 IF PRECONDS AND IN1_OAT > 16 THEN HEATREQ = 0
40 IF PRECONDS AND IN1_OAT <8 THEN HEATREQ = 1
50 IF PRECONDS AND IN1_OAT < 16 AND IN1_OAT > 8 THEN GOSUB 100
60 IF+ TESTFAIL THEN HEATREQ = 0 ELSE HEATREQ = 1
70 IF TIME-ON (TESTFAIL) > 0:15 THEN GOSUB 100
80 IF+ HEATREQ THEN START PUMP
90 REM ** HEATREQ FLAG USED BY NEXT PROGRAM
95 END
100 REM ** SUBROUTINE FOR FLOW TEST
105 TIMEFLAG = 0
110 TESTFAIL = 0 (initialise flags)
120 START PUMP
130 IF+ TIME-ON (PUMP) > 0:0:10 THEN TIMEFLAG
135 IF+ TIMEFLAG THEN MEASFLOW = IN2_FLOW
140 IF+ TIMEFLAG AND MEASFLOW < 5 THEN TESTFAIL = 1
145 IF+ TESTFAIL THEN STOP PUMP (if test passes, leave pump running)
150 RETURN