Jim Flynn
/
button_class_and_test
Implementation of a button class and test program
Revision 0:377a50b631cf, committed 2018-08-30
- Comitter:
- JMF
- Date:
- Thu Aug 30 00:35:30 2018 +0000
- Child:
- 1:c668e9604e63
- Commit message:
- button class example
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Button.hpp Thu Aug 30 00:35:30 2018 +0000 @@ -0,0 +1,75 @@ +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include "mbed.h" + +#define BUTTON_DEBOUNCE 20 + +class Button { + protected: + InterruptIn user_button; + void (*br_cb)(int); + void (*bp_cb)(void); + + Thread button_thread; + void button_monitor_task(void); + EventQueue button_queue; + uint64_t bp_time, bp_duration; + int button_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 active low so setup the falling edge to generate + // an interrupt. Catch the release with an event queue event + 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))); + } + } + + int chkButton_press(int *duration) { + int bp = button_pressed; + + if( button_pressed ) { + *duration = bp_duration; + bp_duration = 0; + button_pressed = 0; + } + return bp; + } + + void setButton_press_cb( void (*buttonpresscb)(void) ) { + bp_cb = buttonpresscb; + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Aug 30 00:35:30 2018 +0000 @@ -0,0 +1,43 @@ +#include "mbed.h" +#include "Button.hpp" + +void br_callback(int dur) +{ + printf("\r\n!! button RELEASE called, press time: %d msec\r\n", dur); +} + +void bp_callback(void) +{ + printf("\r\n!! button PRESS called\r\n"); +} + +int main() { + int k, dur; + Button* button_ptr; + + printf("Testing button class\r\n"); + printf("Test Standard polling type implementation\r\n"); + button_ptr = new Button(USER_BUTTON, Button::ActiveHigh); + while( (k=button_ptr->chkButton_press(&dur)) == 0 ) + /* wait */; + printf(">Button pressed %d times, last was %d msec\r\n",k,dur); + delete button_ptr; + + printf("\nTest with Release callback\r\n"); + button_ptr = new Button(USER_BUTTON, Button::ActiveHigh, br_callback); + while( (k=button_ptr->chkButton_press(&dur)) == 0 ) + /* wait */; + printf(">Button pressed %d times, last was %d msec\r\n",k,dur); + delete button_ptr; + + printf("\nTest with Press & Release callback\r\n"); + button_ptr = new Button(USER_BUTTON, Button::ActiveHigh, br_callback); + button_ptr->setButton_press_cb(bp_callback); + while( (k=button_ptr->chkButton_press(&dur)) == 0 ) + /* wait */; + printf(">Button pressed %d times, last was %d msec\r\n",k,dur); + while (1) { + wait(.5); + } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Thu Aug 30 00:35:30 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#f8b140f8d7cb226e41486c5df66ac4f3ce699219