Shop OBEX P1 Docs P2 Docs Learn Events
Some sort of state monitoring? — Parallax Forums

Some sort of state monitoring?

Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
edited 2011-10-11 12:56 in Propeller 1
I've got a programming challenge that I haven't been able to get my head around..

I'm reading a switch that is either on all the time or off all the time, however I need to activate a command only once when the state of the switch changes.

Anyone have an elegant method for this?

Thanks
OBC

Comments

  • AribaAriba Posts: 2,690
    edited 2011-10-10 21:25
    Is this elegant enough?
    PUB Main  | oldstate, newstate  
      oldstate := ina[pin]        'init old state
      repeat
        newstate := ina[pin]      'read new state
        if newstate <> oldstate   'detect change
          if newstate==1
            ...                   'changed Low to High
          else                    
            ...                   'changed High to Low
          oldstate := newstate
          'add a delay here if you need debouncing (~15ms)
    

    Andy
  • Mike GreenMike Green Posts: 23,101
    edited 2011-10-10 21:25
    In hardware, you can do this with a capacitor to differentiate the switch output. You get a positive going pulse when the switch goes from low to high and a negative going pulse when the switch goes from high to low. You can use a dual optoisolator with the LEDs connected back to back and the outputs in parallel to produce a single positive going pulse when the switch changes either from low to high or from high to low.

    In software, you can do the same sort of thing using a single memory bit to save the most recent state of the switch. Each time through the loop, you compare the bit to the state of the switch. If they're different, you execute your command. In all cases, you copy the state of the switch as it was when you tested it to the bit, wash, rinse, and repeat.
  • shimniokshimniok Posts: 177
    edited 2011-10-10 21:31
    Not that I've done this specific thing on Propeller just yet, but I'd probably try code that, based on current state, issues either waitpne or waitpeq followed by the command, then loop through the code again. Assuming some sort of debouncing in hardware is present. There are programmatic ways to do it but I would think waitpne or waitpeq would be more elegant. That's what I used to sync to rising/falling clock edges on one of my projects.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-10-10 22:01
    shimniok wrote: »
    Not that I've done this specific thing on Propeller just yet, but I'd probably try code that, based on current state, issues either waitpne or waitpeq followed by the command, then loop through the code again. Assuming some sort of debouncing in hardware is present. There are programmatic ways to do it but I would think waitpne or waitpeq would be more elegant. That's what I used to sync to rising/falling clock edges on one of my projects.

    I have used the waitpeq/pne for syncing to the ADC sample clock to the csel in the ADC/DAC fun objects. The one unknown in this equation is by state change does Jeff anticipate always one way or the other with brief excursions to the opposite state, or once switched does it stay permanently there (mostly). If it is not a permanent transition, all three of the solutions presented here have a good probability of failure if the transition is narrow enough to be missed by a cog watching for this transition not being in a tight enough loop time-wise.

    If it is a short transition then consider using the counter feature of the prop cog wherein the init routine looks at the state of the monitored pin and uses a movi to set the counter for pos or neg edge transition detection to capture the transient depending on the initial state recorded.

    Otherwise, you are not looking for a transition, rather a level change. In that case, I would probably use the waitpeq/pne and again at init, see what the initial state is and set the peq/pne instruction looking for one or zero using the movi as done for the transition detect above.

    Frank
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2011-10-11 07:18
    Ah!

    if newstate <> oldstate

    That's what I wasn't thinking of!

    Thanks Ariba!

    OBC
    Ariba wrote: »
    Is this elegant enough?
    PUB Main  | oldstate, newstate  
      oldstate := ina[pin]        'init old state
      repeat
        newstate := ina[pin]      'read new state
        if newstate <> oldstate   'detect change
          if newstate==1
            ...                   'changed Low to High
          else                    
            ...                   'changed High to Low
          oldstate := newstate
          'add a delay here if you need debouncing (~15ms)
    

    Andy
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-11 10:29
    I'd not call waitpne or waitpeq more elegand for the given problem! Oldbitcollector stated that the state is either 0 or 1 ALL the time. I'm sure he meant something like it's only changing very seldom. So, with waitpne and waitpeq you would block a COG for the most time.
    Aribas code can easily be added to a loop which is doing some real work.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-10-11 11:15
    MagIO2 wrote: »
    I'd not call waitpne or waitpeq more elegand for the given problem! Oldbitcollector stated that the state is either 0 or 1 ALL the time. I'm sure he meant something like it's only changing very seldom. So, with waitpne and waitpeq you would block a COG for the most time.
    Aribas code can easily be added to a loop which is doing some real work.

    If he is looking to create a safety ckt or a watch dog function, then he may want a dedicated cog. Hate to waste a cog unless you have to, but cheaper than external circuitry if you have a cog to spare.

    Frank
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2011-10-11 12:56
    I've got a master loop which Andy's code fit into nicely. The loop was so fast that I actually had to create a 50 bounce loop when the change was detected so that the device I'm communicating with catches the change. :)

    OBC
Sign In or Register to comment.