' ========================================================================= ' ' File...... traffic_light.bs2 ' Purpose... ' Author.... Jon McPhalen ' -- Copyright (c) 2020 Jon McPhalen ' -- MIT license unless otherwise noted ' E-mail.... ' Started... ' Updated... 27 JAN 2020 ' ' {$STAMP BS2} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' -----[ Revision History ]------------------------------------------------ ' -----[ I/O Definitions ]------------------------------------------------- EW_YEL PIN 5 ' East/West lamps EW_GRN PIN 4 EW_RED PIN 3 NS_YEL PIN 2 ' North/South lamps NS_GRN PIN 1 NS_RED PIN 0 ' -----[ Constants ]------------------------------------------------------- RED CON 0 ' color state of light GREEN CON 1 YELLOW CON 2 R_TIME CON 44 ' red light timing G_TIME CON 30 ' green light timing Y_TIME CON 10 ' yellow light timing IS_ON CON 1 ' for active-high in/out IS_OFF CON 0 YES CON 1 NO CON 0 ' -----[ Variables ]------------------------------------------------------- nsState VAR Nib ' state controllers ewState VAR Nib nsTimer VAR Byte ' timing control ewTimer VAR Byte ' -----[ Initialization ]-------------------------------------------------- Reset: OUTH = %00000000 : OUTL = %00000000 ' clear all DIRH = %00000000 : DIRL = %00111111 ' P5..P0 are outputs ' nsTimer is preset to 2 to maintain correct overlap ' of lighting sequence with ew lamps nsState = RED ' starting states nsTimer = 2 ' preset timer GOSUB Show_NS ' update lamps ewState = GREEN ewTimer = 0 GOSUB Show_EW ' -----[ Program Code ]---------------------------------------------------- Main: PAUSE 1000 ' set timing units Update_NS: nsTimer = nsTimer + 1 ' inc North/South timer SELECT nsState CASE RED IF (nsTimer = R_TIME) THEN ' red done? nsState = GREEN ' advance to green nsTimer = 0 ' start green timing GOSUB Show_NS ' update lights ENDIF CASE GREEN IF (nsTimer = G_TIME) THEN nsState = YELLOW nsTimer = 0 GOSUB Show_NS ENDIF CASE YELLOW IF (nsTimer = Y_TIME) THEN nsState = RED nsTimer = 0 GOSUB Show_NS ENDIF CASE ELSE ' call emergency handler and restart ENDSELECT Update_EW: ewTimer = ewTimer + 1 SELECT ewState CASE RED IF (ewTimer = R_TIME) THEN ewState = GREEN ewTimer = 0 GOSUB Show_EW ENDIF CASE GREEN IF (ewTimer = G_TIME) THEN ewState = YELLOW ewTimer = 0 GOSUB Show_EW ENDIF CASE YELLOW IF (ewTimer = Y_TIME) THEN ewState = RED ewTimer = 0 GOSUB Show_EW ENDIF CASE ELSE ' call emergency handler and restart ENDSELECT GOTO Main ' -----[ Subroutines ]----------------------------------------------------- Show_NS: ' update North/South lights SELECT nsState CASE RED NS_RED = IS_ON NS_GRN = IS_OFF NS_YEL = IS_OFF CASE GREEN NS_RED = IS_OFF NS_GRN = IS_ON NS_YEL = IS_OFF CASE YELLOW NS_RED = IS_OFF NS_GRN = IS_OFF NS_YEL = IS_ON CASE ELSE ' call emergency handler and restart ENDSELECT RETURN ' ------------------------------------------------------------------------- Show_EW: ' update East/West lights SELECT ewState CASE RED EW_RED = IS_ON EW_GRN = IS_OFF EW_YEL = IS_OFF CASE GREEN EW_RED = IS_OFF EW_GRN = IS_ON EW_YEL = IS_OFF CASE YELLOW EW_RED = IS_OFF EW_GRN = IS_OFF EW_YEL = IS_ON CASE ELSE ' call emergency handler and restart ENDSELECT RETURN ' -----[ User Data ]-------------------------------------------------------