kopia lustrzana https://github.com/kk4das/SSB_Radio_Control
118 wiersze
3.1 KiB
C++
118 wiersze
3.1 KiB
C++
/*
|
|
* ButtonState.cpp
|
|
*
|
|
* Created on: Mar 22, 2022
|
|
* Author: KA4CDN
|
|
*/
|
|
|
|
#include "ButtonState.h"
|
|
|
|
#define DEPRESSED 0
|
|
#define NOT_DEPRESSED 1
|
|
|
|
#define LONG_PRESS_TIME 1500 // msec
|
|
#define DEBOUNCE_TIME 50 // msec
|
|
|
|
#define FILTER_DEPTH 25 // Number of button presses to average
|
|
#define BTN_PRESS_THRSH 0.3 // Threshold to consider an average of 1/0 to be pressed
|
|
|
|
ButtonState::ButtonState (ButtonState::BUTTON_TYPE longPressSupport)
|
|
{
|
|
m_supportLongPress = longPressSupport;
|
|
m_lastBtnState = m_priorBtnState = NOT_DEPRESSED;
|
|
}
|
|
|
|
ButtonState::~ButtonState ()
|
|
{
|
|
// TODO Auto-generated destructor stub
|
|
}
|
|
|
|
/*
|
|
* Check the button state. Pass in the current read state of the button and this
|
|
* method debounces and returns a single shot indication of the button press.
|
|
*
|
|
* If the button was constructed as supporting long presses then the type of
|
|
* press, short or long, is returned.
|
|
*
|
|
* In: byte buttonPressed. Pass 0 if button depressed and 1 if not depressed
|
|
* Out: ButtonState::BUTTON_STATE
|
|
* NO_PRESS : button not pressed
|
|
* PRESSED : button pressed (only if button does not support long presses)
|
|
* SHORT_PRESS : button pressed and release (long press support)
|
|
* LONG_PRESS : button pressed and held, a long press
|
|
*/
|
|
enum ButtonState::BUTTON_STATE ButtonState::CheckButton(byte rawButtonPressed )
|
|
{
|
|
BUTTON_STATE retState = NO_PRESS;
|
|
|
|
// Filter the button high freq. bouces
|
|
byte buttonPressed = filteredButton( rawButtonPressed );
|
|
|
|
// Check for low freq. bounce stability
|
|
if ( debounced(buttonPressed) )
|
|
{
|
|
if ( buttonPressed != m_lastBtnState )
|
|
{
|
|
if ( buttonPressed == DEPRESSED )
|
|
{
|
|
m_buttonLowTime = millis(); // Only used for long press checks
|
|
m_ignoreUp = false;
|
|
}
|
|
else if (m_ignoreUp == false) // ignore button up after long press
|
|
{
|
|
retState = m_supportLongPress == LONG_SUPPORT ? SHORT_PRESS : PRESSED;
|
|
}
|
|
}
|
|
else if ( m_supportLongPress == LONG_SUPPORT )
|
|
{
|
|
if ( (buttonPressed == DEPRESSED)
|
|
&& (m_ignoreUp == false) // ignore button up after long press
|
|
&& ((millis() - m_buttonLowTime) > LONG_PRESS_TIME) )
|
|
{
|
|
retState = LONG_PRESS;
|
|
m_ignoreUp = true;
|
|
m_buttonLowTime = millis();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Reset the debounce timer after a valid press detect.
|
|
if ( retState != NO_PRESS )
|
|
resetDebounceStart();
|
|
|
|
m_lastBtnState = buttonPressed;
|
|
return retState;
|
|
}
|
|
|
|
byte ButtonState::filteredButton( byte buttonPress )
|
|
{
|
|
m_avgButtonState = m_avgButtonState * ( FILTER_DEPTH - 1 ) / FILTER_DEPTH + (float) buttonPress / FILTER_DEPTH;
|
|
|
|
if ( m_avgButtonState < BTN_PRESS_THRSH )
|
|
return DEPRESSED;
|
|
else
|
|
return NOT_DEPRESSED;
|
|
}
|
|
|
|
|
|
bool ButtonState::debounced(byte buttonPress)
|
|
{
|
|
bool debounced = true;
|
|
|
|
if ( millis() < m_stableTime + DEBOUNCE_TIME )
|
|
{
|
|
debounced = false;
|
|
if ( buttonPress != m_priorBtnState )
|
|
{
|
|
m_stableTime = millis();
|
|
m_priorBtnState = buttonPress;
|
|
}
|
|
}
|
|
return debounced;
|
|
}
|
|
|
|
void ButtonState::resetDebounceStart(void)
|
|
{
|
|
m_stableTime = millis();
|
|
}
|