I’ve written a class for detecting the button states for the power windows, door lock and latch buttons for my car.
It is set up for 2 button types:
Button Type 0: Door Locks/Latches
returns 3 States, Inactive(0), Pressed(1), Released(4)
Button Type 1: Power Windows
returns 5 States, Inactive(0), Pressed(1), Quick Press(2), Long Press Hold(3), Long Press Release(4)
It is working great except for one bug(so far).
When in state 3(long press hold) and I wiggle my finger on the button(causing bouncing I assume) it will return other states (1,2) randomly. I have tried several things to fix it, but have been unsuccessful in resolving the issue.
Hoping that one of the coding guru’s here can point out my mistake.
/*
Button State Detection for Automotive Power Windows, Door Locks/Latches
Button Type 0: Door Lock/Latch
Detects 3 States
Inactive(0), Pressed(1), Released(4)
Button Type 1: Power Windows
Detects 5 States
Inactive(0), Pressed(1), Quick Press(2), Long Press Hold(3), Long Press Release(4)
April 2016 by Les Hawkins
*/
#define DEBUG true // Set to true to enable Serial Debug
#define Serial if (DEBUG)Serial // WARNING: Use only when Serial is used for Debugging only (THIS REMOVES Serial COMPLETLY!!!)
class PWButton
{
byte buttonPin;
byte buttonType;
byte buttonRead;
byte oldButtonRead;
byte buttonPressed;
byte buttonReleased;
byte buttonState;
unsigned long currentTime;
unsigned long startTime;
unsigned long debounceTime;
unsigned long quickPressThreshold;
public:
PWButton(byte pin, byte type, unsigned long bounce, unsigned long qpThresh)
{
buttonPin = pin;
pinMode (buttonPin, INPUT_PULLUP);
buttonType = type;
debounceTime = bounce;
quickPressThreshold = qpThresh;
}
byte check()
{
currentTime = millis();
buttonRead = digitalRead(buttonPin);
if (buttonRead != oldButtonRead)
{
oldButtonRead = buttonRead;
startTime = currentTime;
}
if (buttonPressed == 0 && buttonReleased == 0)
{
buttonState = 0; // Button Inactive
}
if (buttonRead == oldButtonRead && currentTime - startTime >= debounceTime)
{
if (buttonRead == LOW) // Button has been Pressed
{
buttonPressed = 1;
buttonState = 1;
}
else // Button has been Released
{
if (buttonPressed == 1)
{
buttonReleased = 1;
}
}
}
if (buttonType == 1) // Power Window Buttons
{
if (buttonState == 1 && buttonReleased == 1 && currentTime - startTime <= quickPressThreshold)
{
buttonState = 2; // Quick Press
buttonPressed = 0;
buttonReleased = 0;
}
if (buttonState == 1 && buttonReleased == 0 && currentTime - startTime > quickPressThreshold)
{
buttonState = 3; // Long Press Hold
}
if (buttonState == 3 && buttonReleased == 1 && currentTime - startTime > quickPressThreshold)
{
buttonState = 4; // Long Press Released
buttonPressed = 0;
buttonReleased = 0;
}
}
if (buttonType == 0) // Door Lock/Latch Buttons
{
if (buttonPressed == 1 && buttonReleased == 1)
{
buttonState = 4;
buttonPressed = 0;
buttonReleased = 0;
}
}
return buttonState; // 0= inactive, 1= pressed, 2= quick press, 3= long press held, 4= released
}
}; // END of Class
// BUTTON OBJECTS
PWButton pwbutton1 (9, 1, 40, 250); // ( pin(pin#), button Type(0 or 1), debounce time(millis), quick press threshold(millis) )
PWButton lockbutton1 (8, 0, 40, 0);
byte readbutton1;
byte readbutton2;
byte oldreadbutton1;
byte oldreadbutton2;
void setup()
{
Serial.begin(9600);
}
void loop()
{
readbutton1 = pwbutton1.check();
if (readbutton1 != oldreadbutton1)
{
oldreadbutton1 = readbutton1;
Serial.println (readbutton1);
}
readbutton2 = lockbutton1.check();
if (readbutton2 != oldreadbutton2)
{
oldreadbutton2 = readbutton2;
Serial.println (readbutton2);
}
}