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.

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?
LikeLike
Hi Snash,
Did you set the UDOWN flag for each button? By the way, revision is coming. I will update the repo as soon as I find some time to do it.
LikeLike
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 ;).
LikeLike