Explains the distinct tones used on companion-radio devices for actions like toggle confirmations. Improves user understanding of audio feedback, especially on button-only devices.
Before this commit, there was no way to set a different max hop count
for unscoped messages.
Now with this change, by defaul it tracks the flood.max setting, until
a user provides a flood.max.unscoped value, which tax precidence for
packets if ROUTE_TYPE_FLOOD is true.
Ensures the RTTTL player has a persistent buffer for melody data. The player stores a pointer to the melody, which requires the buffer to outlive the function call. A static buffer guarantees this, preventing issues from accessing deallocated memory. This is safe as concurrent playback is not supported.
Adjusts the duration and tempo of several buzzer melodies to make them more perceptible. Specifically, the advert sent and generic toggle sounds are modified with longer note durations and slower tempos, improving their clarity on typical small piezo speakers.
Give advert and toggleable settings (buzzer, GPS) their own short,
easily distinguishable buzzer tones so users of buzzer-only devices
(e.g. T1000E) can tell events apart by ear.
- genericBuzzer::playToggle(count, enabled): generic, opt-in helper
for the count/direction convention (N notes ascending if enabled,
descending if disabled). Lives next to play()/startup()/shutdown();
any caller can use it, nothing forces it.
- AbstractUITask: virtual notifyToggle(count, enabled) with an empty
default — subclasses that don't care don't override. UIEventType
only gains one event-shaped entry (advertSent), so it doesn't grow
one entry per toggleable setting.
- ui-orig / ui-new / ui-tiny: notify() handles fixed events;
notifyToggle() is a one-line delegate to buzzer.playToggle().
Button presses, home-page actions, toggleBuzzer (3 notes) and
toggleGPS (4 notes) route through notifyToggle().
- Preserve existing silent-when-connected behavior for incoming
contact messages: when the companion app is connected it handles
user notification, so the device stays quiet.
- Fix mute-confirmation bug: hold mute until the off-tone finishes
so the user actually hears it when disabling the buzzer.
AUTO_OFF_MILLIS is a power-save feature aimed at battery use. When the
board reports isExternalPowered() == true (USB or other DC source),
blanking the screen serves no purpose — there's nothing to conserve.
But OLEDs are vulnerable to burn-in with static content, so this
behaviour is gated behind a new build flag KEEP_DISPLAY_ON_USB. Default
is unchanged from upstream — the display blanks after AUTO_OFF_MILLIS
on USB or battery. Variants that ship with an LCD instead of an OLED
(e.g. heltec_t096) can opt in by adding -D KEEP_DISPLAY_ON_USB to
their env, gaining always-on-while-powered without exposing OLED users
to burn-in risk.
When the flag is enabled, the implementation refreshes _auto_off every
loop iteration while externally powered, so the timer naturally counts
a fresh AUTO_OFF_MILLIS window from the moment power is removed —
no instantaneous-blank-on-unplug.
Applied to all three companion_radio UI flavours (ui-new, ui-tiny,
ui-orig). Boards without an isExternalPowered() override use the
base-class default in MeshCore.h (returns false), so battery-powered
behaviour is unchanged everywhere.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>