2015-08-31 22:25:10 +00:00
|
|
|
#include "MicroBit.h"
|
2015-08-12 10:53:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
* Create a pin representation with the given ID.
|
|
|
|
* @param id the ID of the new MicroBitButton object.
|
|
|
|
* @param name the physical pin on the processor that this butotn is connected to.
|
|
|
|
* @param mode the configuration of internal pullups/pulldowns, as define in the mbed PinMode class. PullNone by default.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* @code
|
|
|
|
* buttonA(MICROBIT_ID_BUTTON_A,MICROBIT_PIN_BUTTON_A); //a number between 0 and 200 inclusive
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* Possible Events:
|
|
|
|
* @code
|
|
|
|
* MICROBIT_BUTTON_EVT_DOWN
|
|
|
|
* MICROBIT_BUTTON_EVT_UP
|
|
|
|
* MICROBIT_BUTTON_EVT_CLICK
|
|
|
|
* MICROBIT_BUTTON_EVT_LONG_CLICK
|
|
|
|
* MICROBIT_BUTTON_EVT_DOUBLE_CLICK
|
|
|
|
* MICROBIT_BUTTON_EVT_HOLD
|
|
|
|
* @endcode
|
|
|
|
*/
|
|
|
|
MicroBitButton::MicroBitButton(uint16_t id, PinName name, PinMode mode) : pin(name, mode)
|
|
|
|
{
|
|
|
|
this->id = id;
|
|
|
|
this->name = name;
|
|
|
|
this->downStartTime = 0;
|
|
|
|
this->sigma = 0;
|
|
|
|
this->doubleClickTimer = 0;
|
|
|
|
uBit.addSystemComponent(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* periodic callback from MicroBit clock.
|
|
|
|
* Check for state change for this button, and fires a hold event if button is pressed.
|
|
|
|
*/
|
|
|
|
void MicroBitButton::systemTick()
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// If the pin is pulled low (touched), increment our culumative counter.
|
|
|
|
// otherwise, decrement it. We're essentially building a lazy follower here.
|
|
|
|
// This makes the output debounced for buttons, and desensitizes touch sensors
|
|
|
|
// (particularly in environments where there is mains noise!)
|
|
|
|
//
|
|
|
|
if(!pin)
|
|
|
|
{
|
|
|
|
if (sigma < MICROBIT_BUTTON_SIGMA_MAX)
|
|
|
|
sigma++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (sigma > MICROBIT_BUTTON_SIGMA_MIN)
|
|
|
|
sigma--;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if we have off->on state change.
|
|
|
|
if(sigma > MICROBIT_BUTTON_SIGMA_THRESH_HI && !(status & MICROBIT_BUTTON_STATE))
|
|
|
|
{
|
|
|
|
// Record we have a state change, and raise an event.
|
|
|
|
status |= MICROBIT_BUTTON_STATE;
|
|
|
|
MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_DOWN);
|
|
|
|
|
|
|
|
//Record the time the button was pressed.
|
|
|
|
downStartTime=ticks;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if we have on->off state change.
|
|
|
|
if(sigma < MICROBIT_BUTTON_SIGMA_THRESH_LO && (status & MICROBIT_BUTTON_STATE))
|
|
|
|
{
|
|
|
|
status = 0;
|
|
|
|
MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_UP);
|
|
|
|
|
|
|
|
//determine if this is a long click or a normal click and send event
|
|
|
|
if((ticks - downStartTime) >= MICROBIT_BUTTON_LONG_CLICK_TIME)
|
|
|
|
MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_LONG_CLICK);
|
|
|
|
else
|
|
|
|
MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK);
|
|
|
|
}
|
|
|
|
|
|
|
|
//if button is pressed and the hold triggered event state is not triggered AND we are greater than the button debounce value
|
|
|
|
if((status & MICROBIT_BUTTON_STATE) && !(status & MICROBIT_BUTTON_STATE_HOLD_TRIGGERED) && (ticks - downStartTime) >= MICROBIT_BUTTON_HOLD_TIME)
|
|
|
|
{
|
|
|
|
//set the hold triggered event flag
|
|
|
|
status |= MICROBIT_BUTTON_STATE_HOLD_TRIGGERED;
|
|
|
|
|
|
|
|
//fire hold event
|
|
|
|
MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_HOLD);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests if this Button is currently pressed.
|
|
|
|
* @return 1 if this button is pressed, 0 otherwise.
|
|
|
|
*/
|
|
|
|
int MicroBitButton::isPressed()
|
|
|
|
{
|
|
|
|
return status & MICROBIT_BUTTON_STATE ? 1 : 0;
|
|
|
|
}
|