Shop OBEX P1 Docs P2 Docs Learn Events
Flip Flop Help — Parallax Forums

Flip Flop Help

izulustudiosizulustudios Posts: 6
edited 2011-04-02 15:44 in BASIC Stamp
Hello and thank you all for this fantastic resource!
I am fumbling around with I suspect is an overly unwieldy amount of code for my application.
My application is as follows:
A set of 8 momentary buttons with an accompanying set of 8 LED's (namely they are illuminated momentary pushbuttons)
I need for each of them to latch; that is, for the corresponding output pin to go high and remain high until any other button is depressed, and for the latch to then shift to the next (random) button to be depressed.
Put very simply: There are 8 buttons, which when pressed, light up and stay lit up until a subsequent button is pressed.
This circuit would be used to control an adjacent system with it's own set of digital inputs and would serve purely as indicator of the last button to have been pressed.
I currently have a convoluted set of IFs, THENs and UNTILs in a big loop, however I suspect there must be a far more elegant way of monitoring a set of 8 dig inputs in one routine and latching a corresponding set of dig outs in another?:innocent:
Any further guidance would be hugely appreciated.
Thanks again.

Dan

Comments

  • davejamesdavejames Posts: 4,047
    edited 2011-04-01 19:43
    Hello Dan,

    People are gonna ask - would you post your code, please? There may be some things to be done there.

    Also (my own curiosity), are you sold on using a Stamp for this rather than some latches?

    Regards,

    DJ
  • vaclav_salvaclav_sal Posts: 451
    edited 2011-04-01 19:44
    How about simply reset all outputs each time button is press and then set / latch the selected pin?
    Vaclav
  • izulustudiosizulustudios Posts: 6
    edited 2011-04-01 21:08
    davejames wrote: »
    Hello Dan,
    Also (my own curiosity), are you sold on using a Stamp for this rather than some latches?
    DJ

    Thanks. Yes, my existing version uses 74LS logic latches, however I am hoping to reduce my component list and use a micro.
    This will also allow us to change the conditions later, if needed.
    Thanks anyway.
  • izulustudiosizulustudios Posts: 6
    edited 2011-04-01 21:11
    vaclav_sal wrote: »
    How about simply reset all outputs each time button is press and then set / latch the selected pin?
    Vaclav
    Thanks Vaclav, that sounds like a great idea.
    What is the simplest code definition of "set / latch"?.
    Thanks again.
  • ZootZoot Posts: 2,227
    edited 2011-04-01 22:00
    This is example presumes all 8 buttons are on 8 adjacent pins and 8 leds on 8 adjacent pins. If not, you could still "map" your inputs to bits in the variables and likewise outputs... this also handles some simple debouncing
    leds VAR OUTL
    buttons VAR INH
    
    buttonsNow VAR Byte
    buttonsLast VAR Byte
    idx VAR Nib ' reusable work variable
    tmp VAR Byte ' resusable work variable
    
    Start:
    
    OUTS =%0000000000000000  ' all off
    DIRS = %0000000011111111 ' pins 0-7 outputs (leds), pins 8-15 inputs (buttons)
    
    PAUSE 100 ' let settle
    
    buttonsNow = buttons ' capture 8 button inputs to byte
    buttonsLast = buttonsNow ' seed as "last"
    
    Main:
      ' debounce buttons and capture if different....
      tmp = buttons   ' capture buttons to seed comparison
      FOR i = 0 TO 5  ' should be good for average debounce
          IF buttons <> tmp THEN EXIT   ' if the current state of pins doesn't match, quit the loop
      NEXT
      IF i >= 5 THEN   ' you are only here if the buttons remained stable...
          buttonsNow = tmp   ' move it to "now"
      ENDIF
         
      IF buttonsNow <> buttonsLast THEN ' you had a change from the last time
         leds = buttonsNow  ' move to leds
      ENDIF
    
     ' the nice thing is you can do other stuff here if you need to, and the leds will be fine and 
     ' you won't miss human button presses... e.g. 
    
      SEROUT x,y,z, [ tmp ] ' comm with some other device
      SERIN x,y,z, [ tmp ] ' comm with some other device
      
      ' do some other stuff
       
    
    
        buttonsLast = buttonsNow  ' save as last -- do it last so you can "parse" state changes if you want...
    
      GOTO Main
        
    

    Another nice thing about this setup is it lets you see if a button was "released" or "pressed", e.g.
    IF buttonsNow.BIT4 = 1 AND buttonsLast.BIT4 = 0 THEN ' if button 4 is high and it was low, it was pressed...
       DEBUG "button 4 pressed!", CR
    ELSEIF buttonsNow.BIT4 = 0 AND buttonsLast.BIT4 = 1 THEN
       DEBUG "button 4 released", CR
    ELSEIF buttonsNow.BIT4 = 1 AND buttonsLast.BIT4 = 1 THEN
       DEBUG "let go of it already!", CR
    ENDIF
    
    ' or...
    
    FOR idx = 0 TO 7
       IF buttonsNow.BIT0(idx) = 1 AND buttonsLast.BIT0(idx) = 0 THEN
          DEBUG "button ", DEC1 idx," pressed!", CR
       ELSEIF buttonsNow.BIT0(idx) = 0 AND buttonsLast.BIT0(idx) = 1 THEN
          DEBUG "button ", DEC1 idx," released!", CR
       ENDIF
    NEXT
    
    

    So.... combining the two to latch only a "press"...

    leds VAR OUTL
    buttons VAR INH
    
    buttonsNow VAR Byte
    buttonsLast VAR Byte
    idx VAR Nib ' reusable work variable
    tmp VAR Byte ' reusable work variable
    
    Start:
    
    OUTS =%0000000000000000  ' all off
    DIRS = %0000000011111111 ' pins 0-7 outputs (leds), pins 8-15 inputs (buttons)
    
    PAUSE 100 ' let settle
    
    buttonsNow = buttons ' capture 8 button inputs to byte
    buttonsLast = buttonsNow ' seed as "last"
    
    Main:
      ' debounce buttons and capture if different....
      tmp = buttons   ' capture buttons to seed comparison
      FOR i = 0 TO 5  ' should be good for average debounce
          IF buttons <> tmp THEN EXIT   ' if the current state of pins doesn't match, quit the loop
      NEXT
      IF i >= 5 THEN   ' you are only here if the buttons remained stable...
          buttonsNow = tmp   ' move it to "now"
      ENDIF
         
      IF buttonsNow <> buttonsLast THEN ' you had a change from the last time, check for a press
    	FOR idx = 0 TO 7
    	   IF buttonsNow.BIT0(idx) = 1 AND buttonsLast.BIT0(idx) = 0 THEN
                   leds = buttonsNow  ' move to leds
                   EXIT
               ENDIF
            NEXT
    
      ENDIF
    
     ' the nice thing is you can do other stuff here if you need to, and the leds will be fine and 
     ' you won't miss human button presses... e.g. 
    
      SEROUT x,y,z, [ tmp ] ' comm with some other device
      SERIN x,y,z, [ tmp ] ' comm with some other device
      
      ' do some other stuff
      
        buttonsLast = buttonsNow  ' save as last -- do it last so you can "parse" state changes if you want...
    
      GOTO Main
        
    
  • izulustudiosizulustudios Posts: 6
    edited 2011-04-02 15:44
    Wow Zoot, thats awesome, thanks!
    I imagined a solution exactly like yours, but was still very hazy with storing the button states as Byte's and the use of OUTS and DIRS.
    This really helps me join the dots, so thanks again.
Sign In or Register to comment.