// 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
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
Diff: main.cpp
- 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