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

Fork of 04_tsi_buttons by Istvan Cserny

main.cpp

Committer:
icserny
Date:
2015-11-03
Revision:
0:de427e23a099

File content as of revision 0:de427e23a099:

#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());
    }
}