detecting 3 push of a button

Discussion in 'Embedded Systems and Microcontrollers' started by bug13, Aug 10, 2016.

  1. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Hi guys

    What is the best not blocking way to detect a 3 pushes of a button. I am thinking this:

    Code (Text):
    1.  
    2. uint16_t timeArray[3];
    3.  
    4. btnThreePush()
    5. {
    6.   if (btnRead()) timeArray[i++] = ticksNow;
    7. }
    8.  
    9. // main loop
    10. while(1)
    11. {
    12.   diff = getDifferent(timeArray);
    13.   if (diff > some_time)
    14.   {
    15.      // do something with 3 push
    16.   }
    17. }
    18.  
    Any flaws? or any better way to do it? Thanks guys
     
  2. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,906
    2,158
    It depends on whether it's three pushes ever or three pushes over a timed period (maybe starting with the first push).
     
  3. SLK001

    Well-Known Member

    Nov 29, 2011
    810
    224
    How are you debouncing the button pushes?
     
  4. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Say over 1 second
     
  5. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Here is how I usually do it, these codes are usually in my timer interrupt, struct inputs is global variable
    Code (Text):
    1.                 if (!SET6_PORTbit)    // if low
    2.                 {
    3.                     if (db < INPUT_BTN_DEBOUNCE)
    4.                         db++;
    5.                     else
    6.                         inputs.set6 = 1;
    7.                 }
    8.                 else
    9.                 {
    10.                     if (db != 0)
    11.                         db--;
    12.                     else
    13.                         inputs.set6 = 0;
    14.                 }
     
  6. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,906
    2,158
    I might put the three button decision logic in btnThreePush() instead of the while loop (diff = ...) if possible as it wastes cpu cycles computing an event (3 presses timed or not) that can be detected and flagged with a variable or status check function for the while loop when the button is pressed in btnThreePush().
     
    bug13 likes this.
  7. xainnasir

    New Member

    Nov 8, 2012
    26
    2
    you need to use button debounce code. Code is as follows for single click check so you have to repeat it for three times:

    Code (Text):
    1. int reading = digitalRead(buttonPin);
    2.   if (reading != lastButtonState) {
    3.     lastDebounceTime = millis();
    4.   }
    5.  
    6.   if ((millis() - lastDebounceTime) > debounceDelay) {
    7.     if (reading != buttonState) {
    8.       buttonState = reading;
    9.  
    10.       if (buttonState == HIGH) {
    11.         ledState = !ledState;
    12.       }
    13.     }
    14.   }
     
  8. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Sorry for the confusion, my btnRead() is already deal with debounce.
     
  9. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,790
    827
  10. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    that's the same principle in my code in post #5, but pic doesn't usually have as many IO interrupt AVR, so I did my scan in a timer interrupt.
     
  11. ian field

    Distinguished Member

    Oct 27, 2012
    4,413
    782
    The favourite hardware way is a SPDT pushbutton and a pair of 2 input inverting gates wired as a bistable.
     
  12. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    OK, but how does it denounce? My debounce code is tucked away in a timer interrupt that fires every 25 ms and can detect stale button presses.

    To get three pulses out of this I would look at a scheme such as this: on the first valid push I would set a count variable to 1 and also start a timing variable. On subsequent checks of the button for denounce I would check the timing variable; should it exceed 1 second I reset the count variable, and if it also detects another button push then increment the count variable. You may want to also reset the timing variable too so your main code has enough time (another second?) to detect a count of three.

    This way the same way you read buttons you can also check for a count of the pressings.
     
    Last edited: Aug 21, 2016
  13. dannyf

    Well-Known Member

    Sep 13, 2015
    1,767
    357
    that's the right approach (to put debouncing in the lower level routines).

    I would use a state machine to detect key presses. For example, you receive consecutive NO_KEYPRESS from your lower level routine, you consider a key press has been terminated.

    Otherwise, if you receive KEY_PRESSED three times, you consider that to be a valid 3-press instance.
     
Loading...