Shop OBEX P1 Docs P2 Docs Learn Events
Push buttons being read while other actions are being performed — Parallax Forums

Push buttons being read while other actions are being performed

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

"

Comments

  • First of all ... we can only give so much help on school projects ... that said, we can certainly make suggestions. You probably need to break up the PAUSEs into a subroutine that also checks all the pushbuttons and sets variables for the pushbutton states maybe every 100ms like this:
    pushed  var bit(4)
    location var nib
    i            var nib
    temp     var bit
    button   var bit(4)
    time      var word
    
    CheckButtons:
    '
    ' This subroutine checks to see if a button is pushed.  It won't accept another push until the
    ' button is released and the button push is remembered until it is acted upon by resetting
    ' button(i) to zero.  You set time to the desired cycle time in ms and this returns after that.
    '
      for i = 0 to 3
        temp = INA.bit0(i) ' check IN0,IN1,IN2,IN3
        if pushed(i) = 0 and temp = 1 then button(i) = 1 ' was up now down?
        pushed(i) = temp ' save previous state for next check
      next i
      pause 100 ' clock 'tic is 100ms
      time = time - 100
      if time > 0 then goto CheckButtons ' if time not done, repeat
      return
    
    Typically, you'd do some action for a cycle calling CheckButtons for any pauses in the cycle like:

    ' 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
  • This is when you learn how to use highest common denominator, and time-slice your code for that.
    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.




  • This is the code I have now. All that I am missing is getting the pedestrian light to go from West to East to North and South if the PBNS as been pressed while the pedestrian light for "WE" is on. I got the code to read that pbns has been pressed while it is on. I just cant figure out why it wont execute the condition I have for the crosswalk to switch after the condition is met.



    "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"


    Mike Green wrote: »
    First of all ... we can only give so much help on school projects ... that said, we can certainly make suggestions. You probably need to break up the PAUSEs into a subroutine that also checks all the pushbuttons and sets variables for the pushbutton states maybe every 100ms like this:
    pushed  var bit(4)
    location var nib
    i            var nib
    temp     var bit
    button   var bit(4)
    time      var word
    
    CheckButtons:
    '
    ' This subroutine checks to see if a button is pushed.  It won't accept another push until the
    ' button is released and the button push is remembered until it is acted upon by resetting
    ' button(i) to zero.  You set time to the desired cycle time in ms and this returns after that.
    '
      for i = 0 to 3
        temp = INA.bit0(i) ' check IN0,IN1,IN2,IN3
        if pushed(i) = 0 and temp = 1 then button(i) = 1 ' was up now down?
        pushed(i) = temp ' save previous state for next check
      next i
      pause 100 ' clock 'tic is 100ms
      time = time - 100
      if time > 0 then goto CheckButtons ' if time not done, repeat
      return
    
    Typically, you'd do some action for a cycle calling CheckButtons for any pauses in the cycle like:

    ' 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

Sign In or Register to comment.