Skip to content

RAK3401: reliable AIN1 button β€” interrupt latch, debounce, digital read, instant screen-on πŸ€–πŸ€–#2652

Draft
disq wants to merge 1 commit into
meshcore-dev:devfrom
disq:rak3401-ain1-button-reliability
Draft

RAK3401: reliable AIN1 button β€” interrupt latch, debounce, digital read, instant screen-on πŸ€–πŸ€–#2652
disq wants to merge 1 commit into
meshcore-dev:devfrom
disq:rak3401-ain1-button-reliability

Conversation

@disq
Copy link
Copy Markdown

@disq disq commented May 31, 2026

Problem

The RAK3401 companion build has a single user button on AIN1, driven by analogRead() polled once per main-loop iteration β€” there is no interrupt serving it. Symptoms:

  • Presses dropped when the loop briefly stalls (LoRa RX/TX, BLE, flash writes).
  • Single clicks feel laggy: the screen only wakes after the multi-click window expires.

Changes

MomentaryButton (generic)

  • Configurable multi-click window on the analog constructor (default unchanged).
  • reset() β€” abandon the in-flight gesture.
  • enableInterrupt() β€” permanent FALLING-edge GPIOTE interrupt that latches presses so they survive loop stalls (and can wake the MCU where the platform sleeps on interrupts). Debounced: one count per press, re-armed only after check() sees a clean release (rejects press/release contact bounce). Skipped for analog/SAADC-threshold buttons (GPIOTE vs analogRead conflict on the same pin).

companion_radio UITask

  • Wake the display instantly on the press edge when it's off, instead of after the multi-click window.
  • Arm the button interrupt at startup for PIN_USER_BTN_ANA boards.

variants/rak3401

  • Read AIN1 digitally (active-low, internal pull-up) instead of via SAADC β€” digitalRead coexists with the GPIOTE edge interrupt where analogRead does not (analogRead otherwise reads stuck "always pressed" once the interrupt is attached). Multi-click retained: single=NEXT / double=PREV / triple=SELECT / long=ENTER.

Notes for reviewers

Testing

  • Builds clean: RAK_3401_companion_radio_ble, RAK_3401_companion_radio_usb.
  • The same MomentaryButton/UITask/target logic was bench-tested on RAK3401 companion_radio_ble hardware on our integration branch (digital read fixes the SAADC+GPIOTE "always pressed" conflict; presses reliable through loop stalls; single/double/triple/long all work, no dropped or double-counted clicks). This dev port is build-verified and should be re-flashed/re-tested on hardware before merge.

Known edge case

If the loop stalls through the middle of a fast double-click so check() never re-arms between the two presses, the second press is dropped (fails toward "one click", never a phantom extra). Normal clicking is unaffected.

πŸ€– Generated with Claude Code

…ad, instant screen-on

The RAK3401 companion build drives its only user button (AIN1) by polling
analogRead() once per main-loop iteration, with no interrupt. Presses are dropped
whenever the loop briefly stalls (LoRa RX/TX, BLE, flash writes), and a single click
waits out the full multi-click window before the screen wakes.

MomentaryButton (generic):
- Configurable multi-click window on the analog constructor (default unchanged).
- reset(): abandon the in-flight gesture (used to swallow a screen-wake press).
- enableInterrupt(): attach a permanent FALLING-edge GPIOTE interrupt that latches
  presses so they survive loop stalls (and can wake the MCU where the platform sleeps
  on interrupts). Debounced by counting one press per press and only re-arming after
  check() has seen a clean release β€” rejects press/release contact bounce. Skipped for
  analog/SAADC-threshold buttons (GPIOTE and analogRead conflict on one pin).

companion_radio UITask: wake the display instantly on the press edge when it is off
(instead of after the multi-click window), and arm the button interrupt at startup
for PIN_USER_BTN_ANA boards.

variants/rak3401: read the AIN1 button digitally (active-low, internal pull-up)
instead of via SAADC. digitalRead coexists with the GPIOTE edge interrupt where
analogRead does not (analogRead reads stuck-low once the interrupt is attached).
Multi-click retained: single=NEXT / double=PREV / triple=SELECT / long=ENTER.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@disq disq changed the title RAK3401: reliable AIN1 button β€” interrupt latch, debounce, digital read, instant screen-on RAK3401: reliable AIN1 button β€” interrupt latch, debounce, digital read, instant screen-on πŸ€–πŸ€– May 31, 2026
@disq disq marked this pull request as draft May 31, 2026 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant