Implementation of a button class and test program
Button.hpp
- Committer:
- JMF
- Date:
- 2018-09-07
- Revision:
- 1:c668e9604e63
- Parent:
- 0:377a50b631cf
File content as of revision 1:c668e9604e63:
/**
* copyright (c) 2018, James Flynn
* SPDX-License-Identifier: MIT
*/
/**
* @file button.hpp
* @brief A small BUTTON class for detecting & debouncing button preesses
*
* @author James Flynn
*
* @date 24-Aug-2018
*/
#include "mbed.h"
#define BUTTON_DEBOUNCE 20 //specify the number of msec to debounce
class Button {
protected:
InterruptIn user_button;
void (*br_cb)(int); //button release callback
void (*bp_cb)(void); //button press callback
Thread *button_thread;
void button_monitor_task(void);
EventQueue button_queue;
uint64_t bp_time, bp_duration; //button press start time and button press duration
int button_pressed; //counts the number of times the button has been pressed
void button_press_handler(void) {
if( (rtos::Kernel::get_ms_count() - bp_time) < BUTTON_DEBOUNCE)
return;
bp_time = rtos::Kernel::get_ms_count();
if( bp_cb )
bp_cb();
}
void button_release_handler(void) {
uint64_t tmp = rtos::Kernel::get_ms_count() - bp_time;
if( tmp > BUTTON_DEBOUNCE ) {
bp_duration = tmp;
button_pressed++;
if( br_cb )
br_cb(bp_duration);
}
}
public:
enum State { ActiveHigh = 0, ActiveLow };
Button(PinName p, State s, void (*cb)(int)=NULL) :
user_button(p),
br_cb(cb),
bp_cb(NULL),
bp_time(0),
bp_duration(0),
button_pressed(0)
{
// The user button is setup for the edge to generate an interrupt.
// The release is caught an event queue callback
button_thread=new Thread(osPriorityNormal,256,NULL,"button_thread");
button_thread->start(callback(&button_queue, &EventQueue::dispatch_forever));
if( s == ActiveHigh ) {
user_button.rise( Callback<void()>(this, &Button::button_press_handler) );
user_button.fall( button_queue.event( Callback<void()>(this, &Button::button_release_handler)));
}
else{
user_button.fall( Callback<void()>(this, &Button::button_press_handler) );
user_button.rise(button_queue.event(Callback<void()>(this, &Button::button_release_handler)));
}
}
~Button() {
button_thread->terminate();
delete button_thread;
}
// will return the number of times the button has been pressed (if it was pressed > 1 time before checked)
// and returns the duration of the last button press in duration
int chkButton_press(int *duration) {
int bp = button_pressed;
if( button_pressed ) {
*duration = bp_duration;
bp_duration = 0;
button_pressed = 0;
}
return bp;
}
//allows the user to set a callback for a button press in
void setButton_press_cb( void (*buttonpresscb)(void) ) {
bp_cb = buttonpresscb;
}
};