mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-10-09 11:16:39 +00:00
fix(radio): disable Pwr save (RX duty-cycle) — unsafe across mixed firmware
Field report: a user on the stock SF8 "EU/UK (Narrow)" preset saw reception drop from ~1-5 msg/min to ~1/3h with Pwr save on, unaffected by a better antenna. Root cause, confirmed against the SX1262 datasheet and RadioLib's own maintainers (jgromes/RadioLib#1597, closed as inherent chip behaviour): the SX126x's duty-cycle preamble detection needs the sender's actual preamble to closely match what we've configured our receiver to expect. A mismatch — e.g. a repeater still on pre-v1.16 firmware sending 16 symbols against our 32 — doesn't cost a little sensitivity, it silently drops every packet from that sender regardless of signal strength. There's no local parameter fix: shortening minSymbols to tolerate shorter preambles directly shortens the wake-window's correlator dwell time, trading the preamble mismatch failure mode for a marginal-signal one instead. Checked whether IoTThinks' MeshCore fork solved this differently — it doesn't hit the problem at all, because its "power saving" only light-sleeps the MCU on the radio's own GPIO interrupt and never touches RX duty-cycle. examples/companion_radio/MyMesh.h now defines FEAT_RX_POWERSAVE 0, gating out the Settings row, the Diagnostics RXPS watchdog row, and every call site that would apply rx_powersave to the radio or CAD auto-enable — including forcing setPowerSaving(false) unconditionally so a stale rx_powersave=1 byte from before this change can't do anything either. The real duty-cycle implementation in RadioLibWrapper/CustomSX1262Wrapper is left in place, unneutered, for if a network-wide compatibility mechanism (e.g. the still-unused ADV_FEAT1/FEAT2 advert bits) is ever built to make it safe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,21 @@ public:
|
||||
// minSymbols=8 is the reliable preamble-latch count for SF7-12. If the
|
||||
// configured preamble is too short for a real duty-cycle (senderPreamble <
|
||||
// 2*minSymbols+1), RadioLib transparently falls back to a continuous receive.
|
||||
//
|
||||
// NOT CURRENTLY REACHABLE: FEAT_RX_POWERSAVE (MyMesh.h) is 0, so nothing ever
|
||||
// calls setPowerSaving(true) and this never runs. Left implemented (matching
|
||||
// our own preambleLengthForSF(sf) convention, so it's correct for nodes on
|
||||
// this same convention) rather than removed, because the reason it's disabled
|
||||
// isn't a bug here: the SX126x's duty-cycle preamble detection needs the
|
||||
// *actual transmitted* preamble to exactly match what we assume here, a
|
||||
// confirmed hardware behaviour (SX1262 datasheet 6.1.3; RadioLib issue
|
||||
// https://github.com/jgromes/RadioLib/issues/1597) that no local parameter
|
||||
// choice can work around -- it requires a network-wide compatibility
|
||||
// guarantee we can't currently make. A mismatch doesn't cost a little
|
||||
// sensitivity, it silently drops every packet from that sender regardless of
|
||||
// signal strength (2026-09-22 field report: near-total reception loss on a
|
||||
// stock SF8 preset, unaffected by antenna gain). See MyMesh.h and
|
||||
// docs/development/roadmap.md before ever flipping FEAT_RX_POWERSAVE back on.
|
||||
int16_t startPowerSaveRecv() override {
|
||||
return ((SX126x *)_radio)->startReceiveDutyCycleAuto(preambleLengthForSF(_preamble_sf), 8);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@ protected:
|
||||
// stays in RX to receive the packet (RX_DONE on DIO1) — no MCU state machine,
|
||||
// average RX current cut several-fold. Driven from armRecv()/loop(); falls back
|
||||
// to continuous RX if the modem doesn't support it.
|
||||
// Companion-side gating: FEAT_RX_POWERSAVE (examples/companion_radio/MyMesh.h)
|
||||
// is 0, so nothing on that target ever calls setPowerSaving(true) and this
|
||||
// path never actually runs there -- the SX126x duty-cycle's preamble
|
||||
// detection needs the sender's actual preamble to exactly match what we
|
||||
// configure (confirmed hardware behaviour, not a bug here), which can't be
|
||||
// guaranteed across a mesh with mixed firmware. See that file before
|
||||
// re-enabling it anywhere.
|
||||
bool _power_save = false;
|
||||
bool _ps_active = false; // is the radio currently armed in duty-cycle mode
|
||||
int8_t _tx_dbm = 0; // last TX power applied (tracks APC's live value)
|
||||
|
||||
Reference in New Issue
Block a user