Make a tap trigger one useful response

A tap-to-react object sounds simple until one tap becomes several events, or the next tap arrives while the first response is still playing. For a toy, an exhibit or a workshop prototype, the useful question is what a physical disturbance should mean to the interaction.

Arduino's Reflexes Machine, described on 9 September 2026, is a recent example of designing around a physical response game. Our bench work was smaller: two switch-type vibration inputs and a combined light-and-sound alert, on RP2040 boards with MicroPython programs built in BIPES. It is enough to examine the event before designing the game.

A switch reports contact, not motion magnitude

The SW-520D ball-switch module has a moving contact inside a small can. Our program checked an active-low digital input and printed a trigger message. The saved block program and project file used GPIO6 with pull-up off and a 20 ms pause; our written wiring note named a different pin. We describe the recorded code here, and the connection should be verified on your own board before reuse.

The SW-18010P spring-switch module followed the same polling pattern. Its mechanism is different, but we did not run a controlled comparison of sensitivity between the two. Neither program reports acceleration, direction or a calibrated amount of vibration. Both only say that contact happened.

Mounting matters because it changes what movement reaches the switch. A ball switch is also orientation-sensitive. A loose module on the bench and the same module fastened inside a case can respond differently. Treat orientation and fastening as part of the test record rather than assuming the module name defines the behavior.

Follow the signal into the combined response

Our assembled alert put the spring switch, an LED module and a buzzer on a perforated mounting plate. In the program, an active-low input on GPIO26 started 1 kHz PWM on GPIO7 with a duty value of 800, turned on the LED on GPIO9 and then waited three seconds. The other branch turned both outputs off. The loop also paused 20 ms each pass.

while True:
    if not vib.value():          # active-low trigger
        buzzer.freq(1000)
        buzzer.duty_u16(800)
        led.value(1)
        time.sleep(3)            # nothing else is checked here
    else:
        buzzer.duty_u16(0)
        led.value(0)
    time.sleep_ms(20)

This structure explains an important limit. The three-second wait blocks ordinary polling, and the outputs are cleared only when a later pass reads the input as inactive. A continuously active input does not produce a three-second alert followed by silence; it keeps re-entering the active branch. The terminal message confirmed triggering. It is not evidence of an event queue or a defined rearm policy, because the program has neither.

Decide what the next tap should do

For one response per tap, the program needs three explicit rules:

Ignoring taps during feedback may be right for one experience and frustrating in another. Write the rule before optimizing polling speed. A faster loop does not fix an undefined behavior; it only produces more events.

Switch or motion sensor?

If a digital "something hit it" event is sufficient, these switches are simple and cheap. Test them in the intended mounting with users, and adjust the threshold on the module if it has one. If the product needs the size of a movement, its direction or a gesture, a switch cannot provide it, and an accelerometer such as an IMU module is the better starting point.

Either way, the test to run next is the same: the module fastened where it will live in the product, a set of intended taps, and a set of ordinary handling that should not trigger anything. Count both, and keep the orientation photo with the results.