How do i create a HOLD-in button function?

OLDmarty

Senior Member
Hi All,

I was thinking about adding a button onto a project, where the button must be held IN for say 2 seconds before a function within my code is triggered.
I was looking at "Button" & "If Pin" options maybe with a long pause command (for 2 seconds), but not sure if they would achieve the press-hold operation needed???

I'm trying to avoid using interrupts & timers if possible, i wanted to keep this code snippet simple & easy. ;-)

Does anyone have a snippet of code that will get me started in the right direction?

with thanks in advance.
 
Maybe a for-loop? When the button is pressed initially, the loop starts ... every 100ms, the loop checks to see if the button is still low ... if so, the loop continues, if not, the loop exits with "Unpressed" ... after 20 loops, you'll know the button was held for a solid 2 seconds....and you can act accordingly.

The PICAXE would be tied up doing nothing else during this time though.

The 2 second delay and re-check won't work, because you could press and release the button, then, 2 seconds later, press it again, and the code would think you've held it the entire time.
 
M2 code: if pButton = 1 then: time=0: do while pButton=1 and time < 2000: loop: endif

Any other code you want might be in the loop.
 
Hi,

RTFM :) I must admit I've never used it, but there is a BUTTON command. ;)

Cheers, Alan.

PS: "time" is a reserved word, one second counter, so the M2 code above might not do what you expect. :(
 
Last edited:
PS: "time" is a reserved word, one second counter, so the M2 code above might not do what you expect. :(
Indeed, the code as shown waits 2000 seconds (not 2000 milliseconds). It will work, with a suitable settimer value, on X2. But again, if you are using timer (X2 equivalent) for anything else, you will need to count and test the time from the start by using a couple of word variables.
 
You can do it by just using a variable to count elapsed time ...
Code:
w0 = 0
Do
  Pause 1
  w0 = w0 + 1
  If BTN_PIN = 0 Then
    w0 = 0
  End If
Loop Until w0 >= 2000
How best to do it, how to structure it as a loop with button handling within it, will depend on what else the code needs to be doing, what you want to do if a button push is less than a two second hold.
 
Using a 10k resistor and a 100uf CAP, I get a 2-second charge time from 0 - 4V ... so, theoretically, using a ST input, you shouldn't get a HIGH for about 2 seconds after the switch is pressed and held ... you'd want another resistor (1k or so) to discharge the cap when the button isn't pressed.
 
Using a 10k resistor and a 100uf CAP, I get a 2-second charge time from 0 - 4V ... so, theoretically, using a ST input, you shouldn't get a HIGH for about 2 seconds after the switch is pressed and held ... you'd want another resistor (1k or so) to discharge the cap when the button isn't pressed.

I do love a good hardware solution alternative. Full marks, bpowell!

The only thing better would include a 555 timer. :)
 
I wrote the following program several years ago as an exercise to demonstrate what can be done with a single momentary switch, three LEDs and a piezo sounder. The originally hardware was the AXE092 Schools Experimenter board made by RevEd. I believe the AXE092 kit has been discontinued but the hardware can be configured on a breadboard using an 08M or 08M2.
Rich (BB code):
' Demonstration of open-loop style of programming, allowing multiple 'tasks' to be handled
' Also demonstrates the Max command: sometimes difficult for the beginner to understand.
'
'What it does:      (Exercise: draw a flow diagram - use a large sheet of paper)
' * At startup, emits a musical trill sound
' * While turned on but not in use, emits a 'tick' sound every few seconds.
' * The pushbutton switch, if pressed momentarily, will toggle the Yellow LED on and off.
' * If the switch is held a little longer (>400mS), the green LED flashes quickly: this
'    indicates that an intermediate time has expired, affecting how the Yellow LED behaves.
' *   Then, if the switch is released, the yellow LED flashes.
' *   Pressing the switch again briefly turns the Yellow LED off.
' * If the switch is held for an extended time (>4 seconds), the Red LED is turned on.
'
'Tested on PICAXE 08M firmware 9.1  (AXE-092 Board)
' Revision History
' 30-Nov-2006  80 bytes Written by inglewoodpete
' 06-Apr-2011  80 bytes Revised presentation, renamed variables/constants
' 07-Oct-2011  94 bytes Added timer limit indication (Red and Green LEDs)
' 19-Feb-2011 120 bytes Added startup trill and battery-saving 'reminder' tick
'
'***** Definitions *****
'
#PICAXE 08M
'      Variables - byte variables are prefixed with 'b'; words with 'w'
'
Symbol bSwTime    = b0
Symbol bLEDState  = b1      '0 = off, 1 = on, 2 to 255 = flash
Symbol bReminder  = b2      'Battery saver: reminder that the AXE092 is turned on!
'
'      Hardware  - outputs are prefixed with 'o'; inputs with 'i'
'
Symbol oRedLED    = 0      'Indicator: Timer has maxed out
Symbol oYellowLED = 1      'Indicator: Result
Symbol oGreenLED  = 2      'Indicator: Input Timer
Symbol oBeeper    = 2      '   -pin 2 is shared with piezo 'alarm'
Symbol iSwitch    = Pin3   'Input
'
'       Constants - constant definitions are prefixed with a 'c'
'
'      Logical Conditions
Symbol cActive    = 1      'Can be 0 or 1
'      Counter Values
Symbol cLongPress = 40     'Discrimination between short and log press
Symbol cHalfTime  = 10     'LED Hi-Lo transition
Symbol cFullTime  = 20     'LED Lo-Hi. Must not be > 254
Symbol cNoteTime  = 7      'Duration of startup notes
Symbol cGap       = 4      'Duration of gaps between notes
'
'***** End Definitions *****
'************************************************************************
'*****  Begin Program  *****
'
'***** Initialisation  *****
Init:
   Sound oBeeper, (50,cNoteTime,0,cGap,70,cNoteTime,0,cGap,90,cNoteTime,0,cGap,120,cNoteTime)
   '
'***** Begin Main Loop *****
   Do
      bSwTime = 0
      Low oRedLED
      Low oGreenLed
      'This Do loop will be bypassed if switch not pressed
      Do While iSwitch = cActive   'Determine the time that the switch is pressed
         Pause 10                  'Only ever use small delays
         bSwTime = bSwTime Max 254 + 1   'Max prevents overflow
         If bSwTime = 255 Then     'Indicate that timer has maxed out
            High oRedLED
         ElseIf bSwTime > cLongPress Then
            Toggle oGreenLed
         EndIf
         Gosub HandleFlash         'Maintain flashing if required while button held down
      Loop                         'Remain in loop while switch pressed
      Pause 10                     'Only ever use small delays
      'Process any switch press
      If bSwTime > cLongPress Then
         'Start LED flashing
         bLEDState = 2
         High oYellowLED
      ElseIf bSwTime > 0 Then      'Short press
         'Turn LED On or Off  (Off also stops flashing)
         If bLEDState = 0 Then     'Off: so turn LED on
            bLEDState = 1
            High oYellowLED
         Else                      'Turn off
            bLEDState = 0
            Low oYellowLED
         Endif
      Else   'Ie. bSwTime = 0      for when the button is not pressed
         Inc bReminder             'The 'Reminder' counts from 0 to 255 each loop
         If bReminder = 0 Then     ' then the counter "rolls over" to zero
            PulsOut oBeeper, 10    'When bReminder = 0, output a "tick" sound
         EndIf
      EndIf
      Gosub HandleFlash
   Loop
'
'***** Subroutines *****
'
HandleFlash: If bLEDState > 1 Then
                'Flash control required only for range 2 to 255
                Select Case bLEDState
                Case > cFullTime
                   'Cycle complete: Flash the LED back on again
                   High oYellowLED
                   bLEDState = 2   'Reset counter to minimum
                Case > cHalfTime
                   'Half time of the flash cycle: reset the LED
                   Low oYellowLED
                EndSelect
                Inc bLEDState
             EndIf
             Return
'
'***** End Of Program *****
 

Attachments

  • AXE-092 LoRes.jpg
    AXE-092 LoRes.jpg
    415.8 KB · Views: 16
Browsing a magician's forum, I found an even more impressive version (sorry, didn't save the link). The magician begins with turning on the blue light and his patter is "The colors are the souls of the lights..." At which point he removes the blue cover from the handle of that switch and keeps talking until the blue light goes out in about 5 seconds.

It's all on a thin double-layer PCB with tracks large enough to be easily visible on both sides of the board. Power is from a coin cell (2032?). I see that PCB as thick enough to have another layer, possibly two, and the holder for the coin cell is large enough to hide an impressively powerful SMD CPU - and maybe a smaller coin cell battery. Any tracks in the inner layer(s) could be hidden by the obvious large tracks on the top and bottom layers

I can think of at least two ways for the light to be triggered to die when the switch handle's slip-on cover is removed. Even an 8-bit CPU with enough EPROM would be fast enough to keep up with user actions and have useful bits for the magician such as "Touch the sockets for bulbs 1 and 3 simultaneously for 10 seconds to turn Scramble mode on or off." With "Scramble" being the "move any bulb" and the color is/is not controlled by the matching switch.

I may have an unfair advantage in having spent some of my teenage years working in an uncle's magic and hobby shop. I knew how to do all of the pocket magic of the day - have to be able to demonstrate to the buying public ;-) And I was exposed to some stage magic, as my uncle was also a stage magician - complete with red and gold silk robes, black magic wand and his name of "Foo Ling Yu". I remember one act where he discovered that he couldn't use his wife as his assistant - her reflexes just could NOT pull the trigger on the blank-only pistol at the right time (key word in the patter) to cover the small amount of mechanical noise the cage mechanism made.
 
Back
Top