Push buttons being read while other actions are being performed
userjyjy
Posts: 30
in BASIC Stamp
I'm stuck on a project. I have the streetlights acting as I need them to but I'm having a difficult time trying to get the pushbutton to be read while the lights are performing.
Here are the guidelines
only one pedestrian light will go green at a time and only when the corresponding pushbutton is pushed.When the button is pushed, traffic should stopin that direction only after the completion of that traffic cycle.
b.The corresponding pedestrian light will turn green and will stay on for 30 seconds. During the last 10 seconds, the green light will be flashing to indicate that time is almost up for crossing the street.
c.Each push button can be only pushed once.After that, the pedestrian light will return to red and normal operation will resume for two complete traffic cycles in that specific direction before the same button can cause the traffic light to change.You can ignore any push made during the completion of the two cycles.
d.If traffic is stopped in a particular direction during a red light and the pedestrian light is pushed, the corresponding pedestrian light should turn green immediately.
e.The left turn traffic should yield to pedestrians crossing the N-S street so there is no need to wait for the left turn signal to turn red.
Here is my code. I tried to simplify it by using subroutines for the change from north south to east west back to the all red.
"
counter VAR WORD
counter = 0
DO
GOSUB alllightsred
GOSUB eastandwest
counter = counter + 1
DEBUG ? counter
GOSUB northandsouth
counter = counter + 1
DEBUG ? counter
IF counter = 2 THEN
DO
IF IN3 =1 AND IN0 =1 THEN
DEBUG ? IN3
PAUSE 30000
ENDIF
LOOP WHILE counter >= 2
ENDIF
LOOP
'All Lights Red'
alllightsred:
HIGH 15
HIGH 14
HIGH 13
HIGH 12
HIGH 11
PAUSE 2000
RETURN
'East Turning Light goes Green and East Light goes green'
Eastandwest:
LOW 13
LOW 12
HIGH 9
HIGH 10
PAUSE 6500
'Turning light goes yellow
LOW 10
HIGH 5
PAUSE 3500
'Turning light goes Red and West goes Green
LOW 15
LOW 5
HIGH 7
HIGH 12
PAUSE 3500
'West and East light goes Yellow'
LOW 9
LOW 10
LOW 7
HIGH 2
HIGH 4
PAUSE 3500
'West and East go red
LOW 4
LOW 5
LOW 2
HIGH 15
HIGH 13
PAUSE 5000
RETURN
northandsouth:
'North and South go green'
HIGH 8
HIGH 6
LOW 11
LOW 14
PAUSE 6500
'North and South go Yellow'
LOW 8
LOW 6
HIGH 3
HIGH 1
PAUSE 3000
'North and south go red'
LOW 3
LOW 1
HIGH 11
HIGH 14
PAUSE 3000
RETURN
"
Here are the guidelines
only one pedestrian light will go green at a time and only when the corresponding pushbutton is pushed.When the button is pushed, traffic should stopin that direction only after the completion of that traffic cycle.
b.The corresponding pedestrian light will turn green and will stay on for 30 seconds. During the last 10 seconds, the green light will be flashing to indicate that time is almost up for crossing the street.
c.Each push button can be only pushed once.After that, the pedestrian light will return to red and normal operation will resume for two complete traffic cycles in that specific direction before the same button can cause the traffic light to change.You can ignore any push made during the completion of the two cycles.
d.If traffic is stopped in a particular direction during a red light and the pedestrian light is pushed, the corresponding pedestrian light should turn green immediately.
e.The left turn traffic should yield to pedestrians crossing the N-S street so there is no need to wait for the left turn signal to turn red.
Here is my code. I tried to simplify it by using subroutines for the change from north south to east west back to the all red.
"
counter VAR WORD
counter = 0
DO
GOSUB alllightsred
GOSUB eastandwest
counter = counter + 1
DEBUG ? counter
GOSUB northandsouth
counter = counter + 1
DEBUG ? counter
IF counter = 2 THEN
DO
IF IN3 =1 AND IN0 =1 THEN
DEBUG ? IN3
PAUSE 30000
ENDIF
LOOP WHILE counter >= 2
ENDIF
LOOP
'All Lights Red'
alllightsred:
HIGH 15
HIGH 14
HIGH 13
HIGH 12
HIGH 11
PAUSE 2000
RETURN
'East Turning Light goes Green and East Light goes green'
Eastandwest:
LOW 13
LOW 12
HIGH 9
HIGH 10
PAUSE 6500
'Turning light goes yellow
LOW 10
HIGH 5
PAUSE 3500
'Turning light goes Red and West goes Green
LOW 15
LOW 5
HIGH 7
HIGH 12
PAUSE 3500
'West and East light goes Yellow'
LOW 9
LOW 10
LOW 7
HIGH 2
HIGH 4
PAUSE 3500
'West and East go red
LOW 4
LOW 5
LOW 2
HIGH 15
HIGH 13
PAUSE 5000
RETURN
northandsouth:
'North and South go green'
HIGH 8
HIGH 6
LOW 11
LOW 14
PAUSE 6500
'North and South go Yellow'
LOW 8
LOW 6
HIGH 3
HIGH 1
PAUSE 3000
'North and south go red'
LOW 3
LOW 1
HIGH 11
HIGH 14
PAUSE 3000
RETURN
"
Comments
' turn on light
time = 500 ' wait 500ms
gosub CheckButtons
' turn off light
time = 500 ' wait 500ms
gosub CheckButtons
button(0) = 0 ' reset button state
' now go check other buttons for stuff to do
Though you could only use gpio irq + timer irq and hardware pwm for this simple project,
but keeping it to a simple state-machine that runs on 1/4sec ticks is easier to understand.
"counter VAR WORD
red VAR WORD
ns VAR WORD
we VAR WORD
pbns VAR WORD
pbwe VAR WORD
counter = 0
main:
DO
HIGH 0
LOW 8
GOSUB alllightsred
GOSUB crosswalk
GOSUB turninglight
GOSUB crosswalk
GOSUB turninglightgoesyellow
GOSUB crosswalk
GOSUB turnlightred
GOSUB crosswalk
GOSUB eastandwestgogreen
GOSUB crosswalk
GOSUB westandeastgoyellow
GOSUB crosswalk
GOSUB westandeastgored
counter = counter + 1
DEBUG ? counter
GOSUB crosswalk
GOSUB northandsouthgogreen
GOSUB crosswalk
GOSUB northandsouthgoyellow
GOSUB crosswalk
GOSUB northandsouthgored
counter = counter + 1
DEBUG ? counter
GOSUB crosswalk
LOOP
'All Lights Red'
alllightsred:
FOR red = 0 TO 1000
HIGH 15
HIGH 12
HIGH 6
HIGH 7
PAUSE 1
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
'Turning Light goes Green AND East Light goes green'
turninglight:
FOR we = 0 TO 2500
LOW 7
LOW 6
HIGH 9
HIGH 4
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
'Turning light goes yellow
turninglightgoesyellow:
FOR we = 0 TO 1100
LOW 4
HIGH 5
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
Turnlightred:
FOR we = 0 TO 1000
LOW 5
HIGH 6
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
Eastandwestgogreen:
'Turning light goes Red and West goes Green
FOR we = 0 TO 2000
LOW 15
HIGH 13
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
westandeastgoyellow:
'West and East light goes Yellow'
FOR we = 0 TO 1100
LOW 9
LOW 13
HIGH 14
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
'West and East go red
westandeastgored:
FOR we = 0 TO 1100
LOW 14
HIGH 15
HIGH 7
NEXT
RETURN
northandsouthgogreen:
'North and South go green'
FOR ns = 0 TO 2500
LOW 12
HIGH 10
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
'North and South go Yellow'
northandsouthgoyellow:
FOR ns = 0 TO 1100
LOW 10
HIGH 11
IF IN3 = 1 AND pbwe = 0 THEN
pbns = pbns + 1
pbwe = 0
DEBUG ? pbns
ELSEIF IN2 = 1 AND pbns = 0 THEN
pbwe = pbwe + 1
pbns = 0
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
'North and south go red'
northandsouthgored:
FOR ns = 0 TO 1100
LOW 11
HIGH 12
IF IN3 = 1 THEN
pbns = pbns + 1
DEBUG ? pbns
ELSEIF IN2 = 1 THEN
pbwe = pbwe + 1
DEBUG ? pbwe
PAUSE 1
ENDIF
NEXT
RETURN
'check for pushbutton'
crosswalk:
IF counter >= 2 AND pbns >= 1 AND pbwe = 0 AND IN10 = 1 THEN
HIGH 8
LOW 0
PAUSE 20000
FOR counter = 0 TO 100
HIGH 8
LOW 0
PAUSE 50
LOW 8
LOW 0
PAUSE 50
NEXT
counter = 0
pbns = 0
pbwe = 0
RETURN
ELSEIF counter >= 2 AND pbwe >= 1 AND IN9 = 1 THEN
FOR counter = 0 TO 10000
HIGH 1
HIGH 5
LOW 4
IF IN3 = 1 THEN
pbns = pbns + 1
DEBUG ? pbns
ENDIF
DO UNTIL IN3 = 0
IF IN3 = 0 THEN
pbns = pbns + 0
ENDIF
LOOP
NEXT
FOR counter = 0 TO 100
HIGH 1
PAUSE 50
LOW 1
PAUSE 50
NEXT
LOW 1
counter = 0
pbns = 0
pbwe = 0
RETURN
ELSEIF pbns > = 1 AND IN10 = 1 THEN
DEBUG ? pbns
DEBUG ? Counter
HIGH 8
LOW 0
PAUSE 20000
FOR counter = 0 TO 100
HIGH 8
LOW 0
PAUSE 50
LOW 8
LOW 0
PAUSE 50
NEXT
HIGH 0
LOW 8
RETURN
ELSEIF pbns= 0 AND pbwe = 0 AND counter >= 2 THEN
pbns = 0
pbwe = 0
ENDIF
RETURN"