PDA

View Full Version : large program oddity



lsteensl
- 13th April 2007, 17:26
I'm using PBP 2.47 and microcode studio 2.3.0.0, to write code for a 16f877a.

I have a large polling loop that includes 18 of these structures:

if T_zone > 0 and current_zone = 1 then
high P_Zone1
else
low P_Zone1
endif

if T_zone > 0 and current_zone = 2 then
high P_Zone2
else
Low P_Zone2
endif

...
if T_zone > 0 and current_zone = 17 then
high P_Zone17
else
low P_Zone17
endif

if T_zone > 0 and current_zone = 18 then
high P_Zone18
else
low P_Zone18
endif

What I find is when I set the current_zone to 17, the output will toggle. All other outputs in this loop don't. Also, when swap the location of the zone17 and zone18 code, zone 18 toggles and zone 17 doesn't.

I have written a few lines of code to go through and test the fact that all the I/Os are working so I haven't blown a driver, or have a weak one.

I have to believe that it has something to do with the fact that the program is on the large-ish size (2370 words). I am not using any branch statements, it's all gotos and gosubs.

I would be happy to include the entire source code if someone thinks they have a good idea as to what would cause it.

thanks

skimask
- 13th April 2007, 18:00
Try this instead:

If T_Zone > 0 Then
Low P_Zone1 : Low P_Zone2.........and so on.....
Select Case current_zone
Case 1
High P_Zone1
Case 2
High P_Zone2
...................................and so on.....
End Select
Endif



And what pin is P_Zone17 on?
For that matter, seeing all the code might not be a bad idea.

lsteensl
- 13th April 2007, 18:13
There is more code than can be added to a window, so I'll have to chop out a few things.



@ DEVICE PIC16f877a, HS_OSC, PWRT_ON, BOD_ON

include "modedefs.bas"

DEFINE OSC 20

' define the I/O pins
I2CDATA VAR PORTC.4
I2CCLK VAR PORTC.3

SerialTX VAR PORTC.6 'pic centric
SerialRX VAR PORTC.7 'pic centric
P_SP_reset VAR PORTE.0 ' site player reset 1 == reset

' P_ indicates pin or port
P_zone1 VAR PORTB.3
P_zone2 VAR PORTB.2
P_zone3 VAR PORTB.1
P_zone4 VAR PORTB.0
P_zone5 VAR PORTD.7
P_zone6 VAR PORTD.6
P_zone7 VAR PORTD.5
P_zone8 VAR PORTD.4
P_zone9 VAR PORTC.5
P_zone10 VAR PORTD.3
P_zone11 VAR PORTD.2
P_zone12 VAR PORTD.1
P_zone13 VAR PORTD.0
P_zone14 VAR PORTC.2
P_zone15 VAR PORTC.1
P_zone16 VAR PORTC.0
P_zone17 VAR PORTA.2
P_zone18 VAR PORTA.3

SP_STATUS con $10
SP_NOP CON $00
SP_READ1byte CON $C0
SP_READ2bytes CON $C1
SP_READ3bytes CON $C2
SP_READ5bytes CON $C4
SP_WRITE1byte CON $80
SP_WRITE2bytes CON $81
SP_WRITE5bytes CON $84

' this is the SP start address for the RTC data
SP_RTCADDR con $7f ' siteplayer address for RTC variables
' these are the binary values from from the web page
SP_DAY var byte ' binary data from the SP
SP_HOURS var byte
SP_MINUTES var byte
SP_SECONDS var byte
SP_AMPM var byte
'these are the BCD and tweaked data to be written to the RTC
RTC_DAY var byte
RTC_HOURS var byte
RTC_MINUTES var byte
RTC_SECONDS var byte
RTC_AMPM var byte 'bit 5 of hour (am/pm) 1==PM

SP_STARTHOUR con $96
SP_STARTMINUTE con $97
SP_STARTAMPM CON $98
SP_WINTER con $A0

' this is the zone 1 start address - 1 'cause
' at read current_zone = 0, so to start the process we increment current_zone
SP_ManualAddr con $83 ' siteplayer address for manual times

' These come from the site players status read
SP_bstatus var byte
manual_run var bit
timed_run var bit

PREVIOUS_MINUTE var byte 'used to decrement the valve times
RTC_STATUS VAR WORD
RTC_STATUS = $003F
RTC_TIMEADDR var word
RTC_TIMEADDR = $0030 ' start of a continuous read ($30 +)

winter VAR bit
T_zone VAR byte
valve_number var byte ' dummy used in for loop during write to EEPROM
valvetime var byte

current_zone var byte
start_hour var byte
start_minute var byte
start_ampm var byte

i2c_ack VAR BIT ' acknowledgement bit
i2c_in var byte ' don't care data from the RTC

BIN2BCD_TEMP var byte
BIN2BCD_VAL var byte
BCD2BIN_TEMP var byte
BCD2BIN_VAL var byte
TEMP1 var byte
TEMP2 var byte
i var byte

t_zone = 0
Current_zone = 0
PREVIOUS_MINUTE = $FF
winter = 0

main:
SEROUT2 SerialTX, 84, [$10]
SERIN2 SerialRX, 84, [SP_bstatus]
if SP_bstatus.7 and SP_bstatus.0 then
Serout2 SerialTX, 84, [SP_READ5bytes, SP_RTCADDR]
SERIN2 SerialRX, 84, [SP_SECONDS, SP_MINUTES, SP_HOuRS, SP_DAY, SP_AMPM]
gosub UPDATE_CURRENT_TIME
endif

if SP_bstatus.7 and SP_bstatus.1 then
SEROUT2 SerialTX, 84, [SP_READ3bytes, SP_STARTHOUR]
SERIN2 SerialRX, 84, [start_hour, start_minute, start_ampm]
write SP_STARTHOUR, start_hour
write SP_STARTMINUTE, start_minute
write SP_STARTAMPM, start_ampm
endif

if SP_bstatus.7 and SP_bstatus.2 then
for valve_number = 1 to 126 ' 1 - 126 memory locations
SEROUT2 SerialTX, 84, [SP_READ1byte, valve_number]
SERIN2 SerialRX, 84, [valvetime]
write valve_number, valvetime
next valve_number
endif

if SP_bstatus.7 and SP_bstatus.3 then
Current_zone = 1
manual_run = 1
gosub MANUALRUN
endif

gosub READ_TIME

SEROUT2 SerialTX, 84, [SP_WRITE5bytes, SP_RTCADDR, SP_SECONDS, SP_MINUTES, SP_HOURS, SP_DAY, SP_AMPM]

if current_zone = 0 then
PREVIOUS_MINUTE = SP_MINUTES
endif

if SP_MINUTES != PREVIOUS_MINUTE and current_zone > 0 THEN
PREVIOUS_MINUTE = SP_MINUTES
T_zone = T_zone - 1
endif

' if we decrement beyond 0 then floor the value
if T_zone = 255 then
T_zone = 0
endif

if SP_HOURS = start_hour and SP_MINUTES = start_minute and current_zone = 0 and winter = 0 and manual_run = 0 then
current_zone = 1
timed_run = 1
gosub GET_CURRENT_VALVE_RUN_TIME
endif

if current_zone > 0 and current_zone < 19 and T_zone = 0 and manual_run = 0 then
current_zone = current_zone + 1 'move to the next zone
gosub GET_CURRENT_VALVE_RUN_TIME
endif

if current_zone > 0 and current_zone < 19 and T_zone = 0 and manual_run = 1 then
current_zone = current_zone + 1 'move to the next zone
gosub MANUALRUN
endif

if current_zone > 18 and T_zone = 0 then
current_zone = 0
manual_run = 0
timed_run = 0
endif

if T_zone > 0 and current_zone = 1 then
high P_Zone1
else
low P_Zone1
endif

if T_zone > 0 and current_zone = 2 then
high P_Zone2
else
Low P_Zone2
endif

if T_zone > 0 and current_zone = 3 then
high P_zone3
else
low P_zone3
endif

if T_zone > 0 and current_zone = 4 then
high P_zone4
else
low P_zone4
endif

if T_zone > 0 and current_zone = 5 then
high P_zone5
else
low P_zone5
endif

if T_zone > 0 and current_zone = 6 then
high P_zone6
else
low P_zone6
endif

if T_zone > 0 and current_zone = 7 then
high P_zone7
else
low P_zone7
endif

if T_zone > 0 and current_zone = 8 then
high P_zone8
else
low P_zone8
endif

if T_zone > 0 and current_zone = 9 then
high P_zone9
else
low P_zone9
endif

if T_zone > 0 and current_zone = 10 then
high P_zone10
else
low P_zone10
endif

if T_zone > 0 and current_zone = 11 then
high P_zone11
else
low P_zone11
endif

if T_zone > 0 and current_zone = 12 then
high P_zone12
else
low P_zone12
endif

if T_zone > 0 and current_zone = 13 then
high P_zone13
else
low P_zone13
endif

if T_zone > 0 and current_zone = 14 then
high P_zone14
else
low P_zone14
endif

if T_zone > 0 and current_zone = 15 then
high P_zone15
else
low P_zone15
endif

if T_zone > 0 and current_zone = 16 then
high P_zone16
else
low P_zone16
endif

if T_zone > 0 and current_zone = 17 then
high P_zone17
else
low P_zone17
endif

if T_zone > 0 and current_zone = 18 then
HIGH P_zone18
else
low P_zone18
endif

pause 1000
goto main

UPDATE_CURRENT_TIME:
BIN2BCD_VAL = SP_SECONDS
gosub BIN_TO_BCD
RTC_SECONDS = BIN2BCD_VAL

BIN2BCD_VAL = SP_MINUTES
gosub BIN_TO_BCD
RTC_MINUTES = BIN2BCD_VAL

BIN2BCD_VAL = SP_HOURS
gosub BIN_TO_BCD
RTC_HOURS = BIN2BCD_VAL
RTC_HOURS.7 = 0 'clear mil bit
RTC_HOURS.5 = SP_AMPM.0 'fixup the AM/PM bit

I2CWRITE I2CDATA, I2CCLK, $DE, RTC_STATUS, [$02] 'set REL
I2CWRITE I2CDATA, I2CCLK, $DE, RTC_STATUS, [$06] 'set WREL & REL
I2CWRITE I2CDATA, I2CCLK, $DE, RTC_TIMEADDR, [RTC_SECONDS, RTC_MINUTES, RTC_HOURS, $00, $00, $00, SP_DAY, $00]
pause 10
I2CWRITE I2CDATA, I2CCLK, $DE, RTC_STATUS, [$00] 'clear WREL & REL
RETURN

MANUALRUN:
SEROUT2 SerialTX, 84, [SP_READ1byte, SP_ManualAddr+current_zone]
SERIN2 SerialRX, 84, [T_zone]
RETURN

GET_CURRENT_VALVE_RUN_TIME:
read (SP_DAY*18)+current_zone, T_zone
RETURN

READ_TIME:
' start
HIGH I2CDATA
HIGH I2CCLK
LOW I2CDATA
LOW I2CCLK
SHIFTOUT I2CDATA,I2CCLK,1,[$DE]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1] 'Receive ACK bit
SHIFTOUT I2CDATA,I2CCLK,1,[$00]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1] 'Receive ACK bit
SHIFTOUT I2CDATA,I2CCLK,1,[$30]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1] 'Receive ACK bit
HIGH I2CDATA
HIGH I2CCLK
LOW I2CDATA
LOW I2CCLK
SHIFTOUT I2CDATA,I2CCLK,1,[$DF]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1]
SHIFTIN I2CDATA,I2CCLK,0,[Sp_SECONDS]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[SP_MINUTES]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[SP_HOURS]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_in]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_in]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_in]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[SP_DAY]
SHIFTOUT I2CDATA,I2CCLK,1,[%1\1]
LOW I2CDATA
HIGH I2CCLK
HIGH I2CDATA
PAUSE 1

BCD2BIN_VAL = SP_SECONDS
gosub BCD_TO_BIN
SP_SECONDS = BCD2BIN_VAL

BCD2BIN_VAL = SP_MINUTES
gosub BCD_TO_BIN
SP_MINUTES = BCD2BIN_VAL

SP_AMPM = SP_HOURS.5
SP_HOURS.5 = 0 ' clear AM/PM bit before we unBCD
BCD2BIN_VAL = SP_HOURS
gosub BCD_TO_BIN
SP_HOURS = BCD2BIN_VAL
return

BIN_TO_BCD:
BIN2BCD_TEMP = ((BIN2BCD_VAL/10)<<4)+(BIN2BCD_VAL//10)
BIN2BCD_VAL = BIN2BCD_TEMP
return

BCD_TO_BIN:
TEMP1 = BCD2BIN_VAL & $F ' Convert the values from BCD to BIN
TEMP2 = BCD2BIN_VAL & $F0 ' Mask off high nibble
TEMP2 = TEMP2 >> 4 ' divide by 16
TEMP2 = TEMP2 * 10 ' X by 10
BCD2BIN_VAL = TEMP1 + TEMP2
return

End

Jerson
- 14th April 2007, 06:05
I suspect it may have to do with incorrect branching due to seletion of the wrong PCLATH value. To check this, you will have to look withing the LST file.

Jerson

skimask
- 14th April 2007, 06:52
Look at the 16F877A datasheet, pages 127, 128, and 135....then look right after DEFINE OSC 20 below...

@ DEVICE PIC16f877a, HS_OSC, PWRT_ON, BOD_ON
include "modedefs.bas"
DEFINE OSC 20
ADCON0=0:ADCON1=6:CMCON=7:I2CDATA VAR PORTC.4:I2CCLK VAR PORTC.3:SerialTX VAR PORTC.6:SerialRX VAR PORTC.7:P_SP_reset VAR PORTE.0:P_zone1 VAR PORTB.3:P_zone2 VAR PORTB.2
P_zone3 VAR PORTB.1:P_zone4 VAR PORTB.0:P_zone5 VAR PORTD.7:P_zone6 VAR PORTD.6:P_zone7 VAR PORTD.5:P_zone8 VAR PORTD.4:P_zone9 VAR PORTC.5:P_zone10 VAR PORTD.3:P_zone11 VAR PORTD.2
P_zone12 VAR PORTD.1:P_zone13 VAR PORTD.0:P_zone14 VAR PORTC.2:P_zone15 VAR PORTC.1:P_zone16 VAR PORTC.0:P_zone17 VAR PORTA.2:P_zone18 VAR PORTA.3:SP_STATUS con $10:SP_NOP CON $00
SP_READ1byte CON $C0:SP_READ2bytes CON $C1:SP_READ3bytes CON $C2:SP_READ5bytes CON $C4:SP_WRITE1byte CON $80:SP_WRITE2bytes CON $81:SP_WRITE5bytes CON $84:SP_RTCADDR con $7f
SP_DAY var byte:SP_HOURS var byte:SP_MINUTES var byte:SP_SECONDS var byte:SP_AMPM var byte:RTC_DAY var byte:RTC_HOURS var byte:RTC_MINUTES var byte:RTC_SECONDS var byte
RTC_AMPM var byte:SP_STARTHOUR con $96:SP_STARTMINUTE con $97:SP_STARTAMPM CON $98:SP_WINTER con $A0:SP_ManualAddr con $83:SP_bstatus var byte:manual_run var bit:timed_run var bit
PREVIOUS_MINUTE var byte:RTC_STATUS VAR WORD:RTC_STATUS = $003F:RTC_TIMEADDR var word:RTC_TIMEADDR = $0030:winter VAR bit:T_zone VAR byte:valve_number var byte:valvetime var byte
current_zone var byte:start_hour var byte:start_minute var byte:start_ampm var byte:i2c_ack VAR BIT:i2c_in var byte:BIN2BCD_TEMP var byte:BIN2BCD_VAL var byte:BCD2BIN_TEMP var byte
BCD2BIN_VAL var byte:TEMP1 var byte:TEMP2 var byte:i var byte:t_zone=0:Current_zone = 0:PREVIOUS_MINUTE = $FF:winter = 0
main:
SEROUT2 SerialTX, 84, [$10]:SERIN2 SerialRX, 84, [SP_bstatus]
if SP_bstatus.7 and SP_bstatus.0 then
Serout2 SerialTX, 84, [SP_READ5bytes, SP_RTCADDR]:SERIN2 SerialRX, 84, [SP_SECONDS, SP_MINUTES, SP_HOuRS, SP_DAY, SP_AMPM]:gosub UPDATE_CURRENT_TIME
endif
if SP_bstatus.7 and SP_bstatus.1 then
SEROUT2 SerialTX,84,[SP_READ3bytes,SP_STARTHOUR]:SERIN2 SerialRX,84,[start_hour,start_minute,start_ampm]:write SP_STARTHOUR,start_hour:write SP_STARTMINUTE,start_minute
write SP_STARTAMPM, start_ampm
endif
if SP_bstatus.7 and SP_bstatus.2 then
for valve_number = 1 to 126:SEROUT2 SerialTX, 84, [SP_READ1byte, valve_number]:SERIN2 SerialRX, 84, [valvetime]:write valve_number, valvetime:next valve_number
endif
if SP_bstatus.7 and SP_bstatus.3 then
Current_zone = 1:manual_run = 1:gosub MANUALRUN
endif
gosub READ_TIME:SEROUT2 SerialTX, 84, [SP_WRITE5bytes, SP_RTCADDR, SP_SECONDS, SP_MINUTES, SP_HOURS, SP_DAY, SP_AMPM]
if current_zone = 0 then PREVIOUS_MINUTE = SP_MINUTES
if SP_MINUTES != PREVIOUS_MINUTE and current_zone > 0 THEN
PREVIOUS_MINUTE = SP_MINUTES:T_zone = T_zone - 1
endif
if T_zone = 255 then T_zone = 0
if SP_HOURS = start_hour and SP_MINUTES = start_minute and current_zone = 0 and winter = 0 and manual_run = 0 then
current_zone = 1:timed_run = 1:gosub GET_CURRENT_VALVE_RUN_TIME
endif
if current_zone > 0 and current_zone < 19 and T_zone = 0 and manual_run = 0 then
current_zone = current_zone + 1:gosub GET_CURRENT_VALVE_RUN_TIME
endif
if current_zone > 0 and current_zone < 19 and T_zone = 0 and manual_run = 1 then
current_zone = current_zone + 1:gosub MANUALRUN
endif
if current_zone > 18 and T_zone = 0 then
current_zone = 0:manual_run = 0:timed_run = 0
endif
if T_zone > 0 then
low p_zone1:low p_zone2:low p_zone3:low p_zone4:low p_zone5:low p_zone6:low p_zone7:low p_zone8:low p_zone9:low p_zone10:low p_zone11:low p_zone12:low p_zone13:low p_zone14:low p_zone15
low p_zone16:low p_zone17:low p_zone18
select case current_zone
case 1
high P_Zone1
case 2
high P_Zone2
case 3
high P_zone3
case 4
high P_zone4
case 5
high P_zone5
case 6
high P_zone6
case 7
high P_zone7
case 8
high P_zone8
case 9
high P_zone9
case 10
high P_zone10
case 11
high P_zone11
case 12
high P_zone12
case 13
high P_zone13
case 14
high P_zone14
case 15
high P_zone15
case 16
high P_zone16
case 17
high P_zone17
case 18
HIGH P_zone18
end select
endif
pause 1000:goto main
UPDATE_CURRENT_TIME:
BIN2BCD_VAL = SP_SECONDS:gosub BIN_TO_BCD:RTC_SECONDS = BIN2BCD_VAL:BIN2BCD_VAL = SP_MINUTES:gosub BIN_TO_BCD:RTC_MINUTES = BIN2BCD_VAL:BIN2BCD_VAL = SP_HOURS:gosub BIN_TO_BCD
RTC_HOURS = BIN2BCD_VAL:RTC_HOURS.7 = 0:RTC_HOURS.5 = SP_AMPM.0:I2CWRITE I2CDATA, I2CCLK, $DE, RTC_STATUS, [$02]:I2CWRITE I2CDATA, I2CCLK, $DE, RTC_STATUS, [$06]
I2CWRITE I2CDATA, I2CCLK, $DE, RTC_TIMEADDR, [RTC_SECONDS, RTC_MINUTES, RTC_HOURS, $00, $00, $00, SP_DAY, $00]:pause 10:I2CWRITE I2CDATA, I2CCLK, $DE, RTC_STATUS, [$00]:RETURN
MANUALRUN:
SEROUT2 SerialTX, 84, [SP_READ1byte, SP_ManualAddr+current_zone]:SERIN2 SerialRX, 84, [T_zone]:RETURN
GET_CURRENT_VALVE_RUN_TIME:
read (SP_DAY*18)+current_zone, T_zone:RETURN
READ_TIME:
HIGH I2CDATA:HIGH I2CCLK:LOW I2CDATA:LOW I2CCLK:SHIFTOUT I2CDATA,I2CCLK,1,[$DE]:SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1]:SHIFTOUT I2CDATA,I2CCLK,1,[$00]:SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1]
SHIFTOUT I2CDATA,I2CCLK,1,[$30]:SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1]:HIGH I2CDATA:HIGH I2CCLK:LOW I2CDATA:LOW I2CCLK:SHIFTOUT I2CDATA,I2CCLK,1,[$DF]:SHIFTIN I2CDATA,I2CCLK,0,[i2c_ack\1]
SHIFTIN I2CDATA,I2CCLK,0,[Sp_SECONDS]:SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]:SHIFTIN I2CDATA,I2CCLK,0,[SP_MINUTES]:SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]:SHIFTIN I2CDATA,I2CCLK,0,[SP_HOURS]
SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]:SHIFTIN I2CDATA,I2CCLK,0,[i2c_in]:SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]:SHIFTIN I2CDATA,I2CCLK,0,[i2c_in]:SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]
SHIFTIN I2CDATA,I2CCLK,0,[i2c_in]:SHIFTOUT I2CDATA,I2CCLK,1,[%0\1]:SHIFTIN I2CDATA,I2CCLK,0,[SP_DAY]:SHIFTOUT I2CDATA,I2CCLK,1,[%1\1]:LOW I2CDATA:HIGH I2CCLK:HIGH I2CDATA:PAUSE 1
BCD2BIN_VAL = SP_SECONDS:gosub BCD_TO_BIN:SP_SECONDS = BCD2BIN_VAL:BCD2BIN_VAL = SP_MINUTES:gosub BCD_TO_BIN:SP_MINUTES = BCD2BIN_VAL:SP_AMPM = SP_HOURS.5:SP_HOURS.5 = 0
BCD2BIN_VAL = SP_HOURS:gosub BCD_TO_BIN:SP_HOURS = BCD2BIN_VAL:return
BIN_TO_BCD:
BIN2BCD_TEMP = ((BIN2BCD_VAL/10)<<4)+(BIN2BCD_VAL//10):BIN2BCD_VAL = BIN2BCD_TEMP:return
BCD_TO_BIN:
TEMP1=BCD2BIN_VAL & $F:TEMP2=BCD2BIN_VAL & $F0:TEMP2 = TEMP2 >> 4:TEMP2 = TEMP2 * 10:BCD2BIN_VAL = TEMP1 + TEMP2:return
End

lsteensl
- 15th April 2007, 19:16
When I changed from that huge if...then tree, to the select case (with a little modification however) the code was small enough to fit in the 2k code size, and he problem went away.

this is what I had to do to make the ports come on, and go off, otherwise all other things are the same:



if T_zone > 0 then
select case current_zone
case 1
HIGH P_zone1
case 2
HIGH P_zone2
case 3
HIGH P_zone3
case 4
HIGH P_zone4
case 5
HIGH P_zone5
case 6
HIGH P_zone6
case 7
HIGH P_zone7
case 8
HIGH P_zone8
case 9
HIGH P_zone9
case 10
HIGH P_zone10
case 11
HIGH P_zone11
case 12
HIGH P_zone12
case 13
HIGH P_zone13
case 14
HIGH P_zone14
case 15
HIGH P_zone15
case 16
HIGH P_zone16
case 17
HIGH P_zone17
case 18
HIGH P_zone18
end select
endif

if T_Zone = 0 then
LOW P_zone1 : LOW P_zone2 : LOW P_zone3 : LOW P_zone4 : LOW P_zone5 : _
LOW P_zone6 : LOW P_zone7 : LOW P_zone8 : LOW P_zone9 : LOW P_zone10 : _
LOW P_zone11 : LOW P_zone12 : LOW P_zone13 : LOW P_zone14 : LOW P_zone15 : _
LOW P_zone16 : LOW P_zone17 : LOW P_zone18
endif

paul borgmeier
- 16th April 2007, 06:28
Want to shorten your code a bunch more? Skip the "HIGH" and "LOW" commands and set the port pins directly (See last sentence and example in both the "HIGH" and "LOW" sections of manual).