Implementation of a button class and test program

Committer:
JMF
Date:
Fri Sep 07 20:54:25 2018 +0000
Revision:
1:c668e9604e63
Parent:
0:377a50b631cf
Added a destructor to the class.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 1:c668e9604e63 1 /**
JMF 1:c668e9604e63 2 * copyright (c) 2018, James Flynn
JMF 1:c668e9604e63 3 * SPDX-License-Identifier: MIT
JMF 1:c668e9604e63 4 */
JMF 1:c668e9604e63 5
JMF 1:c668e9604e63 6 /**
JMF 1:c668e9604e63 7 * @file button.hpp
JMF 1:c668e9604e63 8 * @brief A small BUTTON class for detecting & debouncing button preesses
JMF 1:c668e9604e63 9 *
JMF 1:c668e9604e63 10 * @author James Flynn
JMF 1:c668e9604e63 11 *
JMF 1:c668e9604e63 12 * @date 24-Aug-2018
JMF 1:c668e9604e63 13 */
JMF 0:377a50b631cf 14
JMF 0:377a50b631cf 15 #include "mbed.h"
JMF 0:377a50b631cf 16
JMF 1:c668e9604e63 17 #define BUTTON_DEBOUNCE 20 //specify the number of msec to debounce
JMF 0:377a50b631cf 18
JMF 0:377a50b631cf 19 class Button {
JMF 0:377a50b631cf 20 protected:
JMF 0:377a50b631cf 21 InterruptIn user_button;
JMF 1:c668e9604e63 22 void (*br_cb)(int); //button release callback
JMF 1:c668e9604e63 23 void (*bp_cb)(void); //button press callback
JMF 0:377a50b631cf 24
JMF 1:c668e9604e63 25 Thread *button_thread;
JMF 0:377a50b631cf 26 void button_monitor_task(void);
JMF 0:377a50b631cf 27 EventQueue button_queue;
JMF 1:c668e9604e63 28 uint64_t bp_time, bp_duration; //button press start time and button press duration
JMF 1:c668e9604e63 29 int button_pressed; //counts the number of times the button has been pressed
JMF 0:377a50b631cf 30
JMF 0:377a50b631cf 31 void button_press_handler(void) {
JMF 0:377a50b631cf 32 if( (rtos::Kernel::get_ms_count() - bp_time) < BUTTON_DEBOUNCE)
JMF 0:377a50b631cf 33 return;
JMF 0:377a50b631cf 34 bp_time = rtos::Kernel::get_ms_count();
JMF 0:377a50b631cf 35 if( bp_cb )
JMF 0:377a50b631cf 36 bp_cb();
JMF 0:377a50b631cf 37 }
JMF 0:377a50b631cf 38
JMF 0:377a50b631cf 39 void button_release_handler(void) {
JMF 0:377a50b631cf 40 uint64_t tmp = rtos::Kernel::get_ms_count() - bp_time;
JMF 0:377a50b631cf 41 if( tmp > BUTTON_DEBOUNCE ) {
JMF 0:377a50b631cf 42 bp_duration = tmp;
JMF 0:377a50b631cf 43 button_pressed++;
JMF 0:377a50b631cf 44 if( br_cb )
JMF 0:377a50b631cf 45 br_cb(bp_duration);
JMF 0:377a50b631cf 46 }
JMF 0:377a50b631cf 47 }
JMF 0:377a50b631cf 48
JMF 0:377a50b631cf 49 public:
JMF 0:377a50b631cf 50 enum State { ActiveHigh = 0, ActiveLow };
JMF 0:377a50b631cf 51
JMF 0:377a50b631cf 52 Button(PinName p, State s, void (*cb)(int)=NULL) :
JMF 0:377a50b631cf 53 user_button(p),
JMF 0:377a50b631cf 54 br_cb(cb),
JMF 0:377a50b631cf 55 bp_cb(NULL),
JMF 0:377a50b631cf 56 bp_time(0),
JMF 0:377a50b631cf 57 bp_duration(0),
JMF 0:377a50b631cf 58 button_pressed(0)
JMF 0:377a50b631cf 59 {
JMF 1:c668e9604e63 60 // The user button is setup for the edge to generate an interrupt.
JMF 1:c668e9604e63 61 // The release is caught an event queue callback
JMF 1:c668e9604e63 62 button_thread=new Thread(osPriorityNormal,256,NULL,"button_thread");
JMF 1:c668e9604e63 63 button_thread->start(callback(&button_queue, &EventQueue::dispatch_forever));
JMF 0:377a50b631cf 64 if( s == ActiveHigh ) {
JMF 0:377a50b631cf 65 user_button.rise( Callback<void()>(this, &Button::button_press_handler) );
JMF 0:377a50b631cf 66 user_button.fall( button_queue.event( Callback<void()>(this, &Button::button_release_handler)));
JMF 0:377a50b631cf 67 }
JMF 0:377a50b631cf 68 else{
JMF 0:377a50b631cf 69 user_button.fall( Callback<void()>(this, &Button::button_press_handler) );
JMF 0:377a50b631cf 70 user_button.rise(button_queue.event(Callback<void()>(this, &Button::button_release_handler)));
JMF 0:377a50b631cf 71 }
JMF 0:377a50b631cf 72 }
JMF 0:377a50b631cf 73
JMF 1:c668e9604e63 74 ~Button() {
JMF 1:c668e9604e63 75 button_thread->terminate();
JMF 1:c668e9604e63 76 delete button_thread;
JMF 1:c668e9604e63 77 }
JMF 1:c668e9604e63 78
JMF 1:c668e9604e63 79 // will return the number of times the button has been pressed (if it was pressed > 1 time before checked)
JMF 1:c668e9604e63 80 // and returns the duration of the last button press in duration
JMF 0:377a50b631cf 81 int chkButton_press(int *duration) {
JMF 0:377a50b631cf 82 int bp = button_pressed;
JMF 0:377a50b631cf 83
JMF 0:377a50b631cf 84 if( button_pressed ) {
JMF 0:377a50b631cf 85 *duration = bp_duration;
JMF 0:377a50b631cf 86 bp_duration = 0;
JMF 0:377a50b631cf 87 button_pressed = 0;
JMF 0:377a50b631cf 88 }
JMF 0:377a50b631cf 89 return bp;
JMF 0:377a50b631cf 90 }
JMF 0:377a50b631cf 91
JMF 1:c668e9604e63 92 //allows the user to set a callback for a button press in
JMF 0:377a50b631cf 93 void setButton_press_cb( void (*buttonpresscb)(void) ) {
JMF 0:377a50b631cf 94 bp_cb = buttonpresscb;
JMF 0:377a50b631cf 95 }
JMF 0:377a50b631cf 96 };
JMF 1:c668e9604e63 97