mari: channel hopping for beacons and scanning#165
Merged
Conversation
Gateway TX and a synced node's beacon-slot RX both derive the channel from the cell's channel_offset, so they rendezvous with no extra coordination. Unsynced scanning still uses MARI_FIXED_SCAN_CHANNEL, so cold join is not fully diversified yet. Toggle via MARI_ENABLE_BEACON_HOPPING. AI-assisted: Claude Opus 4.8
AI-assisted: Claude Opus 4.8
Each cold-scan round dwells ~one slotframe on a single advertising channel and syncs to the first gateway heard; a round that finds nothing retries on the next channel (37/38/39), so a faded channel is escaped within a round or two. Reuses the existing scan-retry loop, no sweep-then-pick. Background scan still uses the fixed channel. AI-assisted: Claude Opus 4.8
Reuses slotframe_counter (new mr_scheduler_get_slotframe_counter accessor) to listen on 37 + counter%3 each bg-scan burst. A full handover scan spans one slotframe so it covers one channel; successive slotframes sweep all three, finding a neighbour on any non-faded channel within ~3 slotframes. Gated by MARI_ENABLE_BEACON_HOPPING. AI-assisted: Claude Opus 4.8
Contributor
Author
|
Tested with 100 nodes under different configurations. Yet to test handover case. |
Contributor
Author
|
Handover works! |
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.
Nodes could drop and then get stuck rescanning for many seconds, only recovering
when the RF environment changed (someone moving nearby, etc). Root cause: data
slots already hop channels, but the entire beacon/join path was pinned to one
frequency (MARI_FIXED_SCAN_CHANNEL = 37 / 2402 MHz). A static multipath null at
that frequency at a node's location traps a rescanning node - it cannot hear a
single beacon until the environment shifts. No frequency diversity, no way out.
This gives the beacon/join path the same frequency diversity the data slots
already have, in three parts, all behind one build flag (MARI_ENABLE_BEACON_HOPPING
in models.h; with it off, behaviour is unchanged and everything stays on
MARI_FIXED_SCAN_CHANNEL, so it is an easy A/B on a logic analyzer):
advertising channel (cell offset 0 -> 37, 1 -> 38, 2 -> 39). Gateway and synced
nodes both derive the channel from the cell, so they rendezvous with no extra
coordination.
first gateway it hears; a round that finds nothing retries on the next channel,
so a faded channel is escaped within a round or two. Reuses the existing
scan-retry loop (no sweep-then-pick), and selecting per round keeps every
reading inside mr_scan_select's freshness window.
slotframe_counter, so successive slotframes sweep all three channels and a
neighbour is found on any non-faded channel within ~3 slotframes.
Known follow-up (cosmetic): the synced-RX beacon from a node's own gateway still
records its RSSI under the fixed channel rather than the real received channel.
That entry is excluded from handover selection and the hysteresis reads RSSI from
the received packet (not the scan list), so no decision changes.
Validated: node (nRF52840) and gateway (nRF5340) build clean via SES; testbed
validation underway.