Trying to Get LoRa Working Between Two FPM-T Units

I’m trying to get the internal LoRa radios working between two FPM-T units running as a base and rover pair. The rover seems to ignore the configuration and is trying to use the external radio interface rather than the internal LoRa radio.

The base is configured in fixed/static position mode.

Both units are running ESP32 firmware version d3.4 and LoRa firmware version 3.0.1.

Both units are configured the same in their Configure Radios menu:

ESP-NOW Radio: Disabled
LoRa Radio: Enabled
LoRa Coordination Frequency: 910.000
LoRa Transmit Gain: 10dB
LoRa Save Settings to Flash: Disabled

With Print LoRa Debugging enabled on the base unit, I see these messages on the serial console at startup (unrelated messages edited out):

Radio Ext corrections: disabled -> enabled (Forced)
STATE_BASE_NOT_STARTED --> STATE_BASE_CONFIG_WAIT
Mode: Base fixed Geodetic
Begin LoRa
LoRa firmware: 3.0.1
Getting LoRa radio attributes
RADIO_ATTR:
version: 301
mode:    4
freq tx: 915000000
freq rx: 915000000
bps:     38400
bwid tx: 250
bwid rx: 250
power:   10
dprt:    1

OK
Base Mode - SIV: 20
Base configured
STATE_BASE_CONFIG_WAIT --> STATE_BASE_FIXED_NOT_STARTED, 2026-07-06 20:43:41.116
Mode: Base fixed Geodetic
LoRa: Moving to TX
LoRa radio configured for transmitting
Base Mode - SIV: 20
STATE_BASE_FIXED_NOT_STARTED --> STATE_BASE_FIXED_TRANSMITTING, 2026-07-06 20:43:43.831
LoRa should have transmitted 0 RTCM bytes
Base Mode - SIV: 20
LoRa should have transmitted 1401 RTCM bytes

and these messages repeating during operation:

LoRa should have transmitted <xxxx> bytes

The base unit’s OLED display shows the base (“fortress”) icon and “Xmitting RTCM” with increasing values.

On the rover unit, with Print Correction Debugging and Print LoRa Debugging both enabled, I see these messages at startup (unrelated messages edited out):

Radio Ext corrections: disabled -> enabled (Forced)
STATE_ROVER_NOT_STARTED --> STATE_ROVER_CONFIG_WAIT
Mode: Rover
Begin LoRa
LoRa firmware: 3.0.1
Getting LoRa radio attributes
RADIO_ATTR:
version: 301
mode:    4
freq tx: 915000000
freq rx: 915000000
bps:     38400
bwid tx: 250
bwid rx: 250
power:   10
dprt:    1

OK
Rover Accuracy (m): 2.938, SIV: 18 GNSS State: DGPS Fix
Rover configured
STATE_ROVER_CONFIG_WAIT --> STATE_ROVER_NO_FIX, 2026-07-06 20:27:12.068
LoRa: Moving to RX Dedicated
LoRa radio configured for receiving

The rover unit’s Configure Corrections Priorities menu shows an asterisk on the External Radio line, along with “active”, and a Last Seen values that ranges up to about 15 Sec. The LoRa Radio line shows “inactive”. I moved the LoRa line up to Priority 0 from the default position; either way, the results were the same.

The rover unit’s OLED display shows the Handheld Radio icon (external radio) rather than the Broadcast Tower icon (LoRa radio).

And, the rover never indicates either RTK Float or RTK Fix status.

This behavior is similar to that described in this SparkFun forums topic:

https://community.sparkfun.com/t/base-rover-setup-with-original-rtk-torch-and-sparkpnt-fpm-t/68989/8

but that seemed to be a firmware mismatch problem, which isn’t the case with my two FPM-T units.

Taking a very quick look at GNSS_Mosaic.ino in the RTK Everywhere firmware source code, in the method GNSS_MOSAIC::begin(), I’m intrigued by this line and its comments:

// Set COM2 (Radio) protocol(s)
// Both Ext Radio and LoRa need RTCM on UART2
// Note: this is probably redundant? I'm now not sure why I added it...
setCorrRadioExtPort((settings.enableExtCorrRadio || settings.enableLora), true); // Force the setting

Ideas, anyone? Thanks!

Hi @wjc ,

As always - apologies for the hassle. Let’s see if we can work out what is not working.

I can’t (yet) explain why your Rover isn’t getting Float / Fix.

But I can explain why “External Radio” appears to be delivering the corrections:

Actually it isn’t. LoRa is, or should be. On FPM-T, LoRa corrections will always be reported as External Radio. The mis-reporting of the correction source is just a limitation of the firmware. I have looked at this and, at the moment, I don’t have a good solution…

On Torch, reporting the LoRa corrections is ‘easy’ because the LoRa traffic is routed through the ESP32. The ESP32 passes-through the LoRa RTCM messages from the LoRa chip to the GNSS. The ESP32 can monitor the RTCM message byte counts, and - importantly - can stop the pass-through if LoRa is not the highest priority corrections source.

On Facet FP, LoRa and External Radio traffic is routed directly to the GNSS UART2. An electronic switch selects between the LoRa chip UART and the External Radio JST connector. The mosaic GNSS is able to monitor the arrival of RTCM on its UART2. It reports this to the ESP32 through an SBF message. So, the GNSS is able to tell the ESP32 that RTCM is arriving. But only the ESP32 knows which way the electronic switch is set, so only it knows if these corrections come from LoRa or External Radio.

On Facet FPL(-T), the LG290P does not support a similar how-many-RTCM-bytes-are-arriving-on-this-UART message. On Facet FPL(-T), if LoRa or External Radio is enabled, we have to assume that RTCM is arriving because we have no way of knowing if it actually is - or not.

It gets complicated when we start to consider disabling the LoRa (or External Radio) corrections if they are not the highest priority. We can do that on Facet FPM because we know if corrections are actually arriving. If they are arriving and are not the highest priority, we can disable them via the UART2 protocols. But we can’t do that on Facet FPL. On FPL, the priority decides if the RTCM protocol is enabled, or not.

Right now, I don’t have a good solution that covers all the possibilities.

So, thinking about your issue, I’m wondering if it could be caused by the External Radio corrections priority. Does everything start working if you increase the priority of External Radio back to 0 (top of the list)?

In summary: set External Radio back to priority 0; ensure LoRa is enabled; ensure External Radio is not enabled.

I hope this helps,

Paul

@PaulZC , the first thing I noticed from the clips was that 910 Hz was requested, but 915 Hz was used by the FPM.

@Ryan.F :

Yes - thanks. I’m not concerned about that. The RADIO_ATTR report is based on what is stored in the LoRa chip’s internal flash memory. It does not necessarily reflect what frequency is set by the ESP32 based on the RTK Everywhere Firmware settings. 915MHz is the default for the LoRa firmware itself. 910MHz is the default for RTK Everywhere. The freq tx / rx would be reported correctly after the next power cycle only if “13) LoRa Save Settings to Flash” has been enabled in the radio menu.

I hope this helps,

Paul

Hi, Paul (@PaulZC):

Thank you for the prompt response!

After trying some further tests subsequent to your response, I’ve determined that this was a case of operator error, compounded by UI behavior that doesn’t match the SparkPNT documentation.

Yesterday, I had been preparing for a project in which I’d have the base FPM-T set up on a monument with known coordinates. I had configured that unit to be in fixed base mode, with that monument’s coordinates. However, for my initial test of LoRa connectivity, I did not have the base unit actually on the monument — I was running it about 70 meters away from the monument, where I could conveniently have a computer for serial configuration and status monitoring.

I had wondered if that might impair RTK convergence, vs simply introducing a position offset during that initial test. However, when I saw the rover unit displaying indications that it thought the External Radio was in use rather than the LoRa Radio (e.g. showing the Handheld Radio icon rather than the Broadcast Tower icon, as described in the documentation), I figured something more fundamental was going wrong and I went off on that detour.

I’ve now tried another test, running the base unit in survey-in mode, and the rover achieved RTK Fix within seconds. Switching the base back to fixed base mode, the rover once again didn’t even get into RTK Float. Evidently, 70 meters is enough of an offset to prevent any RTK convergence. We’re having significant rain here today, so setting up on the monument to again try fixed base mode will have to wait.

An edit of the documentation ( Display | SparkPNT FPM-T Product Manual ) is needed.

I still have a question about the Last Seen values shown in the Configure Corrections Priorities menu. Even with the rover receiving messages over LoRa and getting into RTK Fix, I’m seeing the Last Seen value for the External Radio repeatedly counting up from zero to about 15 seconds. This seems odd, given the base unit’s RTCM messages settings:

GNSS Messages / Set Base RTCM Messages: all intervals = 1.0 except RTCM1033 = 10.0; RTCM1005, RTCM1033, and MSM4 enabled (no others)

Configure Base / Set RTCM Message Rates for Base Mode / Set RTCM Messages for Base Mode: same as above

I could imagine the rover showing Last Seen values ranging up to 1 second, 10 seconds, or never, but why 15 seconds?

Also, there’s one point in your response that I’m curious about:

Is there a setting for disabling / enabling the External Radio? In Configure Radios, the only disable / enable items I see are for ESP-NOW Radio and LoRa Radio.

Thank you for your help!

--Bill

Hi Bill (@wjc ),

Many thanks for this. It’s clear we need to take another look at LoRa vs. External Radio corrections reporting on Facet FP. I’ve opened an issue for this on GitHub here.

The last-seen sawtoothing between 0 and 15 seconds is expected. That’s to do with how often we call isCorrRadioExtPortActive. There is a setting named correctionsSourcesLifetime_s which defaults to 30 seconds. We call isCorrRadioExtPortActive twice per that lifetime, i.e. every 15 seconds. The last-seen value isn’t really last-seen, in this case it is last-checked. For other correction sources (Bluetooth, USB, ESPNow) last-seen really does mean last-seen. But sadly not in this case.

The External Radio settings are in the Ports Menu, not Configure Radios. Humm. It looks like what I said earlier about ensuring External Radio is disabled was not correct. Looking at the code, if LoRa is enabled on Facet FP: the GNSS UART2 RTCM protocol is enabled, and the electronic switch is set to the LoRa position. It probably doesn’t matter if Allow incoming corrections on Ext Radio is enabled or not. The LoRa setting will override this. But this is clearly something I should check when I look again at the corrections reporting.

Please do keep sending us feedback about this and any similar issues. We truly value the feedback. And if something is not right, or not clear, we’ll do our best to fix it.

Best wishes,
Paul

Good morning, Paul (@PaulZC).

Thank you for the further explanations. Now that yesterday’s 3 inches of rain are finished, I’m going to try my base-rover + LoRa project today. Some cleanup in the documentation and perhaps in the firmware is needed, but at least the functionality really is there.

If you think it’s appropriate, I’d be willing to edit the Display | SparkPNT FPM-T Product Manual web page to add a note explaining the current, actual behavior of the OLED UI when using LoRa (“As of [date] / [firmware rev], when using LoRa on the FPM-T…”). That could avoid sending other customers and SparkPNT staff on detours. I could also do that for the corresponding FPM page; I don’t have access to an FPM, but I have to believe the behavior is the same.

However, I see that clicking the “Edit this page” link on the above page yields a 404.

--Bill