Skip to content

GNSS and gpsd ​

Most boats get their position from a GPS antenna on the NMEA 2000 bus, and nothing in this chapter applies to them.

Some do not. The Brain may have its own GNSS receiver — a USB dongle, a serial module on the board, an LTE modem with GNSS built in — wired to the Brain and invisible to the bus. Or the boat's only chartplotter GPS has failed and there is a spare receiver in a drawer.

This chapter is about that receiver. muxen-nmea2000 can read it, feed it into the navigation report like any other source, and put it on the NMEA 2000 bus so that every chartplotter and instrument on board sees a position again — including ones from manufacturers that have never heard of MUXEN.

That last part is worth being explicit about: this is how a Brain with a USB GPS becomes the boat's GPS.

gpsd does the talking to the hardware ​

The daemon does not open serial ports or speak to receivers directly. It talks to gpsd, the standard Linux GPS daemon, over TCP. gpsd owns the device, handles every receiver protocol there is, and hands out a tidy JSON stream.

That means: if gpsd can see your receiver, so can this daemon; if it cannot, this daemon is the wrong place to debug.

sh
sudo apt install gpsd gpsd-clients
gpspipe -w -n 5 localhost:2947     # does gpsd have data?

GNSS support is compiled in only when libgps was available at build time. If it was not, none of the --source-gpsd* options exist and the daemon rejects them as unknown. Check with muxen-nmea2000 --help.

Reading a receiver ​

sh
muxen-nmea2000 --interface=can1 --name=0x11223344FF467788 \
               --report-nav --source-gpsd
OptionDefaultEffect
--source-gpsdoffenable the gpsd client
--source-gpsd-host HOSTlocalhostgpsd server
--source-gpsd-port PORT2947gpsd port
--source-gpsd-device PATHall devicesuse only this receiver

--source-gpsd-device matters when gpsd is managing more than one receiver. Without it the daemon takes whichever device reports first and stays with it.

The daemon subscribes to gpsd's JSON stream and consumes:

ClassCarries
VERSIONgpsd's protocol version, logged at connect
DEVICESthe list of receivers gpsd is managing
TPVtime, position, altitude, course, speed, fix mode
SKYsatellites in view and dilution-of-precision figures
GSTposition error estimates

A lost connection is retried with an exponential backoff starting at 1 second and capping at 60.

Status on MQTT ​

sh
mosquitto_sub -h 127.0.0.1 -t 'nmea/gpsd' -v

Retained, QoS 0, expireAfterSec 10:

json
{
  "data": { "connected": true, "device": "/dev/ttyUSB0", "fix": "3d" },
  "metadata": { "rxDate": "…", "rxTimestamp": 1736174045, "expireAfterSec": 10 }
}

fix is none, 2d or 3d. device and fix are omitted while disconnected — connected: false on its own is the disconnected state.

Into the navigation report ​

A position from gpsd is fed to the navigation report only once the receiver has a real fix (TPV.mode of 2 or 3). With --nav-high-speed it also feeds the 10 Hz position and course/speed paths.

It arrives under the daemon's own J1939 NAME, because that is the identity the Brain has on the bus. So in muxen-nmea2000-config the gpsd position appears as a source named after the daemon, and it is ranked against the bus GPS receivers with exactly the same priority rules as any other source — see Navigation.

There is no automatic demotion: a gpsd position competes on equal terms unless an installer gives it a priority. If you want the bus GPS preferred, set the priorities.

SKY data is not used by the navigation report; it exists for the transmit path below.

Transmitting onto the bus ​

This is the part that makes the Brain a GPS for the whole boat.

sh
muxen-nmea2000 … --source-gpsd --source-gpsd-transmit

The flag takes an optional mode:

ModeBehaviour
on (the default when the flag is given bare)transmit whenever gpsd has data
failovertransmit only while the bus has no valid GNSS of its own

Add --source-gpsd-transmit-high-speed for the rapid-update PGNs.

The daemon transmits:

PGNNameRateRequires
129029GNSS Position Data1 Hz
129539GNSS DOPs1 Hz
129540GNSS Satellites in View1 Hz
129025Position, Rapid Update10 Hz--source-gpsd-transmit-high-speed
129026COG & SOG, Rapid Update10 Hz--source-gpsd-transmit-high-speed

Transmission is gated on freshness, so a stalled gpsd goes quiet instead of repeating an old fix: 1 Hz PGNs stop after 5 s without a TPV, rapid updates after 1 s, and satellite data after 10 s without a SKY message.

The frames go out under the daemon's claimed address and NAME. The gateway does not acquire a second identity for GNSS — to the rest of the bus, the MUXEN gateway is the thing transmitting position.

Failover mode ​

failover is the mode for a boat that already has a GPS and wants a standby. The Brain stays silent while another device gives the bus a position, takes over when none does, and hands back when one returns.

What counts as a GNSS on the bus. A position received from another device: GNSS Position Data (129029) whose method field reports a fix, or Position, Rapid Update (129025) carrying a latitude and a longitude. A receiver that transmits without a fix does not count. Neither do the Brain's own frames.

Taking over. The Brain starts transmitting when no such position has been received for --source-gpsd-transmit-failover-delay seconds (default 60) and gpsd has a fix. A single valid position from the bus starts the delay again.

Handing back. The Brain stops once valid positions have been coming from the bus for 10 seconds with no gap longer than 5 seconds. During those 10 seconds both positions are on the wire. A receiver that comes and goes — a fix for a few seconds, then nothing — never completes them, so it does not silence the Brain. After handing back, the Brain needs the whole delay again before it takes over a second time.

At startup. The delay runs from the moment the daemon has claimed its address on the bus, at startup and again after a bus failure. A Brain that starts on a boat with a working GPS therefore never transmits; on a boat without one it starts when the delay has passed.

Sixty seconds is a deliberate default. A GPS receiver that reboots, or whose antenna is briefly shaded, can be silent for tens of seconds and come back on its own; a shorter delay makes the Brain start transmitting into a bus that already has a working GPS, and now there are two positions on the wire.

The shortest delay is 5 seconds, because a receiver is only considered lost after 5 seconds of silence — the rule the navigation report applies to a position source (Navigation). A value of 1 to 4 behaves as 5. 0 is accepted and selects the default of 60 seconds.

Option dependencies ​

The daemon refuses to start rather than silently ignoring a flag:

Config: --source-gpsd-transmit requires --source-gpsd
Config: --source-gpsd-transmit-high-speed requires --source-gpsd-transmit
Config: --source-gpsd-transmit mode must be 'on' or 'failover', got 'yes'
Config: --source-gpsd-transmit-failover-delay must be non-negative

Before you turn transmit on ​

Putting a second GNSS source on an NMEA 2000 bus is a real change to the boat, not a monitoring setting.

  • Two GPS sources is a decision, not an accident. Every plotter on the bus will see both and each will choose for itself. Some choose badly. On a boat with a working GPS, prefer failover.
  • The bus is 250 kbit/s and shared. 129540 with a full satellite list is a large Fast Packet message; at 1 Hz alongside 10 Hz rapid updates, this is real traffic on a busy bus.
  • A USB GPS is not a marine GPS. No differential corrections, no integrity monitoring, no reference-station information, and a timestamp only as good as the dongle. It is a good standby and a poor primary.
  • Check what the plotters do. Transmit onto the bus at the dock, and confirm on each display that the position is right and the source is the one you expect, before relying on it.

Diagnostics ​

sh
journalctl -u muxen-nmea2000 -f
mosquitto_sub -h 127.0.0.1 -t 'nmea/gpsd' -v
candump can1 | grep 19F805          # PGN 129029 leaving the Brain

--verbose-gpsd logs the connection, the device and the fix state; without it the gpsd path is nearly silent. --verbose-control logs the transmit lifecycle, including the moment failover takes over and the moment it hands back.

If nmea/gpsd says connected: false, the problem is between the Brain and gpsd, not on the CAN bus. If it says fix: none, the problem is the antenna. See Troubleshooting.

Integration of multiplexed solutions
MUXEN and the MUXEN logo are trademarks of MUXEN SAS.