// Simple button/swipe library for FRDM-KL25Z // AI Williams -- The Touch of a Button // Dr.Dobb's Journal // http://www.drdobbs.com/embedded-systems/the-touch-of-a-button/240169431

Dependencies:   mbed tsi_sensor

Simple button/swipe library for FRDM-KL25Z by AI Williams: The Touch of a Button Dr.Dobb's Journal http://www.drdobbs.com/embedded-systems/the-touch-of-a-button/240169431

Revision:
0:de427e23a099
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Nov 03 12:52:59 2015 +0000
@@ -0,0 +1,100 @@
+#include "mbed.h"
+#include "tsi_sensor.h"
+ 
+// Simple button/swipe library for FRDM-KL25Z
+// AI Williams -- The Touch of a Button
+// Dr.Dobb's Journal
+// http://www.drdobbs.com/embedded-systems/the-touch-of-a-button/240169431 
+ 
+/* This defines will be replaced by PinNames soon */
+#if defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
+  #define ELEC0 9
+  #define ELEC1 10
+#elif defined (TARGET_KL05Z)
+  #define ELEC0 9
+  #define ELEC1 8
+#else
+  #error TARGET NOT DEFINED
+#endif
+ 
+// Define the "zones" considered to be buttons
+// 4 is about the limit and 3 might be even better
+// You could also equal space them automatically pretty easily
+// (e.g., specify 25% and fill in BTNMAX programmatically 
+float BTNMAX[]= {0.25, 0.50, 0.75, 1.00 };
+#define SWIPETIME .350  // seconds to wait before sensing a button push or swipe
+#define SWIPE_R 256     // virtual button code for right swipe
+#define SWIPE_L 512     // virtual button code for left swipe
+ 
+Serial pc(USBTX, USBRX); // tx, rx  for debugging
+TSIAnalogSlider tsi(ELEC0, ELEC1, 40);  // The Analog slider
+Timeout scan;
+ 
+ 
+int candidate=-1;     // possible button push (-1 is none)
+volatile int realbtn=-1;  // actual button push (-1 is none)
+volatile int hold=0;   // waiting for button release when 1
+ 
+// internal function to get raw button state
+int getrawbtn()
+{
+    float v=tsi.readPercentage();  // read slider
+    if (v==0.0) return -1;         // no button at all
+    for (int i=0;i<sizeof(BTNMAX)/sizeof(BTNMAX[0]);i++)   // classify by zone
+        if (v<BTNMAX[i]) return i;
+    return -1;  // what?
+}
+ 
+// This is called by the timeout to 
+// either see there is no swipe
+// see that there is a swipe
+// or see that there is a button release
+void checkbtn(void)
+{
+    int newbtn=getrawbtn();
+    if (hold!=0 && newbtn==-1)  // wait for key release
+    {
+        hold=0;   // released so
+        return;  // don't reschedule me
+    }
+    // reschedule us for next swipetime
+    scan.attach(checkbtn,SWIPETIME);
+    if (hold) return;  // still waiting for release
+    hold=1;            // we will be waiting for release from now on
+    if (newbtn==-1||newbtn==candidate)   // if no touch or button is the same, the candidate is the button
+    {
+        realbtn=candidate; 
+        return;
+    }
+    // Otherwise we are swiping either left or right
+    if (candidate<newbtn) realbtn=SWIPE_L; else realbtn=SWIPE_R;
+    return;
+}
+ 
+// This is the main API
+// Call it to get a button code (0-3 or 256 or 512)
+// You can block or not (default is to block)
+int getbtn(bool kwait=true)
+{
+    while (hold)  // if holding, either wait or return
+    {
+        if (!kwait) return -1;
+    }
+    realbtn=-1;    // mark that we don't know
+    do
+    {
+        candidate=getrawbtn();   // get a candidate (or return if not waiting)
+    } while (candidate==-1 || !kwait);
+    if (candidate==-1) return -1;
+    scan.attach(checkbtn,SWIPETIME);  // schedule the checkbtn routine
+    while (realbtn==-1);    // wait for realbtn to get set
+    return realbtn;   // return it
+}
+ 
+// Simple test program
+int main(void) {
+     
+    while (true) {
+       pc.printf("Button %d\r\n",getbtn());
+    }
+}
\ No newline at end of file