How possible when they are declared as 'const'?
right they are constant they are used like time stamps so if i press the button and its longer than 200 then its considered a long push and if i press and its less than 200 it is a short press.
if( pressDuration > LONG_PRESS_TIME ) {
Serial.println("A long press is detected");
digitalWrite(LEDP, HIGH);
So it is clearly absurd to have two such constants. ![]()
I dont know I was just following a tutorial. made sense to me lol.
I have an open mind. Explain it to me.
Just that the value shouldnt change, I suppose they dont need to be const int but again i dont know what im really doing. How would you suggest to do it?
also the main problem im is that LEDS is turning on after I let go from a long press. I cant see in issue in my code and was maybe wondering if you could spot it?
I agree that they shouldn't change. Each one should define a different interval - one, the time that defines a short press, one the time that defines a long press. Obviously, the long press time should be longer than the short press time. How the code uses those values is baked into whatever logic you use, it should have nothing to do with the values of the defined constants.
I have never implemented a long/short press system so I'm not immediately sure how that is done. Why not just use a button library that does all that for you? They do exist.
I am using the ezButton library, and was just following the code from their tutorial but ran into a bit of an issue with the short press turning on after the long press and am having difficulty coding the led to flash when long or short pressed.
Did you break down the problem into manageable sub-tasks? Write a program that doesn't flash LEDs at all, just serial prints, "long pressed" on a long press and "short press" on a short press...
Is there a hard baked requirement to use only that one library? Does that tutorial deal with variable length presses?
Connecting those inputs with LED actions is usually done by setting and checking state variables or flags.
I have not been following this thread too closely.
If you get some time, review Nick Gammon’s Switch Manager library.
https://arduinogetstarted.com/tutorials/arduino-button-long-press-short-press this is the library and tutorial I was following, and yes the serial print short and long were separate and i added in the LED functions, with my current knowledge of coding my code has it set to were it should only turn on the led if it states short press in the serial print, where as it doesnt in practice on the bread board. Ill do some research on flags and state variables and maybe try those!
ill take a look into it. so far the ezButton library has been the only form of code ive come close to what i want my outcome to be but since I'm still knew i will look into more stuff including the different libraries!
I'm not knocking the library, but when I looked at it yesterday, I didn't see anything like an advanced event manager, such as a specific handler for long and short presses. That just means extra work for you if you have to implement it yourself.
I understand ill take a look into more libraries ad see what I can do by myself for now.
Try the Switch Manager method applied to your sketch from post 17.
//Version 1
//**************************************************************************************************
//normally this Class would be inside a library but
//for a all in one example, it is placed here
class SwitchManager
{
enum { debounceTime = 10, noSwitch = -1 };
typedef void (*handlerFunction) (const byte newState,
const unsigned long interval,
const byte whichSwitch);
int pinNumber_;
handlerFunction f_;
byte oldSwitchState_;
unsigned long switchPressTime_; // when the switch last changed state
unsigned long lastLowTime_;
unsigned long lastHighTime_;
byte sampleCounter_; // 1.01
public:
// constructor
SwitchManager ()
{
pinNumber_ = noSwitch;
f_ = NULL;
oldSwitchState_ = HIGH;
switchPressTime_ = 0;
lastLowTime_ = 0;
lastHighTime_ = 0;
sampleCounter_ = 0; // 1.01
}
void begin (const int pinNumber, handlerFunction f)
{
pinNumber_ = pinNumber;
f_ = f;
if (pinNumber_ != noSwitch)
pinMode (pinNumber_, INPUT_PULLUP);
} // end of begin
void check ()
{
// we need a valid pin number and a valid function to call
if (pinNumber_ == noSwitch || f_ == NULL)
return;
// time to check the switch?
if (millis () - switchPressTime_ < debounceTime) // 1.01
{
//it's not time yet
return;
}
// times up, get ready for next sequence
switchPressTime_ = millis();
byte switchState = digitalRead(pinNumber_);
// has the switch changed state?
if (switchState == oldSwitchState_) // 1.01
{
// reset the counter as no state changed was detected 1.01
sampleCounter_ = 0; // 1.01
return; // 1.01
}
// The switch has changed state
// This is used to filter circuit noise 1.01
sampleCounter_++; // 1.01
// Must read the switch sequential 2 times before we validate a switch change. 1.01
// i.e. if debounceTime is 10ms, it will take 20ms to validate a switch change. 1.01
// With an input sample rate of 10ms, input signals > 20ms are guaranteed to be captured. 1.01
// Signals 10-20ms might be captured, with signals < 10ms guaranteed not to be captured. 1.01
// Is this the 2nd time in two sequential reads? 1.01
if (sampleCounter_ >= 2) // 1.01
{
// remember for next time
oldSwitchState_ = switchState;
// Get ready for the next 2 samples 1.01
sampleCounter_ = 0; // 1.01
// see if switch is LOW or HIGH
if (switchState == LOW)
{
lastLowTime_ = switchPressTime_;
f_ (LOW, lastLowTime_ - lastHighTime_, pinNumber_);
}
// switch must be HIGH then
else
{
lastHighTime_ = switchPressTime_;
f_ (HIGH, lastHighTime_ - lastLowTime_, pinNumber_);
}
}
} // end of operator ()
}; //END of Class SwitchManager
//**************************************************************************************************
//object instantiations
SwitchManager mySwitch;
#define RELEASED HIGH
#define PUSHED LOW
#define LEDon HIGH //A HIGH on the pin turns the LED ON
#define LEDoff LOW
#define ENABLED true
#define DISABLED false
bool LEDSflag = DISABLED;
const byte heartBeatLED = 13;
const byte Button1 = 10; //Switch wired to GND, N.O.
const byte LEDP = 9;
const byte LEDS = 8;
//timing stuff
unsigned long heartbeatMillis;
unsigned long heartFlashRate = 500UL; // time the led will change state
unsigned long LEDSmillis;
unsigned long LEDSonTime = 1000ul; //how long the LEDS LED is ON
unsigned long SHORT_PRESS_TIME = 200ul;
unsigned long LONG_PRESS_TIME = 1000ul;
//**************************************************************************************************
void setup()
{
Serial.begin(9600);
//gives a visual indication if the sketch is blocking
pinMode(heartBeatLED, OUTPUT);
digitalWrite(LEDP, LEDoff);
pinMode(LEDP, OUTPUT);
digitalWrite(LEDS, LEDoff);
pinMode(LEDS, OUTPUT);
//the handleSwitchPresses() function is called when a switch changes state
mySwitch.begin (Button1, handleSwitchPresses);
} //END of setup()
//**************************************************************************************************
void loop()
{
//*************************** h e a r t b e a t T I M E R
//some code to see if the sketch is blocking
if (millis() - heartbeatMillis >= heartFlashRate)
{
//restart this TIMER
heartbeatMillis = millis();
//toggle the heartBeatLED
digitalWrite(heartBeatLED, !digitalRead(heartBeatLED));
}
//*************************** L E D S T I M E R
//if we are timing, is it time to turn OFF the LED ?
if (LEDSflag == ENABLED && millis() - LEDSmillis >= LEDSonTime)
{
//diasble this TIMER
LEDSflag = DISABLED;
digitalWrite(LEDS, LEDoff);
}
//***************************
//check to see what's happening with the switches
//"Do not use delay()s" in your sketch as it will make switch changes unresponsive
//Use BlinkWithoutDelay (BWD) techniques instead.
mySwitch.check ();
//*********************************
//put other non-blocking stuff here
//*********************************
} //END of loop()
//**************************************************************************************************
void handleSwitchPresses(const byte newState, const unsigned long interval, const byte whichPin)
{
//You get here 'ONLY' if there has been a change in a switches state.
//when a switch has changed state, SwitchManager passes this function 3 arguments:
//"newState" this will be HIGH or LOW. This is the state the switch is in now.
//"interval" the number of milliseconds the switch stayed in the previous state
//"whichPin" is the switch pin that we are examining
switch (whichPin)
{
//******************************************* m y S w i t c h
//are we dealing with this switch?
case Button1:
//*************************
//has this switch gone from LOW to HIGH (gone from pressed to released)
//this happens with normally open switches wired as mentioned at the top of this sketch
if (newState == RELEASED)
{
//***********
//if we are not timing was this a short press ?
if (LEDSflag == DISABLED && interval < SHORT_PRESS_TIME)
{
Serial.println("A short press is detected");
digitalWrite(LEDS, LEDon);
//enable the LEDS Timer
LEDSflag = ENABLED;
//set the LEDS ON time
LEDSonTime = 1000;
//start the TIMER
LEDSmillis = millis();
}
//***********
//was this a long press ?
else if ( interval >= LONG_PRESS_TIME)
{
Serial.println("A long press is detected");
digitalWrite(LEDP, LEDon);
}
}
break; //End of case Button1
//*************************
} //End of switch (whichPin)
} //End of handleSwitchPresses()
//**************************************************************************************************
// E N D O F C O D E
//**************************************************************************************************
thank you so much very easy to follow, one thing though what would I have to add so that the LEDP is only turned on when the button is being pressed instead of after the hold, because before I would be able to just hold the button and for the duration of the hold the led would be on and when coded eventually flashing. Would I do a call function if I want to blink the LEDs?
// Version YY/MM/DD Comments
// 1.00 22/02/27 Running code
//**************************************************************************************************
//normally this Class would be inside a library but
//for a all in one example, it is placed here
class SwitchManager
{
enum { debounceTime = 10, noSwitch = -1 };
typedef void (*handlerFunction) (const byte newState,
const unsigned long interval,
const byte whichSwitch);
int pinNumber_;
handlerFunction f_;
byte oldSwitchState_;
unsigned long switchPressTime_; // when the switch last changed state
unsigned long lastLowTime_;
unsigned long lastHighTime_;
byte sampleCounter_; // 1.01
public:
// constructor
SwitchManager ()
{
pinNumber_ = noSwitch;
f_ = NULL;
oldSwitchState_ = HIGH;
switchPressTime_ = 0;
lastLowTime_ = 0;
lastHighTime_ = 0;
sampleCounter_ = 0; // 1.01
}
void begin (const int pinNumber, handlerFunction f)
{
pinNumber_ = pinNumber;
f_ = f;
if (pinNumber_ != noSwitch)
pinMode (pinNumber_, INPUT_PULLUP);
} // end of begin
void check ()
{
// we need a valid pin number and a valid function to call
if (pinNumber_ == noSwitch || f_ == NULL)
return;
// time to check the switch?
if (millis () - switchPressTime_ < debounceTime) // 1.01
{
//it's not time yet
return;
}
// times up, get ready for next sequence
switchPressTime_ = millis();
byte switchState = digitalRead(pinNumber_);
// has the switch changed state?
if (switchState == oldSwitchState_) // 1.01
{
// reset the counter as no state changed was detected 1.01
sampleCounter_ = 0; // 1.01
return; // 1.01
}
// The switch has changed state
// This is used to filter circuit noise 1.01
sampleCounter_++; // 1.01
// Must read the switch sequential 2 times before we validate a switch change. 1.01
// i.e. if debounceTime is 10ms, it will take 20ms to validate a switch change. 1.01
// With an input sample rate of 10ms, input signals > 20ms are guaranteed to be captured. 1.01
// Signals 10-20ms might be captured, with signals < 10ms guaranteed not to be captured. 1.01
// Is this the 2nd time in two sequential reads? 1.01
if (sampleCounter_ >= 2) // 1.01
{
// remember for next time
oldSwitchState_ = switchState;
// Get ready for the next 2 samples 1.01
sampleCounter_ = 0; // 1.01
// see if switch is LOW or HIGH
if (switchState == LOW)
{
lastLowTime_ = switchPressTime_;
f_ (LOW, lastLowTime_ - lastHighTime_, pinNumber_);
}
// switch must be HIGH then
else
{
lastHighTime_ = switchPressTime_;
f_ (HIGH, lastHighTime_ - lastLowTime_, pinNumber_);
}
}
} // end of operator ()
}; //END of Class SwitchManager
//**************************************************************************************************
//object instantiations
SwitchManager mySwitch;
#define RELEASED HIGH
#define PUSHED LOW
#define LEDon HIGH //A HIGH on the pin turns the LED ON
#define LEDoff LOW
#define ENABLED true
#define DISABLED false
bool LEDSflag = DISABLED;
const byte heartBeatLED = 13;
const byte Button1 = 10; //Switch wired to GND, N.O.
const byte LEDP = 9;
const byte LEDS = 8;
//timing stuff
unsigned long heartbeatMillis;
unsigned long heartFlashRate = 500UL; // time the led will change state
unsigned long LEDSmillis;
unsigned long LEDSonTime = 1000ul; //how long the LEDS LED is ON
unsigned long SHORT_PRESS_TIME = 200ul;
unsigned long LONG_PRESS_TIME = 1000ul;
//**************************************************************************************************
void setup()
{
Serial.begin(9600);
//gives a visual indication if the sketch is blocking
pinMode(heartBeatLED, OUTPUT);
digitalWrite(LEDP, LEDoff);
pinMode(LEDP, OUTPUT);
digitalWrite(LEDS, LEDoff);
pinMode(LEDS, OUTPUT);
//the handleSwitchPresses() function is called when a switch changes state
mySwitch.begin (Button1, handleSwitchPresses);
} //END of setup()
//**************************************************************************************************
void loop()
{
//*************************** h e a r t b e a t T I M E R
//some code to see if the sketch is blocking
if (millis() - heartbeatMillis >= heartFlashRate)
{
//restart this TIMER
heartbeatMillis = millis();
//toggle the heartBeatLED
digitalWrite(heartBeatLED, !digitalRead(heartBeatLED));
}
//*************************** L E D S T I M E R
//if we are timing, is it time to turn OFF the LED ?
if (LEDSflag == ENABLED && millis() - LEDSmillis >= LEDSonTime)
{
//diasble this TIMER
LEDSflag = DISABLED;
digitalWrite(LEDS, LEDoff);
}
//***************************
//check to see what's happening with the switches
//"Do not use delay()s" in your sketch as it will make switch changes unresponsive
//Use BlinkWithoutDelay (BWD) techniques instead.
mySwitch.check ();
//****************************************************
//put other non-blocking stuff here
//****************************************************
} //END of loop()
//**************************************************************************************************
void handleSwitchPresses(const byte newState, const unsigned long interval, const byte whichPin)
{
//You get here 'ONLY' if there has been a change in a switches state.
//when a switch has changed state, SwitchManager passes this function 3 arguments:
//"newState" this will be HIGH or LOW. This is the state the switch is in now.
//"interval" the number of milliseconds the switch stayed in the previous state
//"whichPin" is the switch pin that we are examining
switch (whichPin)
{
//***************************************************** m y S w i t c h
//are we dealing with this switch?
case Button1:
//*************************
//has this switch gone from LOW to HIGH (gone from pressed to released)
//this happens with normally open switches wired as mentioned at the top of this sketch
if (newState == RELEASED)
{
//***********
//if we are not timing was this a short press ?
if (LEDSflag == DISABLED && interval < SHORT_PRESS_TIME)
{
Serial.println("A short press is detected");
digitalWrite(LEDS, LEDon);
//enable the LEDS Timer
LEDSflag = ENABLED;
//set the LEDS ON time
LEDSonTime = 1000;
//start the TIMER
LEDSmillis = millis();
}
// //***********
// //was this a long press ?
// else if ( interval >= LONG_PRESS_TIME)
// {
// Serial.println("A long press is detected");
//
// digitalWrite(LEDP, LEDon);
// }
//the switch was released, turn OFF LEDP
digitalWrite(LEDP, LEDoff);
} //END of if(newState == RELEASED)
//***********
//the switch was just pressed ?
else
{
digitalWrite(LEDP, LEDon);
}
break; //End of case Button1
//*************************
} //End of switch (whichPin)
} //End of handleSwitchPresses()
//**************************************************************************************************
// E N D O F C O D E
//**************************************************************************************************
If I press short the long one turns on first now,
It needs a way to detect if its long after the short press time, but holding for the long works great!
As it is now:
-
When the switch is pushed/closed LEDP is/stays ON.
-
If the switch is pressed for less then 200ms, the LEDS is triggered to go ON for 1000 milli seconds.
What do you want the LEDs to do ?
everything works how it should except if I press wanting the short press LEDS to turn on the LEDP turns on for as long as I press it. I want the LEDP to only turn on after the interval to detect the short press. basically the LEDP turns on every time I press the button no matter what. I want LEDP to turn on only after the interval for LEDS passed, if that makes sense. I want them to be separate.