Gamepad Input and Edge Detection
Read sticks, triggers, and buttons without repeated accidental actions.
Read sticks, triggers, and buttons without repeated accidental actions.
In this lesson, you will:
Gamepad sticks and triggers are continuous values, while buttons are booleans sampled many times per second. A held button may be true for dozens of loops, so the code must decide whether it represents a held command or a single press event.
Drivers think in actions: hold intake, tap score, reset heading, slow mode. Code should match that intention. Some controls should run while held; others should fire once when the button changes from false to true.
Hey, so you already know the difference between a button being held, pressed, and released. Let's trace the same button across five robot loops so we can see exactly when each signal becomes true. Each column represents one pass through the robot loop. The button values are false, false, true, true, and false. The button remains down for loops three and four, so the loop reads true twice. The important part is that does not mean the driver pressed it twice. It means the program sampled the same held button on two different loops. If we draw these same values as a graph over time, the line starts low because the button is false during loops one and two. At the boundary before loop three, the line steps straight up. That rising edge is the instant the button becomes pressed. The line stays high through loops three and four, and that flat high section means the button is being held. It does not create another press. Before loop five, the line steps straight back down, and that falling edge is the release. The line remains low because the button is false again. This looks like one square pulse from a PWM-style graph, but it is not a PWM output. We are only using the shape to show a boolean button state over time. Now we can compare the current sample with the previous sample. Held is the current button value, so it is true on both loops where the button is down. A pressed signal, also called a rising edge, is true only on loop three. That is the moment current changes from false to true. A released signal, or falling edge, is true only on loop five, where current changes from true back to false. If we look at some code, at the top of the loop, currentA reads the button now. previousA still contains the value from the last loop. aPressed is true when currentA is true and previousA is false, so it is the rising edge. aReleased is true when current is false and previous is true, so it is the falling edge. The order matters here, and we calculate both edges first. We want to update previousA near the bottom of the loop, after the results have already been used. If you overwrite previous before then, both values become identical and the edge disappears. The slow-mode line reads left_bumper directly because slow mode should remain active for every loop where the bumper is held. The claw toggle uses aPressed because the claw should change once per button press, not repeatedly while the button remains down. If we did not implement a rising-edge detector here, the toggle would only work if the driver pressed the button for exactly one sample, but that is not reliable or realistic. A simple translation from our words would be: while held uses the current value, when pressed uses the rising edge, and when released uses the falling edge. Edge detection cannot fix a confusing control layout, so you want to talk with your drivers before writing the condition. Before running the code, complete the held, pressed, and released rows for these five samples. Choose one season-robot action that should repeat while held and one action that should happen when pressed. Predict first what is going to happen, compare with telemetry, and keep the control behavior documented so new drivers know how it works even after the season is over.
On FTC SDK 11.2, use the Gamepad edge methods such as aWasPressed() for a one-shot action and read fields such as left_bumper directly for a held mode. Call an edge method once per control per loop so its internal previous-state tracking stays unambiguous.
EdgeDetection.javaJava
if (gamepad2.aWasPressed()) {
arm.goToDeposit();
}
// Continuous controls still read the current value every loop.
boolean slowMode = gamepad2.left_bumper;Repeated scheduling, double toggles, and flickering states usually mean a one-shot action is being run as a held action. Print current, previous, and detected edge to prove the control behavior.
Convert one mechanism button from held behavior to edge-triggered behavior. Then identify one control that should remain held.
Check your understanding before moving on.
0 of 2 answered