Robin2:
That is a neat piece of code. I have added it to my bookmarks.
Sorry, but I don’t understand your question. It doesn’t sound like it has anything to do with the button logic.
Have you tried adding your relay code into the clickEvent() function?
…R
I have just applied my previous case statement code to clickEvent() but am not getting the results I want.
Here is the revised code:
/* 4-Way Button: Click, Double-Click, Press+Hold, and Press+Long-Hold Test Sketch
By Jeff Saltzman
Oct. 13, 2009
To keep a physical interface as simple as possible, this sketch demonstrates generating four output events from a single push-button.
1) Click: rapid press and release
2) Double-Click: two clicks in quick succession
3) Press and Hold: holding the button down
4) Long Press and Hold: holding the button for a long time
*/
#include <Bounce2.h>
#define buttonPin 1 // analog input pin to use as a digital input
#define relayPin1 3 // digital output pin for relaypin1
#define relayPin2 4 // digital output pin for relaypin2
#define ledPin2 13 // digital output pin for relaypin2
#define ledPin3 0 // digital output pin for LED 1
#define ledPin4 13 // digital output pin for LED 2
// LED variables
boolean relayVal1 = false; // state of LED 1
boolean relayVal2 = false;
boolean ledVal2 = false; // state of LED 2
boolean ledVal3 = false; // state of LED 3
boolean ledVal4 = false; // state of LED 4
byte mode = 0;
Bounce bouncer = Bounce();
//=================================================
void setup() {
// Set button input pin
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH );
// Set LED output pins
pinMode(relayPin1, OUTPUT);
digitalWrite(relayPin1, relayVal1);
pinMode(relayPin2, OUTPUT);
digitalWrite(relayPin2, relayVal2);
pinMode(relayPin2, OUTPUT);
pinMode(ledPin2, OUTPUT);
digitalWrite(ledPin2, ledVal2);
pinMode(ledPin3, OUTPUT);
digitalWrite(ledPin3, ledVal3);
pinMode(ledPin4, OUTPUT);
digitalWrite(ledPin4, ledVal4);
// After setting up the button, setup the object
bouncer .attach( buttonPin );
bouncer .interval(5);
}
void loop() {
// Get button event and act accordingly
int b = checkButton();
if (b == 1) clickEvent();
if (b == 2) doubleClickEvent();
if (b == 3) holdEvent();
if (b == 4) longHoldEvent();
}
//=================================================
// Events to trigger
void clickEvent() {
// relayVal1 = !relayVal1;
// digitalWrite(relayPin1, relayVal1);
bouncer.update ( ); // Update the debouncer for the push button
switch( mode )
{
case 0://------------------------ I'm off and in restmode
if ( bouncer.read() == HIGH )
{
digitalWrite (ledPin2, LOW);
digitalWrite (relayPin1, LOW);
digitalWrite (relayPin2, HIGH); // switch relay ON
mode = 1;
}
break;
case 1://------------------------ I'm in ON mode, w8 4 keyrelease
if ( bouncer.read() == LOW )
{
digitalWrite (ledPin2, LOW);
digitalWrite (relayPin1, HIGH);
digitalWrite (relayPin2, LOW); // switch relay ON
mode = 2;
}
break;
case 2://------------------------ I'm ON and in restmode
if ( bouncer.read() == HIGH )
{
digitalWrite (ledPin2, HIGH);
digitalWrite (relayPin1, LOW);
digitalWrite (relayPin2, LOW); // switch relay ON
mode = 3;
}
break;
case 3://------------------------ I'm in OFF mode, w8 4 keyrelease
if ( bouncer.read() == LOW )
{
digitalWrite (ledPin2, LOW);
digitalWrite (relayPin1, LOW);
digitalWrite (relayPin2, HIGH); // switch relay ON
mode = 0;
}
break;
}//switch
}
void doubleClickEvent() {
ledVal2 = !ledVal2;
digitalWrite(ledPin2, ledVal2);
}
void holdEvent() {
ledVal3 = !ledVal3;
digitalWrite(ledPin3, ledVal3);
}
void longHoldEvent() {
ledVal4 = !ledVal4;
digitalWrite(ledPin4, ledVal4);
}
//=================================================
// MULTI-CLICK: One Button, Multiple Events
// Button timing variables
int debounce = 20; // ms debounce period to prevent flickering when pressing or releasing the button
int DCgap = 250; // max ms between clicks for a double click event
int holdTime = 1000; // ms hold period: how long to wait for press+hold event
int longHoldTime = 3000; // ms long hold period: how long to wait for press+hold event
// Button variables
boolean buttonVal = HIGH; // value read from button
boolean buttonLast = HIGH; // buffered value of the button's previous state
boolean DCwaiting = false; // whether we're waiting for a double click (down)
boolean DConUp = false; // whether to register a double click on next release, or whether to wait and click
boolean singleOK = true; // whether it's OK to do a single click
long downTime = -1; // time the button was pressed down
long upTime = -1; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered
boolean waitForUp = false; // when held, whether to wait for the up event
boolean holdEventPast = false; // whether or not the hold event happened already
boolean longHoldEventPast = false;// whether or not the long hold event happened already
int checkButton() {
int event = 0;
buttonVal = digitalRead(buttonPin);
// Button pressed down
if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
{
downTime = millis();
ignoreUp = false;
waitForUp = false;
singleOK = true;
holdEventPast = false;
longHoldEventPast = false;
if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true) DConUp = true;
else DConUp = false;
DCwaiting = false;
}
// Button released
else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
{
if (not ignoreUp)
{
upTime = millis();
if (DConUp == false) DCwaiting = true;
else
{
event = 2;
DConUp = false;
DCwaiting = false;
singleOK = false;
}
}
}
// Test for normal click event: DCgap expired
if ( buttonVal == HIGH && (millis()-upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2)
{
event = 1;
DCwaiting = false;
}
// Test for hold
if (buttonVal == LOW && (millis() - downTime) >= holdTime) {
// Trigger "normal" hold
if (not holdEventPast)
{
event = 3;
waitForUp = true;
ignoreUp = true;
DConUp = false;
DCwaiting = false;
//downTime = millis();
holdEventPast = true;
}
// Trigger "long" hold
if ((millis() - downTime) >= longHoldTime)
{
if (not longHoldEventPast)
{
event = 4;
longHoldEventPast = true;
}
}
}
buttonLast = buttonVal;
return event;
}
I do that same thing, except I use an analog input, so I can have multiple buttons (up to 6 or 8) on a single input, all with that above functionality, plus optional auto-repeat when a button is held down.
Regards,
Ray L.
That is something that I have been looking into for a dual button set up. You just have multiple pulldown resistor values to create a voltage divider on the analog pin, correct?