Skip to content

Unreliable button input: missed presses and phantom triggers on PCB #29

Description

@ololonly

Symptom

On the assembled PCB the physical button (Button1) works unreliably: sometimes a press is ignored, sometimes phantom/false presses fire on their own. Right after a fresh re-solder of the ESP mount (which had a ground pad shorting to an unused, unconnected pin) the button worked perfectly — then regressed after a couple of days. This points strongly at a hardware/solder root cause, but the firmware also has no protection against marginal input.

Hardware hypotheses (likely primary)

  • Cold / marginal solder joints on the button trace or the ESP mount that drift with thermal cycling and time.
  • Flux residue or oxidation creating high-resistance leakage paths around GPIO12.
  • The internal pull-up alone may be too weak to hold the line high if GPIO12 leaks toward GND through a contaminated joint.
  • Floating neighbouring pins coupling noise into the button net.

Suggested checks: reflow and clean (IPA) the ESP mount and button traces, verify there are no solder bridges, confirm a solid ground, and consider an external ~10k pull-up plus a small (~100nF) hardware debounce cap to GND.

Firmware contributing factors

The firmware does nothing to reject electrical noise, which makes marginal hardware much worse:

  • No software debounce. ButtonState::update (src/button.rs:52-79) only records pressed_at on the first "down" and fires the callback on release (<500ms = Short, >=500ms = Long). Any contact bounce or noise on the line can register as spurious presses.
  • Variable polling cadence. The main loop polls button1.is_low() every iteration (src/setup.rs:200) but only yields via FreeRtos::delay_ms(0) (src/setup.rs:321), so the effective sampling rate floats with render / UART / MQTT load — presses can be missed or doubled.
  • The InterruptType::NegEdge interrupt is registered (src/setup.rs:98-110) but never actually used; input is pure polling.

Proposed firmware mitigations (future, not in this issue)

  • Add software debounce: require the level to be stable for ~20–30ms before accepting a transition.
  • Filter press/release edges explicitly instead of firing on a single release sample.
  • Optionally wire up the already-registered NegEdge interrupt.

Notes

This may share an electrical root cause (noise / marginal shared ground from the solder work) with #30. Filed separately for tracking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghardwarephysical components part

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions