Back at it again with another programming question. As always I apologize if this has been answered somewhere, but I could not find an answer.
So I am trying to use a small toggling type function to assign a bool variable to true after a button press, and then revert it back to false after a certain amount of time has passed.
I’m assuming this if block is in some kind of loop.
Here’s what happens:
Button pressed condition passes
toggle2 starts false, so second condition passes
toggle2 set to true
program delays for 2 seconds and does nothing
toggle2 set to false (second condition complete)
program delays for 200ms and does nothing (first condition complete)
rest of the loop executes
What you’re describing makes it sound like you want it to do something like this instead:
Button is pressed and toggle2 is false
Set toggle2 to true
make note of the time (condition complete)
Otherwise, if it has been two seconds since toggle2 became true,
Set toggle2 to false (condition complete)
rest of the loop executes
If you want other things to happen while it waits for two seconds, you either need to record the time and check the current time against the recorded time or handle the delay in a separate thread (which is much more complicated). Otherwise, just telling the single thread you have to delay for 2 seconds will cause all execution to delay for two seconds.
@Hackapi That will produce the same behavior as he’s already seeing. Sleeping for two seconds will sleep for two solid seconds no matter how you dress it up. He needs a way to eliminate the sleep(2000) altogether.
Reset the timer or record its value when the button is pressed as well are setting the boolean to true.
In your while(true) loop, just keep checking the boolean. If the boolean is true, check the timer to see if enough time has passed. If it has, change the boolean back to false.
Btw the 200ms sleep is what I have for all my toggles so that they are not triggered 30x times over by a single press (there is probably a better way, but that’s for a dedicated programmer to figure out), and the issue of stopping the whole robot has not come up, most likely because of the short wait time comparatively. So that is why I used another sleep function to wait during the loop
If I wanted to make it a two-step toggle I would, but I would much rather have it as one press to simplify driving, but if that is only to stop me from slapping sleep functions everywhere then thanks.
What you wrote was not a toggle so much as a triggered pulse. There was no way for pressing the button again to unset the toggle.
If you want a true toggle on rising edge (when the button goes from not-pressed to pressed) with timeout, you need to add a piece onto the timer that we’ve been telling you about. A simple 200ms wait isn’t going to cut it.
Rising edge detection requires you to keep track of the last state of the button, and only trigger your action when the state changes in the direction you want. To put it in a truth table:
last button | this button || take action
----------------------------------------
F | F || F
F | T || T
T | F || F
T | T || F
So you would check (!last && current) to take action. The action would be changing the state of your toggle and setting the timeout time:
There’s one last wrinkle to making this work right, and that’s how we set the value of last. If we just set it to whatever the button currently is whenever, we could run into a race condition where the state of the button changes after we’ve checked for it but before we set the state of last, meaning it could jump straight from the FF row to the TT row, skipping the FT row that we care about. So we only set last to true if we handled FT, so we add that to the two lines above and add this to handle resetting last to false: