// 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

Committer:
icserny
Date:
Tue Nov 03 12:52:59 2015 +0000
Revision:
0:de427e23a099
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
icserny 0:de427e23a099 1 #include "mbed.h"
icserny 0:de427e23a099 2 #include "tsi_sensor.h"
icserny 0:de427e23a099 3
icserny 0:de427e23a099 4 // Simple button/swipe library for FRDM-KL25Z
icserny 0:de427e23a099 5 // AI Williams -- The Touch of a Button
icserny 0:de427e23a099 6 // Dr.Dobb's Journal
icserny 0:de427e23a099 7 // http://www.drdobbs.com/embedded-systems/the-touch-of-a-button/240169431
icserny 0:de427e23a099 8
icserny 0:de427e23a099 9 /* This defines will be replaced by PinNames soon */
icserny 0:de427e23a099 10 #if defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
icserny 0:de427e23a099 11 #define ELEC0 9
icserny 0:de427e23a099 12 #define ELEC1 10
icserny 0:de427e23a099 13 #elif defined (TARGET_KL05Z)
icserny 0:de427e23a099 14 #define ELEC0 9
icserny 0:de427e23a099 15 #define ELEC1 8
icserny 0:de427e23a099 16 #else
icserny 0:de427e23a099 17 #error TARGET NOT DEFINED
icserny 0:de427e23a099 18 #endif
icserny 0:de427e23a099 19
icserny 0:de427e23a099 20 // Define the "zones" considered to be buttons
icserny 0:de427e23a099 21 // 4 is about the limit and 3 might be even better
icserny 0:de427e23a099 22 // You could also equal space them automatically pretty easily
icserny 0:de427e23a099 23 // (e.g., specify 25% and fill in BTNMAX programmatically
icserny 0:de427e23a099 24 float BTNMAX[]= {0.25, 0.50, 0.75, 1.00 };
icserny 0:de427e23a099 25 #define SWIPETIME .350 // seconds to wait before sensing a button push or swipe
icserny 0:de427e23a099 26 #define SWIPE_R 256 // virtual button code for right swipe
icserny 0:de427e23a099 27 #define SWIPE_L 512 // virtual button code for left swipe
icserny 0:de427e23a099 28
icserny 0:de427e23a099 29 Serial pc(USBTX, USBRX); // tx, rx for debugging
icserny 0:de427e23a099 30 TSIAnalogSlider tsi(ELEC0, ELEC1, 40); // The Analog slider
icserny 0:de427e23a099 31 Timeout scan;
icserny 0:de427e23a099 32
icserny 0:de427e23a099 33
icserny 0:de427e23a099 34 int candidate=-1; // possible button push (-1 is none)
icserny 0:de427e23a099 35 volatile int realbtn=-1; // actual button push (-1 is none)
icserny 0:de427e23a099 36 volatile int hold=0; // waiting for button release when 1
icserny 0:de427e23a099 37
icserny 0:de427e23a099 38 // internal function to get raw button state
icserny 0:de427e23a099 39 int getrawbtn()
icserny 0:de427e23a099 40 {
icserny 0:de427e23a099 41 float v=tsi.readPercentage(); // read slider
icserny 0:de427e23a099 42 if (v==0.0) return -1; // no button at all
icserny 0:de427e23a099 43 for (int i=0;i<sizeof(BTNMAX)/sizeof(BTNMAX[0]);i++) // classify by zone
icserny 0:de427e23a099 44 if (v<BTNMAX[i]) return i;
icserny 0:de427e23a099 45 return -1; // what?
icserny 0:de427e23a099 46 }
icserny 0:de427e23a099 47
icserny 0:de427e23a099 48 // This is called by the timeout to
icserny 0:de427e23a099 49 // either see there is no swipe
icserny 0:de427e23a099 50 // see that there is a swipe
icserny 0:de427e23a099 51 // or see that there is a button release
icserny 0:de427e23a099 52 void checkbtn(void)
icserny 0:de427e23a099 53 {
icserny 0:de427e23a099 54 int newbtn=getrawbtn();
icserny 0:de427e23a099 55 if (hold!=0 && newbtn==-1) // wait for key release
icserny 0:de427e23a099 56 {
icserny 0:de427e23a099 57 hold=0; // released so
icserny 0:de427e23a099 58 return; // don't reschedule me
icserny 0:de427e23a099 59 }
icserny 0:de427e23a099 60 // reschedule us for next swipetime
icserny 0:de427e23a099 61 scan.attach(checkbtn,SWIPETIME);
icserny 0:de427e23a099 62 if (hold) return; // still waiting for release
icserny 0:de427e23a099 63 hold=1; // we will be waiting for release from now on
icserny 0:de427e23a099 64 if (newbtn==-1||newbtn==candidate) // if no touch or button is the same, the candidate is the button
icserny 0:de427e23a099 65 {
icserny 0:de427e23a099 66 realbtn=candidate;
icserny 0:de427e23a099 67 return;
icserny 0:de427e23a099 68 }
icserny 0:de427e23a099 69 // Otherwise we are swiping either left or right
icserny 0:de427e23a099 70 if (candidate<newbtn) realbtn=SWIPE_L; else realbtn=SWIPE_R;
icserny 0:de427e23a099 71 return;
icserny 0:de427e23a099 72 }
icserny 0:de427e23a099 73
icserny 0:de427e23a099 74 // This is the main API
icserny 0:de427e23a099 75 // Call it to get a button code (0-3 or 256 or 512)
icserny 0:de427e23a099 76 // You can block or not (default is to block)
icserny 0:de427e23a099 77 int getbtn(bool kwait=true)
icserny 0:de427e23a099 78 {
icserny 0:de427e23a099 79 while (hold) // if holding, either wait or return
icserny 0:de427e23a099 80 {
icserny 0:de427e23a099 81 if (!kwait) return -1;
icserny 0:de427e23a099 82 }
icserny 0:de427e23a099 83 realbtn=-1; // mark that we don't know
icserny 0:de427e23a099 84 do
icserny 0:de427e23a099 85 {
icserny 0:de427e23a099 86 candidate=getrawbtn(); // get a candidate (or return if not waiting)
icserny 0:de427e23a099 87 } while (candidate==-1 || !kwait);
icserny 0:de427e23a099 88 if (candidate==-1) return -1;
icserny 0:de427e23a099 89 scan.attach(checkbtn,SWIPETIME); // schedule the checkbtn routine
icserny 0:de427e23a099 90 while (realbtn==-1); // wait for realbtn to get set
icserny 0:de427e23a099 91 return realbtn; // return it
icserny 0:de427e23a099 92 }
icserny 0:de427e23a099 93
icserny 0:de427e23a099 94 // Simple test program
icserny 0:de427e23a099 95 int main(void) {
icserny 0:de427e23a099 96
icserny 0:de427e23a099 97 while (true) {
icserny 0:de427e23a099 98 pc.printf("Button %d\r\n",getbtn());
icserny 0:de427e23a099 99 }
icserny 0:de427e23a099 100 }