This might be a good candidate for switch state logic. Remember that you can detect the following states when using a switch state latch;
(1) new = 1, old = 0 --> new press
(2) new = 0, old = 1 --> new release
(3) new = 1, old = 1 --> still pressed
(4) new = 0, old = 0 --> still released
Start a 3-second timer when you detect the "new press" state. If the timer times out while the switch is held pressed then set a "long" flag. If you detect a "new release" state before the timer times out then set a "short" flag.

Another C example (sorry Gentlemen) based on a 50-msec loop time (sample/debounce/timer interval) that generates a single 'beep' on a "new press" and a double beep at the 3-second time-out;
Code:
;
; unsigned char swnew = 0; // fresh switch sample
; unsigned char swold = 0; // switch state latch
; unsigned char swtmr = 0; // 3-second switch timer
;
; #define newpress swnew.0 == 1 && swold.0 == 0
; #define newrelease swnew.0 == 0 && swold.0 == 1
;
; while(1) //
; { delay_ms(50); // 50-msec sample/debounce interval
; swnew = ~gpio; // sample active lo switches
; if(newpress) // if "new press"
; { swold.0 = 1; // update switch state latch
; swtmr = 3000/50; // start 3 second timer
; beep1(); // send "new press" beep
; }
; if(newrelease) // if "new release"
; { swold.0 = 0; // update switch state latch
; if(swtmr) // if 'short' press
; swtmr = 0; // turn off switch timer
; sflag = 1; // set "short" flag
; }
; if(swtmr) // if switch timer running
; { swtmr--; // decrement it and
; if(swtmr == 0) // if 3 second timeout
; { beep2(); // send double beep and
; lflag = 1; // set "long" flag
; }
; }
; if(sflag) // if "short" press
; { //
; } //
; if(lflag) // if "long" press
; { //
; } //
; } //
;
Add a little more logic for safety (and outputs) and you've got one of those novelty lighted single switch ignition systems (I don't endorse or recommend anyone trying this as it's just too dangerous, IMO);

Code:
; unsigned char swnew = 0; // fresh switch sample
; unsigned char swold = 0; // switch state latch
; unsigned char swtmr = 0; // 1-second switch timer
;
; #define ignition gpio.0 // GP0, active hi relay output
; #define starter gpio.1 // GP1, active hi relay output
; #define running swold.0 // flag
;
; #define newpress swnew.3 == 1 && swold.3 == 0
; #define newrelease swnew.3 == 0 && swold.3 == 1
; #define allowstart ignition == 1 && running == 0
;
; while(1)
; { delay_ms(32); // 32-msec debounce intervals
; swnew = ~gpio; // sample active lo switch GP3
; if(newpress) // if "new press"
; { swold.3 = 1; // update switch state latch
; swtmr = 1000/32; // start 1 second timer
; beep1(); // send a single beep
; }
; if(newrelease) // if "new release"
; { swold.3 = 0; // update switch state latch
; starter = 0; // turn GP1 "starter" off
; if(swtmr) // if "short" press
; { ignition ^= 1; // toggle GP0 "ignition"
; swtmr = 0; // turn 1 second timer off
; running = 0; // clear "running" flag
; } //
; }
; if(swtmr) // if 1 second timer running
; { swtmr--; // decrement it
; if(swtmr == 0) // if timed out
; { beep2(); // send a double beep
; if(allowstart) // if start allowed
; { running = 1; // set "running" flag
; starter = 1; // turn GP1 "starter" on
; } //
; } //
; }
; }
;
Bookmarks