Newbie input/button query

c7trp

New Member
Hi

Bear with me, I'm new to this stuff :)

I'm writing an application that needs to respond to the user holding a push button down for 3 or more seconds.

The program is doing nothing else, except waiting for the key press.

This is the code I'm using
Code:
  Do : Loop Until pin1 = 1               'wait for button press
  wait 3                                      'wait 3 seconds
  if pin1=1 then                            'if its still pressed then...
      do : loop until pin1=0             'wait for button to be released
       'respond to button press event.
  endif
Is this the best way of doing this?

Thanks
 

hippy

Ex-Staff (retired)
I'm writing an application that needs to respond to the user holding a push button down for 3 or more seconds.
Welcome to the PICAXE forum.

The code is a good first attempt but it can be fooled. Press the button briefly, wait two seconds then hold it for another one second or longer and it will think the short pushes lasted the whole three seconds.

It's a bit like looking in a room to check someone is there, checking three minutes later and seeing they are still there. That they are doesn't prove they did not leave during those three mintes any number of times.

What you need to do is check more frequently that the button is still pushed and a change in logic will also make the issue clearer to understand and should make things easier to code; "Do whatever if the button has not been released during the three seconds after being first pushed".
 

c7trp

New Member
Thanks All.

Now I know I'm going in the right direction, I'll can re-think the code to accomodate Hippy's observations :eek:

I did look at the button command, but it looks mighty complicated! I was planning to debounce with a capacitor. Also if the button needs to be pushed for 3 seconds or so, then I assume bounce wouldn't be too much of an issue anyway?
 

hippy

Ex-Staff (retired)
Bounce issues depend on how frequently you check the button. In the original code you were allowing up to three seconds of bounce to be ignored :)
 

westaust55

Moderator
Another option might be to use the PULSIN command.

Use a loop and run the PULSIN command say 5 times each with a timeout duration of 0.65 seconds.
Store each result in consecutive SFR RAM locations, and return to the PULSIN comamnd.
Then after the 5 loops check the stored results.
If the switch is released at any time(s) during the 3 seconds then one (or more) of the period will not reach the maximum period.
 

Dippy

Moderator
Your code looks fine C7. There are variations on this theme, but yours looks abs OK.
I can't see any sensible reason to complicate matters. If it works in the 'Real World' then hurrah.
Personally, I never use the Button command as I don't uderstand it.

For that long delay you needn't worry about debounce, unless you are expecting 3 seconds of bounce and scrape ;)
As your second 'button press' test (the IF bit) is after 3 seconds, you must ensure that the switch quality is good enough. I have seen some real cheap flakey switches not providing consistent contact even when pressed. i.e. a bit off/onny even when pressed.
I would imagine in most cases it will be just fine.

Obviously the user must ensure they don't have the DTs when using it.
 

fred_b

Member
buttons.JPG

I have a problem that is relevant to this thread.

I have 3 buttons in my circuit, as well as an lcd.
(I am using an 18x picaxe chip)

(see schematic)

I am using readadc 0,b11 to get input.

I used serout to display the value of b11 on the lcd.

For example: when pressing one button, the display is 150 plus or minus 2. When pressing no buttons the value for b11 goes back to zero. The other readings were ~180 and ~252.

This all works perfectly fine until I disconnect the serial cable. Then the "no button pressed" reading becomes very erratic and changes constantly. Pressing any button produces mostly readings of 255 or so.

What is a good way to read 3 button input using a single adc pin?
 
Last edited:

lbenson

Senior Member
Fred--the Enhanced Serial Download Circuit (Manual 1, p 37 in V 6.7) provides a better reference for ADC when the serial cable is disconnected.
 

fred_b

Member
Thanks for the fast reply. So the bat85 should do the trick?

I will have to get some of those.

Is my approach a good one for getting button inputs? Is there a better way?
 

krypton_john

Senior Member
Welcome to the PICAXE forum.

The code is a good first attempt but it can be fooled. Press the button briefly, wait two seconds then hold it for another one second or longer and it will think the short pushes lasted the whole three seconds.

It's a bit like looking in a room to check someone is there, checking three minutes later and seeing they are still there. That they are doesn't prove they did not leave during those three mintes any number of times.

What you need to do is check more frequently that the button is still pushed and a change in logic will also make the issue clearer to understand and should make things easier to code; "Do whatever if the button has not been released during the three seconds after being first pushed".
It could be a nice use for interrupts?
 

lbenson

Senior Member
I can't say for certain that the BAT85 (available from Digikey, among others) will fix your problem, but people have said in the past that it will help stablize ADC reads, and I think that that has specifically been said with regard to disconnection of the download cable. If you are breadboarding and have another Schottky diode available, you might try that.
 

fred_b

Member
This can't be all that difficult!

Thank you everyone for your willingness to help out! I always get a fast reply on this forum!

Ok. For some reason I am struggling with button input.

I've switched from reading adc input to having the button, tied high with a 22K resistor and the other pole connected to an input pin.

I can use "if pin2=high then..." with no problems when the serial cable is connected.

Again, things get erratic when the serial cable is disconnected.




What is the most common method for detecting a button press?
 

Attachments

lbenson

Senior Member
What you have will be, as you say, "erratic" because when your pushbutton is not down, the input pin will be "floating" and subject to false triggering from rf sources such as mains or florescent lighting. The pin needs to be pulled low normally. See manual 3, p 25 for switch circuits and code.
 

BeanieBots

Moderator
lbenson is spot on about why your circuit will be 'erratic'.
either,
The resistor should connect directly to the input pin.
The other end should go to either 5v or 0v depending on which way you want the switch to act.
If you connect the resistor to 5v, then the switch should go to 0v and the input will be high (5v) when the switch is open.
If you connect the resistor to 0v, then the switch should go to 5v and the input will be low (0v) when the switch is open.
 

Colinpc

New Member
I have been working on a program requiring being able to differentiate between 1, 2 or 3 pulses in a 2 sec period or being held for 1 sec for a reset function.

The interrupt routine below is how I did it. The section starting at timelp loops until the button is released. In this case for one second. If released earlier it looks for more presses. If held for the period it resets for program.

Fred


;Interrupt service routine

interrupt:
rstflag = 0 ;make sure reset flag is cleared on entry
low led ;make sure LED is off

pause 10 ;debounce switch 10ms


timelp: ;loop for 1 sec,
for n = 0 to 100 ;100 x 10 ms
if pushbut = 1 then sw_open ;switch is open again
pause 10 ;pause 10 ms
next n ;button held 1 sec if timed out

if hours = 0 and delflag = 0 then sw_closed
;nothing to reset

gosub flash300 ;acknowledge reset

rstflag = 1 ;set reset flag

sw_closed:
if pushbut = 0 then sw_closed ;wait for switch to open
goto quit

sw_open:
hours = 1 ;button pressed once & was not a reset

swopen:
for n = n to 200 ;look for another pulse
if pushbut = 0 then hrs ;in 2 seconds
pause 10
next n
goto quit

hrs: inc hours

sw_closed1:
if pushbut = 0 then sw_closed1 ;wait for switch to open

if hours > 2 then goto quit

if n < 200 then goto swopen ;look for third pulse

quit: setint inlvl,pinmask ;re enable interrupt
return
 
Last edited:
Top