PDA

View Full Version : Condition check using single switch as toggle on/off?



Oldbitcollector (Jeff)
12-28-2009, 10:23 AM
Ok, this is probably very simple, but it's been driving me crazy for the last hour.
Time to ask for help...

I'm trying to use a single pushbutton input as an on/off toggle in my loop.
(Thanks Nick for this headache. :)

I can't seem to get wrap my head around detecting the push of button
to change from and on/off state in the loop without it detecting wrong.

something like this:




counter++ 'main loop counter

if ina[play] == 1 and counter > 5
'' Stop what I'm doing here

if ina[play] == 1
'' Continue




Hopefully I've given and idea what I'm shooting for. Thanks in advance!

OBC

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?

Visit the: The Propeller Pages (http://www.warrantyvoid.us/tiki-index.php?page=Propeller) @ Warranty Void.

kwinn
12-28-2009, 10:31 AM
I think you may need a variable to store the current state (on or off) of the button and flip the state each time the button is pressed and then released.

whicker
12-28-2009, 10:50 AM
Yeah, there's really more than one programming step going on here.
Two buttons, one "Start" and the other "Stop" are really easy to do with IF statements.


To set up toggling with one button, you'll first need to clean up the signal with debounce.
Microswitches don't bounce for more than about 20ms, but I've seen 12.5ms debounce times as well.

After you can reliably detect a button press, there's a need to find the rising edge of the debounced signal.
Then use the rising edge flag in the if statement to toggle the state of something.

JonnyMac
12-28-2009, 10:55 AM
You should be able to XOR the present state with the input (assuming pressed = 1) to toggle the state; that said, after toggling you may want to add a short delay to prevent oscillating.

kwinn
12-28-2009, 11:16 AM
In general I run through a loop where the push button switch gives me 4 consecutive high (or low) readings before I consider it a valid level. Then I look for 4 consecutive low (or high) readings, and after that I consider that the button has been pressed and released so I can update the variable (on to off, off to on, etc). Works very well in spin. Pasm needs a waitcnt in the loop.

whicker
12-28-2009, 11:20 AM
JonnyMac:

Button = 0, State = 0

Button = 1, State = 0, Button XOR State = 1
Toggle State: State = 1
{Delay in which button is released}

Button = 0, State = 1, Button XOR State = 1
Toggle State: State = 0
{Delay, button is still released}

Button = 0, State = 0, Button XOR State = 0

kwinn
12-28-2009, 12:25 PM
OBC, here is a PASM routine I used to read and debounce a couple of switches. It is called once per mSecond from the main program.

Hope it helps.

SamMishal
12-28-2009, 12:26 PM
I think your problem is called Push Button BOUNCE.

You need a DEBOUNCING routine to make sure that you are getting a CLEAN state.

Try this routine



Pri Get_Button_Debounced(PB_Pin) | c
'Returns true if button is pushed assuming active low.
'It also performs a debounce of the button.
'the routine assumes you have alread set DirA[PB_Pin]~~
'in the calling code
c := 0
if InA[PB_Pin] 'if not pushed return 0
return 0
repeat 'perform debouncing
waitcnt(ClkFreq/100+cnt)
if InA[PB_Pin] 'again active low
return 0
c++
until c == 10

repeat until InA[PB_Pin] 'remove this line if all you need is button state and not wait for it to be released
return true


The line before last can be replaced with a DELAY (e.g. Waitcnt()) to enable a button to
register as MULTIPLE pushes if it stays down. The delay will define how fast the REPEAT RATE
is going to be.... just like in a PC keyboard.

If you keep the line then you will have to Push the button and Release it to register as a push.

The routine assumes an ACTIVE LOW button.... if you want active high then reverse the
logic whenever there is an InA[].

Regards



Samuel

P.S. as you can tell from the code this will tie up the program execution if the button is pushed
and stays pushed....I you need CONCURRENT execution then use a cog with the routine.


Post Edited (SamMishal) : 12/28/2009 4:39:10 AM GMT

JonnyMac
12-28-2009, 12:27 PM
Exaclty; when the button is pressed (1) you get a change; when not pressed, no change. I use XOR to do this in many programs. I do some thing like this:



if ina[BTN] == Pressed
state ^= 1
waitcnt(cnt + (clkfreq >> 2))



Of course, this kind of code must run in a loop and that's not always convenient. It would be pretty easy to create a PASM cog that monitored several inputs, toggling their state (stored in the hub) as required.

Oldbitcollector (Jeff)
12-28-2009, 12:38 PM
Thanks guys..

That is the elegant solution I was looking for.
It looks like there is more going on in the code, so I've got more digging to do elsewhere.

OBC

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?

Visit the: The Propeller Pages (http://www.warrantyvoid.us/tiki-index.php?page=Propeller) @ Warranty Void.