detecting long button pushes

triphil

New Member
Hi

I would like to know the best way of detecting long button pushes as opposed to a quick push - I would like to use one button for two jobs etc. Would it be better to use the button function or just look to see if a pin is held low?
 

nick12ab

Senior Member
Welcome to the PICAXE Forum.

The behaviour of the button command is:
This gives action like a computer keyboard key press - send one press, wait for 'delay' number of loops, then send multiple presses at time interval 'rate'. Note that button should be used within a loop. It does not pause program flow and so only checks the input switch condition as program flow passes through the command.
I don't think it can be used to perform a different action based on how long the button is held for.

Instead you can use the timer or time variable depending on PICAXE used.

Example:
Code:
main:
	time = 0
	if pinC.1 = 1 then
		do while pinC.1 = 1 : loop
		if time > 3 then
			goto thing1
		else
			goto thing2
		end if
	end if
	goto main

thing1:

	goto main
	
thing2:
	
	goto main
 

westaust55

Moderator
How many inputs/switches do you want this feature associated with?
what typical durations for short and long presses?

May be possible with use of interrupts (SETINT) and PULSIN command or interrupt and a Timer /the Time variable.
Use the interrupt to detect start of a keypress.
 

Buzby

Senior Member
A lot depends on if you need to do something else waiting for the button push.

Ir you just need to 'sit and wait' then PULSIN is easiest.

What PICAXE are you using ?

If you can use multiple tasks then it's quite easy to put a timing 'clock' in one task, and use another to look for the button on/off.
 

Goeytex

Senior Member
The code example below should work ok. It discriminates between a short press & release and a 3 second hold.
When the switch is held down for 3 seconds it does not need to be released to jump to the long press routine. Just hold
the switch down and in ~ 3 seconds the program will jump to "LONG".

Code:
#picaxe 14M2

setint %00000010,%00000010 [COLOR="#008000"] 'interrupt on pinc.1 high[/COLOR]

main:

do
   [COLOR="#008000"] ' MAIN PROGRAM LOOP [/COLOR]
loop


interrupt:
        pause 40  [COLOR="#008000"] 'Debounce  switch [/COLOR]
        
      if pinC.1 = 1 then  [COLOR="#008000"]'Switch is still pressed[/COLOR]
	   
	      time = 0 [COLOR="#008000"]       'Start timer[/COLOR]
	   
	      do while pinC.1 = 1            [COLOR="#008000"] 'now switch has been pressed for about 20ms [/COLOR]
	         if time > 2 then goto long  [COLOR="#008000"] 'switch held down for 3 sec & does not need to be released .[/COLOR]
	      loop                           [COLOR="#008000"] 'to jump to "long"[/COLOR]
		    
	    goto Momentary[COLOR="#008000"] 'momentary press & release	    [/COLOR]
   
      else [COLOR="#008000"] 'switch not held for at least ~40ms[/COLOR]
         setint %00000010,%00000010  
         return
         endif
       		
        Momentary: [COLOR="#008000"] 'Switch was pressed momentarily[/COLOR]
        setint %00000010,%00000010
        return
	 
        Long:[COLOR="#008000"] 'Switch held down for ~3 seconds[/COLOR]
        setint %00000010,%00000010
        return
 
Last edited:

triphil

New Member
Hi

would a simple bit of programing like

main:

gosub beep
if pinc.3 = 0 then main rem detect button press or not
pause 500
if pinc.3 = 0 then beepdelay rem detect button press or not
pause 500
if pinc.3 = 1 then slumber rem detect button press or not
goto main


work or will the button bounce cause problems???
 

inglewoodpete

Senior Member
Long pauses when reading inputs often produces unreliable results. Your code may work for you but it depends on what your application needs.

A while ago I wrote a small piece of demonstration code for the 08M (AXE092 Schools Experimenter Kit). It is posted here in Finished User PICAXE Projects. It shouldn't be too difficult to modify the code for other PICAXE chips/circuits. The code uses an "open looping" technique that allows the PICAXE to do many things without getting "stuck" on one task.
 
Just a thougt, I'm not able to test it right now but,

Why not set an interrupt diretly after the interrupt routine started that will detect the release of the button?
Code:
interrupt:
  setint %00000010,%00000000  'interrupt on pinc.1 low
  <... rest of programme>
also I must warn on using returns in interrupt routines. It is easy to get in the situation of nested loops or empty return stacks. Better use 'goto main' or whatever label tou wat to go to.

Also, I also like the open loop approach but rather make the counters count down and detect the '0' value.
This way you can easily set the desired value every time different when you trigger the routine without changing code.

Just my 0.05 cents...
 

geoff07

Senior Member
Gotos are the software equivalent of a wiring rats nest. The goto has been deprecated since the beginning of software engineering in the 1970s or theareabouts (see Dijkstra). Picaxe Basic is a sophisticated language, albeit with the limitations of the chips. There is no need to use upward gotos ever and only one case where a downwards one might be needed (for serial timeouts). If you discipline yourself to write code with gosubs, do/while, select/case, if/else constructs, and exit, you will understand your code better when you write it and again after a few years, should you ever come back to it. Rant over (but it is a serious point worth considering for any but the most trivial programs).
 
Top