Pushbutton Event Handler: Part 4

Pushbutton Handler

The handler routine is started by calling PushButton_Init function. This function registers PushButton_Routine at the end as a callback of the software timer.

   35 void PushButton_Init(uint8_t mask)
   36 {
   37     int i ;
   38 
   39     // clear data
   40     pp.old_state = pp.new_state = 0;
   41     pp.mask = mask;
   42     pp.mode = 0;
   43     pp.flag = false;
   44 
   45     // clear log
   46     for(i = 0; i < 8; i++)
   47     {
   48         PushButton_ClearLog(i);
   49     }
   50 
   51     // register pushbutton main routine
   52     UsrTimer_Set(PUSHBTN_TMR_PERIOD, 0, PushButton_Routine);
   53 }

The PushButton_Routine is then called at every 80msec and tracks the button state. If the button state is ON for at least three consecutive polling (80 x 3 = 240msec) then it declares CLICK by posting an event. These timing can be set to fit the bouncing characteristic of the mechanical switch.

   71 /// PushButton_Routine timer period in msec
   72 #define PUSHBTN_TMR_PERIOD      80
   73 /// Criteria for determination of short click and long click
   74 #define PUSHBTN_TO_SHORT        3       // 3 * PUSHBTN_TMR_PERIOD
   75 #define PUSHBTN_TO_LONG         10      // 10 * PUSHBTN_TMR_PERIOD
   76 #define PUSHBTN_TO_MAX          255     // maximum duration count

The PushButton_Routine, distinguishes single, double, triple click and long click (push and hold) and generates event accordingly, which in turn collected by the event handler in the main loop.

You can also change the mode from click detection to up/down detection, in which event is constantly generated when you hold the button down.

(source code)

3 thoughts on “Pushbutton Event Handler: Part 4

  1. Thank you for your great work. I’m using your code successfully for up to 8 buttons now.
    I only have a problem with PushButton_SetMode. After activating PUSHBTN_MODE_UDOWN, it seams this mode is just working for the first button (first bit of mask) and has no funktion for thos other buttons (bits of mask).
    Have you may still noticed the same problem, or can let me know how to fix it?

    Like

      • thanks or our fast reply!
        well I thought I set the flag… my demo looks similar like yours, just with CAN instead of UART ->

        if(Evt_DeQueue(event))
        {
        switch(event[0])
        {
        // pushbutton event ================================================
        // event[1]: button id
        // event[2]: PBTN_SCLK, _DCLK, _TCLK, _LCLK, _DOWN, _ENDN
        case EVT_PBTN_INPUT:

        if(event[2] == PBTN_SCLK)
        {
        CAN_Tx(“B%d: single click”,event[1]);
        }
        else if(event[2] == PBTN_LCLK)
        {
        CAN_Tx(“B%d: long click”,event[1]);
        }
        else if(event[2] == PBTN_DCLK)
        {
        CAN_Tx(“B%d: double click”,event[1]);
        }
        else if(event[2] == PBTN_TCLK)
        {
        CAN_Tx(“B%d: triple click”,event[1]);

        PushButton_SetMode(PUSHBTN_MODE_UDOWN, true);
        CAN_Tx(“Switch to up-down mode”);
        }
        else if(event[2] == PBTN_DOWN)
        {
        CAN_Tx(“B%d: is being pressed”,event[1]);
        }
        else if(event[2] == PBTN_ENDN)
        {
        CAN_Tx(“B%d: has been released”,event[1]);
        PushButton_SetMode(PUSHBTN_MODE_CLICK, true);
        CAN_Tx(“Switch to click mode”);
        }
        break;
        }
        }
        else
        {
        // delay here is recommended not to call Evt_DeQueue too frequently
        HAL_Delay(10);
        }

        Can you please send me an example how it should work?

        Great to know you are still working on that code. I would be really interested into your mentioned rev.. Hope you will find time for it soon ;).

        Like

Leave a comment