1

I'm using JChristensen's Button Library to debounce my buttons and provide extra functionality. I'm trying to use his press & hold function to do something if the button is pressed and held for greater than 2 seconds. If it is just pressed momentarily it should do something else. His example use switch cases, and I couldn't get it to work. Here is my example that currently doesn't work.

 #include <Button.h>
 #include <SPI.h>
 #include <printf.h>
 // Keypress state setup
 byte clearPin = 16; // Clear pin
 #define PULLUP true
 #define INVERT true // Since the pullup resistor will keep the pin high unless the
 #define DEBOUNCE_MS 20 // A debounce time of 20 milliseconds usually works well for tactile button switches.
 #define LONG_PRESS 2000 // We define a "long press" to be 2000 milliseconds.
 unsigned long ms; // The current time from millis()
 Button clearBtn(clearPin, PULLUP, INVERT, DEBOUNCE_MS); // Declare the button
 int score=1;
void setup () 
{
 pinMode(16, INPUT_PULLUP); // Pin for clear button
 Serial.begin(9600); // Radio Setup
} 
void loop()
{
 clearScore(); // sets both home and away scores to 0 or enters settings menu
}
void clearScore()
{
 ms = millis(); //record the current time
 clearBtn.read(); // Read the button
 if (clearBtn.pressedFor(2000)) {
 // Enter settings menu
 Serial.println("Settings Menu");
 while (clearBtn.read()!=1) {
 } // End While
 return; // Hopefully not proceed down to the next if
 }
 if (clearBtn.wasReleased() && !clearBtn.pressedFor(2000)) {
 score=0;
 Serial.println("Clearing Scores");
 delay(50); 
 }
}

Can anyone help please? My serial output repeats "Settings Menu" over and over. Once I let go of the button (削除) variable1 (削除ここまで) always gets set to 0.

James Waldby - jwpat7
8,9203 gold badges21 silver badges33 bronze badges
asked Oct 15, 2015 at 21:38
4
  • No it was an example of what my code was. I was hoping for someone to write something generic and I'd learn and adapt from it. In any event, I have included the full code now. Commented Oct 17, 2015 at 2:55
  • user1229925, I edited the question (selected code and pressed ctrl-k to code-format it; changed word 'Entering' to 'Setting' after the code; crossed out variable1, not knowing what it should be. Does the "Clearing Scores" msg ever appear? Commented Oct 17, 2015 at 3:12
  • So it's supposed to work like this: 1) hold button down for 2 seconds to enter settings menu. While in settings menu ill code other stuff. STAY in settings menu until the clear button is pressed momentarily again. Once you press clear button again from being in the settings menu, the score should NOT be reset, and it should just return to the main loop. 2) if the clear button was not pressed for more than 2 seconds, just clear the score. Does that help @jwpat7 ? Commented Oct 17, 2015 at 13:43
  • My earlier comment about the action of the code had numerous incorrect parts, so I deleted it. See my answer below. Commented Oct 17, 2015 at 15:43

1 Answer 1

0

The loop() and clearScore() code that you have is like the following.

void loop() {
 clearScore(); // sets both home and away scores to 0 or enters settings menu
}
void clearScore() {
 ms = millis(); //record the current time
 clearBtn.read(); // Read the button
 if (clearBtn.pressedFor(2000)) {
 // Enter settings menu
 Serial.println("Settings Menu");
 while (clearBtn.read()!=1) {
 // do stuff
 } // End While
 return; // Don't proceed to next if
 }
 if (clearBtn.wasReleased() && !clearBtn.pressedFor(2000)) {
 score=0;
 Serial.println("Clearing Scores");
 delay(50); 
 }
}

When you reset the Arduino and then hold down the clearBtn, clearScore() will be called repeatedly. clearBtn.pressedFor(2000) will not be satisfied during the first two seconds of holding the button down, and clearBtn.wasReleased() will not be satisfied either, so clearScore() will do nothing during the first two seconds.

After the first two seconds, "Settings Menu" will be sent repeatedly: clearBtn.pressedFor(2000) is true, so the first if succeeds each time clearScore() runs, and it will run repeatedly because it is called from loop(). The while test, clearBtn.read()!=1 [which in more-idiomatic C would be written as !clearBtn.read()] fails until the clearBtn is released, so the while loop does nothing. Also, clearBtn.wasReleased() will be false, so the other if does nothing.

When the button finally is released, clearBtn.pressedFor(2000) goes false, so the first if fails and the second executes one time.

Here is some code that should act more like what you want, as expressed in your comment,

It's supposed to work like this: 1) hold button down for 2 seconds to enter settings menu. While in settings menu I'll code other stuff. Stay in settings menu until the clear button is pressed momentarily again. Once you press clear button again from being in the settings menu, the score should NOT be reset, and it should just return to the main loop. 2) if the clear button was not pressed for more than 2 seconds, just clear the score.

void clearScore() {
 ms = millis(); //record the current time
 while (clearBtn.read()) {
 if (clearBtn.pressedFor(2000)) {
 Serial.println("Settings Menu"); // Announce Settings menu
 while (clearBtn.read()) {} // Await button release
 while (!clearBtn.read()) { // Await button press
 // do Settings menu stuff here
 // (possibly wait for clearBtn release, to 
 // avoid immediately clearing score again)
 }
 }
 return;
 }
 if (clearBtn.wasReleased()) { // See if released, after short press
 score=0;
 Serial.println("Clearing Scores");
 delay(50); 
 }
}

Edit edit: To avoid resetting the score at every settings exit, in the above code replace

 // (possibly wait for clearBtn release, to 
 // avoid immediately clearing score again)
 }
 }

with

 }
 }
 while (clearBtn.read()) {} // wait for the settings-exit clearBtn release
 clearBtn.read(); // Do another read to avoid clearing score on next clearScore()

That is, right before the return, wait for clearBtn release, and read it again to be sure later reads won't register a release. The latter read might not be needed, because clearScore() does a read when it tests the first while condition; you could experiment.

answered Oct 17, 2015 at 15:42
6
  • I think 2 seconds is way too long; half a second might be a more reasonable transition from ordinary press to long press. Commented Oct 17, 2015 at 15:56
  • Wow. This works great! Thank you for the thoughtful explanation next to everything. It unfortunately resets the score every time you exit settings, but other than that I'm much closer then before. How do I ever repay you. Commented Oct 18, 2015 at 11:51
  • See edit about avoiding that reset. Feel free to accept answer (click some green button) and upvote. Commented Oct 18, 2015 at 20:12
  • That edit at the end didn't end up working. Can I paypal you to help finish? Commented Oct 19, 2015 at 2:50
  • I'm too busy to accept more work at the moment. I imagine the problem at the end was the two lines being before } } instead of after; see re-edit. Commented Oct 19, 2015 at 14:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.