Skip to content

feat: Enable GPS on RAK 1W kit 🤖🤖#2640

Open
disq wants to merge 3 commits into
meshcore-dev:devfrom
disq:gps-fixes
Open

feat: Enable GPS on RAK 1W kit 🤖🤖#2640
disq wants to merge 3 commits into
meshcore-dev:devfrom
disq:gps-fixes

Conversation

@disq
Copy link
Copy Markdown

@disq disq commented May 28, 2026

Re-application of #2401

Tested on RAK3401 + RAK12500 in SLOT A (UART / I2C Communication)
At the time of testing, the RAK19007 board also had RAK13302 (1W) and RAK12002 (RTC)

disq and others added 2 commits May 28, 2026 16:18
Three related issues hit by RAK3401 + RAK19007 + RAK12500 (I²C ublox).

1. -D RAK_BOARD restored on [rak3401].
   It was removed in 68363d9 (revert of meshcore-dev#2401) with the symptom
   "RadioLib error -707", because adding RAK_BOARD enables rakGPSInit(),
   whose WB_IO4 fallback probe pulses pin 4 (= SX126X_RESET on RAK3401)
   LOW for 500 ms — hard-resetting the SX1262 after radio_init() has
   already configured it, and (via stop_gps + gpsResetPin = WB_IO4)
   leaving it held in reset afterwards.
   Without RAK_BOARD, RAK_WISBLOCK_GPS isn't auto-defined, the I²C
   ublox path is unreachable, and the firmware falls back to
   Serial1-NMEA detection — which silently fails on a serial-less
   RAK12500. Fixes 2 and 3 below make RAK_BOARD safe to re-enable.

2. RAK12500LocationProvider passed maxWait of 2/8 ms to getLatitude()
   etc. These are below the ublox I²C response window, so the polls
   routinely timed out and the SparkFun library returned stale/garbage
   PVT bytes. Observed: getGnssFixOk() returning true with a current
   latitude but a longitude from some previous fix. Bumped to 250 ms.
   Also switched getAltitude() (height above WGS84 ellipsoid) to
   getAltitudeMSL() for more intuitive altitude readings.

3. rakGPSInit() probes WB_IO2 first. On failure, gpsIsAwake() leaves
   the probed pin as INPUT. WB_IO2 also controls the 3V3_S switched
   peripheral rail on these RAK base boards, so a failed first probe
   left I²C peripherals (RTC, display, the GPS itself) unpowered
   before the WB_IO4/WB_IO5 fallbacks ran. The else-branch now
   restores WB_IO2 HIGH before falling through.

   On RAK3401, those fallback probes (WB_IO4 = pin 4 = SX126X_RESET,
   WB_IO5 = pin 9 = SX126X_BUSY) are also dangerous, see point 1.
   Adding -D FORCE_GPS_ALIVE in the RAK3401 base env skips stop_gps()
   after detection, so even if gpsResetPin ends up = WB_IO2 (kills
   the rail) or pin 4 (= radio reset), it can't be pulled LOW again
   after init.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The loop() function printed lat/lon, then computed altitude, then
printed lat/lon/alt — making the first print pure noise. Every
gps_update_interval_sec (default 1 s) the log got two near-identical
lines, drowning out anything else when MESH_DEBUG=1 is on.

Drop the first MESH_DEBUG_PRINTLN entirely (in both the RAK_WISBLOCK_GPS
and the non-RAK branches). Throttle the surviving lat/lon/alt line to
roughly every 10th update via a static skip counter, so a debug build
gets a position sample every ~10 s instead of every second while still
covering the typical GPS visibility window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
_lng = ublox_GNSS.getLongitude(2) / 10;
_alt = ublox_GNSS.getAltitude(2);
_sats = ublox_GNSS.getSIV(2);
_lat = ublox_GNSS.getLatitude(250) / 10;
Copy link
Copy Markdown

@jakymiwm jakymiwm May 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the "/ 10" and add it below?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this will diverge the code paths between other branches: It normalises ublox's native 1e-7 degree integer down to the implicit LocationProvider interface contract of microdegrees (1e-6).
Touching these has no real benefit other than complicating things, even if we changed it everywhere else. It won't be any faster or any better.

Comment thread src/helpers/sensors/EnvironmentSensorManager.cpp
Comment thread src/helpers/sensors/EnvironmentSensorManager.cpp
Comment thread src/helpers/sensors/EnvironmentSensorManager.cpp
Comment thread src/helpers/sensors/EnvironmentSensorManager.cpp
Comment thread src/helpers/sensors/EnvironmentSensorManager.cpp
@disq disq changed the title feat: Enable GPS on RAK 1W kit feat: Enable GPS on RAK 1W kit 🤖🤖 May 28, 2026
Ublox modules sometimes report gnssFixOK=true with bogus coordinates
during cold start, before any actual fix has been acquired — e.g.
factory-almanac defaults that look like real positions. Observed: an
unfixed module reporting plausible-looking but wrong-hemisphere
coordinates persistently, with _location->isValid() returning true.

Tighten RAK12500LocationProvider::loop() to require BOTH gnssFixOK
(DOP/accuracy masks satisfied) AND fixType == 3 (3D fix). fixType
values: 0=no fix, 1=dead reckoning only, 2=2D, 3=3D, 4=GNSS+DR,
5=time only. Only the 3D fix is a position we want to publish.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants