RECENTLY CHECKED
All projects →
Make a control respond · STAGE 3 OF 4

Make one press produce one mode change

Add a button without stopping the timed output. Separate noisy input changes from a deliberate press.

You needA browser for the input trace. Hardware example targets an Arduino Uno with a momentary button between pin 2 and GND using INPUT_PULLUP; verify your exact board before adapting.

Reference checked 9 September 2026. Authored exercise; no physical build result is claimed.

Understand the change

  1. Define the input

    With this pull-up circuit, released reads HIGH and pressed reads LOW. Start released. The example pin is for an Uno, not a universal ESP32 or SmartKnob pin assignment.

  2. Read a bouncing trace

    Try LOW at 100 ms, HIGH at 105 ms and LOW at 110 ms. No press is accepted until LOW has lasted 30 ms, at 140 ms or the next loop check.

  3. Separate an edge from a level

    Keep the button held. Mode changes once, not on every pass through loop. Release long enough to debounce, then press again to return to slow mode.

  4. Compare both tasks

    Slow mode toggles the output every 500 ms; fast mode every 125 ms. Button handling continues in both. Record any missed or duplicate actions before considering a more complex control project.

THE BRIEF

A focused request to try

Use this with a suitable AI assistant. Its response will vary; compare it with the checks below.

Extend a non-blocking LED sketch with an active-low button on Uno pin 2 using INPUT_PULLUP. Accept a new button state only after it stays unchanged for 30 ms. Toggle slow/fast mode on the debounced falling edge only, not while held. Keep LED timing non-blocking. Explain the starting state and make no claim this pin maps to SmartKnob.
THE REFERENCE

Worked reference example

Read the example, predict one change, then check the result.

const int buttonPin = 2; // Arduino Uno example only.
const unsigned long debounceMs = 30;
bool rawLast = HIGH, stable = HIGH, fast = false, led = false;
unsigned long rawChangedAt = 0, ledChangedAt = 0;
void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  rawLast = stable = digitalRead(buttonPin);
  rawChangedAt = ledChangedAt = millis();
}
void loop() {
  const unsigned long now = millis();
  const bool raw = digitalRead(buttonPin);
  if (raw != rawLast) {
    rawLast = raw;
    rawChangedAt = now;
  }
  if (raw != stable && now - rawChangedAt >= debounceMs) {
    stable = raw;
    if (stable == LOW) fast = !fast;
  }
  const unsigned long interval = fast ? 125 : 500;
  if (now - ledChangedAt >= interval) {
    led = !led;
    ledChangedAt = now;
    digitalWrite(LED_BUILTIN, led ? HIGH : LOW);
  }
}
TRY THE WORKING EXAMPLE

Inspect a bouncing input

Step through a model of the logic. This does not run or validate physical hardware.

EVENT TRACE

TimeEvent

Check your result

  • The bouncing example produces one accepted press at about 140 ms.
  • Holding the button produces no further mode changes.
  • A debounced release followed by a new press produces one more change.
  • The LED task continues while the button state is being checked.

Where this can go wrong

The 30 ms interval is an authored exercise setting, not a guarantee for every switch. This sketch is not SmartKnob firmware and must not replace its motor-control loop.

Go to the source

Arduino Debounce. Confirm current tool instructions before using them.

Tell us where this exercise was unclear