Implementation of a button class and test program

Files at this revision

API Documentation at this revision

Comitter:
JMF
Date:
Thu Aug 30 00:35:30 2018 +0000
Child:
1:c668e9604e63
Commit message:
button class example

Changed in this revision

Button.hpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /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