Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 64 additions & 20 deletions src/helpers/sensors/EnvironmentSensorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class RAK12500LocationProvider : public LocationProvider {
int _sats = 0;
long _epoch = 0;
bool _fix = false;
unsigned long _next_poll = 0;
public:
long getLatitude() override { return _lat; }
long getLongitude() override { return _lng; }
Expand All @@ -193,16 +194,45 @@ class RAK12500LocationProvider : public LocationProvider {
void begin() override { }
void stop() override { }
void loop() override {
if (ublox_GNSS.getGnssFixOk(8)) {
// Throttle the I²C poll to ~1 Hz. The getXxx() calls below each issue a
// synchronous ublox poll that blocks up to its maxWait; the GNSS solution only
// updates at the 1 Hz navigation rate (setMeasurementRate(1000)), so polling on
// every main-loop iteration just burns the loop on redundant I²C round-trips —
// that stall is what made the AIN1 button sluggish and drop double-clicks.
// Polling once per nav epoch keeps the fix/time fresh while leaving the loop
// free for button sampling the rest of the time.
if (millis() < _next_poll) {
return;
}
_next_poll = millis() + 1000;

// The numeric arg is maxWait (ms) for the I²C poll, not a field index.
// The previous 2/8 ms values were below the ublox response window, so polls
// routinely timed out and returned stale/garbage PVT data (observed: random
// wrong-hemisphere longitudes despite getGnssFixOk() returning true).
// 250 ms is a ceiling; a responsive module returns well before that. getPVT()
// does the single poll here, then every getter reads that same cached packet
// (passing no maxWait, so they never re-poll). Gating all reads on getPVT()
// succeeding matters: if the poll times out, a getter with a stale cache would
// otherwise fire its own poll at the library default (~1100 ms) and stall hard.
if (!ublox_GNSS.getPVT(250)) {
return; // no response this tick — keep last reported values
}

// Require BOTH gnssFixOK (DOP/accuracy mask passed) AND fixType==3 (3D fix).
// Ublox reports gnssFixOK=true with bogus coords during cold start (e.g. an
// unfixed module on first boot reporting coordinates from factory almanac);
// requiring fixType==3 filters those out.
if (ublox_GNSS.getGnssFixOk() && ublox_GNSS.getFixType() == 3) {
_fix = true;
_lat = ublox_GNSS.getLatitude(2) / 10;
_lng = ublox_GNSS.getLongitude(2) / 10;
_alt = ublox_GNSS.getAltitude(2);
_sats = ublox_GNSS.getSIV(2);
_lat = ublox_GNSS.getLatitude() / 10;
_lng = ublox_GNSS.getLongitude() / 10;
_alt = ublox_GNSS.getAltitudeMSL(); // height above mean sea level, not ellipsoid
_sats = ublox_GNSS.getSIV();
} else {
_fix = false;
}
_epoch = ublox_GNSS.getUnixEpoch(2);
_epoch = ublox_GNSS.getUnixEpoch();
}
bool isEnabled() override { return true; }
};
Expand Down Expand Up @@ -787,16 +817,25 @@ void EnvironmentSensorManager::rakGPSInit(){
//search for the correct IO standby pin depending on socket used
if(gpsIsAwake(WB_IO2)){
}
else if(gpsIsAwake(WB_IO4)){
}
else if(gpsIsAwake(WB_IO5)){
}
else{
MESH_DEBUG_PRINTLN("No GPS found");
gps_active = false;
gps_detected = false;
Serial1.end();
return;
else {
// WB_IO2 controls the 3V3_S switched peripheral rail on these RAK boards.
// gpsIsAwake() leaves the pin as INPUT on failure, which drops the rail and
// takes I²C peripherals (RTC, display, the GPS itself) down with it.
// Restore it before probing other sockets.
pinMode(WB_IO2, OUTPUT);
digitalWrite(WB_IO2, HIGH);

if(gpsIsAwake(WB_IO4)){
}
else if(gpsIsAwake(WB_IO5)){
}
else{
MESH_DEBUG_PRINTLN("No GPS found");
gps_active = false;
gps_detected = false;
Serial1.end();
return;
}
}

#ifndef FORCE_GPS_ALIVE // for use with repeaters, until GPS toggle is implimented
Expand Down Expand Up @@ -890,6 +929,7 @@ void EnvironmentSensorManager::loop() {

#if ENV_INCLUDE_GPS
static long next_gps_update = 0;
static uint8_t gps_debug_skip = 0; // throttle: print roughly every 10th update tick
if (gps_active) {
_location->loop();
}
Expand All @@ -900,17 +940,21 @@ void EnvironmentSensorManager::loop() {
if ((i2cGPSFlag || serialGPSFlag) && _location->isValid()) {
node_lat = ((double)_location->getLatitude())/1000000.;
node_lon = ((double)_location->getLongitude())/1000000.;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
node_altitude = ((double)_location->getAltitude()) / 1000.0;
MESH_DEBUG_PRINTLN("lat %f lon %f alt %f", node_lat, node_lon, node_altitude);
if (gps_debug_skip-- == 0) {
gps_debug_skip = 9;
MESH_DEBUG_PRINTLN("lat %f lon %f alt %f", node_lat, node_lon, node_altitude);
}
}
#else
if (_location->isValid()) {
node_lat = ((double)_location->getLatitude())/1000000.;
node_lon = ((double)_location->getLongitude())/1000000.;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
node_altitude = ((double)_location->getAltitude()) / 1000.0;
MESH_DEBUG_PRINTLN("lat %f lon %f alt %f", node_lat, node_lon, node_altitude);
if (gps_debug_skip-- == 0) {
gps_debug_skip = 9;
MESH_DEBUG_PRINTLN("lat %f lon %f alt %f", node_lat, node_lon, node_altitude);
}
}
#endif
}
Expand Down
3 changes: 3 additions & 0 deletions variants/rak3401/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ build_flags = ${nrf52_base.build_flags}
${sensor_base.build_flags}
-I variants/rak3401
-D RAK_3401
-D RAK_BOARD
-D NRF52_POWER_MANAGEMENT
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D SX126X_REGISTER_PATCH=1 ; Patch register 0x8B5 for improved RX with SKY66122 FEM
-D FORCE_GPS_ALIVE ; on RAK3401, gpsResetPin ends up = WB_IO2 (kills 3V3_S rail) or
; pin 4 (= SX126X_RESET, holds radio in reset). stop_gps() must not run.
build_src_filter = ${nrf52_base.build_src_filter}
+<../variants/rak3401>
+<helpers/sensors>
Expand Down