RAK3401: reliable AIN1 button β interrupt latch, debounce, digital read, instant screen-on π€π€#2652
Draft
disq wants to merge 1 commit into
Draft
Conversation
β¦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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:Changes
MomentaryButton(generic)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 aftercheck()sees a clean release (rejects press/release contact bounce). Skipped for analog/SAADC-threshold buttons (GPIOTE vsanalogReadconflict on the same pin).companion_radio
UITaskPIN_USER_BTN_ANAboards.variants/rak3401digitalReadcoexists with the GPIOTE edge interrupt whereanalogReaddoes 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
enterLightSleeplives on our integration branch and depends on power-management work not yet upstream β intentionally left out here.)Testing
RAK_3401_companion_radio_ble,RAK_3401_companion_radio_usb.MomentaryButton/UITask/targetlogic was bench-tested on RAK3401companion_radio_blehardware 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