ThinkNode M6: make GPS usable in the repeater and room server builds - #3288
Open
andyhoobing wants to merge 1 commit into
Open
ThinkNode M6: make GPS usable in the repeater and room server builds#3288andyhoobing wants to merge 1 commit into
andyhoobing wants to merge 1 commit into
Conversation
On a sealed ThinkNode M6 (nRF52840 + soldered-on L76K GNSS, IP65 solar
enclosure) the GNSS could not be used at all:
1. simple_repeater and simple_room_server both default gps_enabled=0, so
sensors.begin() detected the L76K and then immediately powered it back
down via _location->stop() (which drives PIN_GPS_EN low). The M6 has no
button or screen, so there was no way to switch it on short of a USB
console.
2. Both default advert_loc_policy to ADVERT_LOC_PREFS, so adverts carried
the fixed ADVERT_LAT/ADVERT_LON (0,0) and ignored the GNSS entirely.
3. The 1s "is a GPS attached?" probe in initBasicGPS() gates the 'gps'
setting; losing that race leaves GPS unreachable until reboot. The M6
always has the module fitted.
Rather than changing behaviour for every board, the two example defaults
become build-time overridable:
#ifndef GPS_ENABLED_DEFAULT
#define GPS_ENABLED_DEFAULT 0
#endif
#ifndef ADVERT_LOC_POLICY_DEFAULT
#define ADVERT_LOC_POLICY_DEFAULT ADVERT_LOC_PREFS
#endif
Every other board keeps its existing defaults; only the M6 repeater and
room_server envs opt in, and they also skip the GPS probe. Both settings
remain adjustable at runtime via 'gps on'/'gps off' and
'gps advert prefs|share|none'.
Each example declares the defines where it already keeps its ADVERT_*
fallbacks -- MyMesh.cpp for the repeater, MyMesh.h for the room server --
to match each example's own convention.
Verified: ThinkNode_M6_repeater, ThinkNode_M6_room_server,
RAK_4631_repeater and RAK_4631_room_server all build; envdump confirms the
new flags resolve for the M6 envs and are absent for RAK, so other boards
are untouched. Confirmed on real M6 hardware: 'gps -> on, active, fix,
13 sats' with 'gps advert -> share', persisting across reboot.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7b3E6KcBEGZ2zr2jZMrBL
This was referenced Aug 24, 2026
andyhoobing
marked this pull request as ready for review
August 24, 2026 02:35
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.
Split out of #3287 as one self-contained fix, per the one-fix-per-PR guideline.
The companion PR covers the M6 status LED and shares no files with this one.
Problem
On a sealed Elecrow ThinkNode M6 (nRF52840 + SX1262 + soldered-on L76K GNSS,
IP65 solar enclosure) the GNSS could not be used at all:
simple_repeaterandsimple_room_serverboth defaultgps_enabled = 0, sosensors.begin()detected the L76K and then immediately powered it back downvia
_location->stop()(which drivesPIN_GPS_ENlow). The M6 has no buttonor screen, so there was no way to switch it on short of a USB console.
advert_loc_policytoADVERT_LOC_PREFS, so adverts carriedthe fixed
ADVERT_LAT/ADVERT_LON(0,0) and ignored the GNSS entirely.initBasicGPS()gates thegpssetting; losing that race leaves GPS unreachable until reboot. The M6 always
has the module fitted.
Approach
Rather than changing behaviour for every board, the two example defaults become
build-time overridable:
Every other board keeps its existing defaults. Only the M6
repeaterandroom_serverenvs opt in, and they also setENV_SKIP_GPS_DETECT. Bothsettings remain adjustable at runtime via
gps on/gps offandgps advert prefs|share|none.Each example declares the defines where it already keeps its
ADVERT_*fallbacks —
MyMesh.cppfor the repeater,MyMesh.hfor the room server — tomatch each example's own convention rather than imposing one layout on both.
Testing
ThinkNode_M6_repeater,ThinkNode_M6_room_server,RAK_4631_repeaterandRAK_4631_room_serverall build againstdev.pio run -t envdumpconfirms the new flags resolve for the M6 envs and areabsent for the RAK envs, so other boards are provably untouched.
gps -> on, active, fix, 13 sats,gps advert -> share, surviving a reboot.Note for maintainers
One pre-existing behaviour worth being aware of (not changed by this PR): these
compiled defaults only apply to a fresh install. A UF2 update does not erase
InternalFS, so a device that has run MeshCore before keeps its saved prefs and
silently ignores new defaults — it must be reconfigured at runtime or factory
reset. This cost me some debugging and may be worth documenting.
Authored with assistance from Claude (see
Co-Authored-Bytrailers).