'I2C I/O expander addresses
Symbol PCA9554A_1 = %01111000 'Lane 1 DIP switch inputs
Symbol PCA9554A_2 = %01111100 'Lane 2 DIP switch inputs
Symbol PCA9554A_3 = %01110110 'Lane 3 DIP switch inputs
Symbol PCA9554A_4 = %01110010 'Lane 4 DIP switch inputs
Symbol PCA9554A_5 = %01111110 '10x2 rotary DIP switch inputs (2x8421)
Symbol PCA9554A_6 = %01110000 'Traffic lights
'ALCU Picaxe-20X2 I2C addresses
Symbol ALCULane_1 = %01100010 'Lane 1 ALCU
Symbol ALCULane_2 = %01100100 'Lane 2 ALCU
Symbol ALCULane_3 = %01100110 'Lane 3 ALCU
Symbol ALCULane_4 = %01101000 'Lane 4 ALCU
'I2C I/O expander masks
Symbol TLState1 = %00011000 'R1_3 ON G2_4 ON Y OFF
Symbol TLState2 = %00001000 'R1_3 ON G2_4 OFF Y OFF
Symbol TLState3 = %00000101 'R2_4 ON G1_3 ON Y OFF
Symbol TLState4 = %00000001 'R2_4 ON G1_3 OFF Y OFF
Symbol TLState5 = %00000010 'R2_4 OFF G1_3 OFF Y ON
Symbol TLStateOFF = %00000000 'R2_4 OFF G1_3 OFF Y OFF
Symbol AllInputs = %11111111 'All port I/O pins set as inputs or All inputs inverted
Symbol AllOutputs = %00000000 'All port I/O set as outputs
'Command bytes for PCA9554A
Symbol InputReg = 0
Symbol OutputReg = 1
Symbol PolarInvReg = 2
Symbol ConfigReg = 3
'Interrupt pins
Symbol I2CInt = pinB.2 'I2C Interrupt, Active Low
Symbol IRInt1 = pinB.1 'Infrared transmission interrupt, Lane 1
Symbol INT1 = B.1 'Same pin as output for initialization
Symbol IRInt2 = pinD.4 'Infrared transmission interrupt, Lane 2
Symbol INT2 = D.4 'Same pin as output for initialization
Symbol IRInt3 = pinD.2 'Infrared transmission interrupt, Lane 3
Symbol INT3 = D.2 'Same pin as output for initialization
Symbol IRInt4 = pinD.3 'Infrared transmission interrupt, Lane 4
Symbol INT4 = D.3 'Same pin as output for initialization
'Remote access pins
Symbol SerRXPin = pinC.7
Symbol SerRX = C.7
Symbol SerTXPin = pinC.6
Symbol SerTX = C.6
'Automatically set up correct ALCU I2C addresses depending on the Lane unit is connected to
pause 500 'wait some extra time for ALCUs to initialise
serout INT1, SerNRate, ("ICCU", ChipAddrMSB, ChipAddrLSB, ALCULane_1) 'send address string to Lane 1
serout INT2, SerNRate, ("ICCU", ChipAddrMSB, ChipAddrLSB, ALCULane_2) 'send address string to Lane 2
serout INT3, SerNRate, ("ICCU", ChipAddrMSB, ChipAddrLSB, ALCULane_3) 'send address string to Lane 3
serout INT4, SerNRate, ("ICCU", ChipAddrMSB, ChipAddrLSB, ALCULane_4) 'send address string to Lane 4
'Intialise I/O expanders
hi2csetup i2cmaster, PCA9554A_1, I2CSpeed, i2cbyte 'Announce there will be I2C
hi2cout ConfigReg,(AllInputs) 'Configure all Lane1 DIP swithc inputs as inputs
hi2cout [PCA9554A_2],ConfigReg,(AllInputs) 'Configure all Lane2 DIP swithc inputs as inputs
hi2cout [PCA9554A_3],ConfigReg,(AllInputs) 'Configure all Lane3 DIP swithc inputs as inputs
hi2cout [PCA9554A_4],ConfigReg,(AllInputs) 'Configure all Lane4 DIP swithc inputs as inputs
hi2cout [PCA9554A_5],ConfigReg,(AllInputs) 'Configure Custom Address selector switches as inputs
hi2cout PolarInvReg, (AllInputs) 'Invert all inputs to read correct 1248 BCD switch values
hi2cout [PCA9554A_6],ConfigReg,(AllOutputs) 'Configure Traffic Lights as outputs
Main:
gosub ReadSetup
#rem when I2C does not seem to work
sertxd ("Lane1State is: ",#Lane1State,"; ")
sertxd ("Lane2State is: ",#Lane2State,"; ")
sertxd ("Lane3State is: ",#Lane3State,"; ")
sertxd ("Lane4State is: ",#Lane4State,"; ")
sertxd ("Custom Address 1 is: ",#CustomAddress1,"; ")
sertxd ("Custom Address 2 is: ",#CustomAddress2,"; ")
sertxd ("CAValue is: ", #CAValue,". ")
#endrem
gosub ErrorCheck
do
gosub TrafficLight
loop
goto Main
ReadSetup:
'read dip switch status through I2C I/O expanders
hi2csetup i2cmaster, PCA9554A_5, I2CSpeed, i2cbyte 'read custom addresses first to free bit variables
hi2cin InputReg, (CAValue)
gosub DecodeBCD 'decode bit variables from CAValue into CustomAddress1 and CustomAddress2
hi2cin [PCA9554A_1],InputReg,(Lane1State)
hi2cin [PCA9554A_2],InputReg,(Lane2State)
hi2cin [PCA9554A_3],InputReg,(Lane3State)
hi2cin [PCA9554A_4],InputReg,(Lane4State)
'read if Traffic Lights Module is present and with what setting (jumper)
readadc 6, helper3
select case helper3
case 0 to 64 : ModeFlag = 2 'TLM not present or jumper not set
case 65 to 128 : ModeFlag = 1 'TLM present, set to yellow only mode (yellow jumper, high value resistor)
case 129 to 196 'TLM present, for future use
case 197 to 256 : ModeFlag = 0 'TLM present, trafic lights in normal mode (green jumper, no resistor)
end select
return
ErrorCheck:
'check which lanes are connected at all
hi2csetup i2cmaster, ALCULane_1, I2CSpeed, i2cbyte 'set up I2C
hi2cout 0, (1) 'assign the connected chip as Lane_1 for I2C test
hi2cout [ALCULane_2], 0, (2) 'assign the connected chip as Lane_2 for I2C test
hi2cout [ALCULane_3], 0, (3) 'assign the connected chip as Lane_3 for I2C test
hi2cout [ALCULane_4], 0, (4) 'assign the connected chip as Lane_4 for I2C test
hi2cin [ALCULane_1], 0, (helper3) 'read back if that was stored ...
if helper3 = 1 then '... if yes, set Lane1 as available/connected and increase couter
Lane1AvailableFlag = 1
inc ErrCounter
endif
hi2cin [ALCULane_2], 0, (helper3)
if helper3 = 2 then
Lane2AvailableFlag = 1
inc ErrCounter
endif
hi2cin [ALCULane_3], 0, (helper3)
if helper3 = 3 then
Lane3AvailableFlag = 1
inc ErrCounter
endif
hi2cin [ALCULane_4], 0, (helper3)
if helper3 = 4 then
Lane4AvailableFlag = 1
inc ErrCounter
endif
if ErrCounter < 2 then 'signal error if less than 2 lanes are connected
high ErrLED
for Counter = 183 to 232
read Counter, helper3
next Counter
endif
'check if no routes are available for some type of vehicle or in layout OFF mode
for BitNumber = 0 to 7
ErrCounter = 0 'reset the counter
if Lane1State bit BitNumber set then : inc ErrCounter : endif
if Lane2State bit BitNumber set then : inc ErrCounter : endif
if Lane3State bit BitNumber set then : inc ErrCounter : endif
if Lane3State bit BitNumber set then : inc ErrCounter : endif
if ErrCounter < 1 then exit
next BitNumber
if ErrCounter < 1 then 'signal error if less than 1 lane is open for any vehicle type or in layout OFF mode...
high ErrLED '...this could be increased to 2, if it is certain, that no vehicle of a restricted...
for Counter = 233 to 252 '...type would enter FROM a lane, restricted for exit from the crossing
read Counter, helper3
next Counter
endif
'check if main road configuration is correct - only two of the available lanes selected at any time
ErrCounter = 0 'reset the counter
if MAIN1 = 0 and Lane1AvailableFlag = 1 then : inc ErrCounter : endif
if MAIN2 = 0 and Lane2AvailableFlag = 1 then : inc ErrCounter : endif
if MAIN3 = 0 and Lane3AvailableFlag = 1 then : inc ErrCounter : endif
if MAIN4 = 0 and Lane4AvailableFlag = 1 then : inc ErrCounter : endif
select case ErrCounter 'demands main road to be selected - could omit to >2 only to allow not using the feature
case 0
MainRoadConfig = 0 'set to no configuration/error code
case 2
if MAIN1 = 0 and MAIN3 = 0 then : MainRoadConfig = 1 : endif 'check if lane1 and lane3 selected
if MAIN2 = 0 and MAIN4 = 0 then : MainRoadConfig = 2 : endif 'check if lane2 and lane4 selected
if MAIN1 = 0 and MAIN2 = 0 then : MainRoadConfig = 3 : endif 'check if lane1 and lane2 selected
if MAIN2 = 0 and MAIN3 = 0 then : MainRoadConfig = 4 : endif 'check if lane2 and lane3 selected
if MAIN3 = 0 and MAIN4 = 0 then : MainRoadConfig = 5 : endif 'check if lane3 and lane4 selected
if MAIN4 = 0 and MAIN1 = 0 then : MainRoadConfig = 6 : endif 'check if lane4 and lane1 selected
else
MainRoadConfig = 0 'set to no configuration/error code
high ErrLED 'indicate error
for Counter = 233 to 252 'read and display error text over serial
read Counter, helper3
next Counter
endselect
return