Appearance
Address claiming
Every device on an NMEA 2000 bus has an address, and nobody assigns it. There are no DIP switches and no configuration screen. Each device arrives on the bus, announces the address it would like, and either keeps it or is told — by another device that wants the same one — to go somewhere else. Within a couple of seconds the whole bus has sorted itself out.
This chapter is about how muxen-nmea2000 takes part in that, and what an installer can change about it. The crew-visible summary is short: this is why the gateway appears in a chartplotter's device list, and why the number next to it can be different after a refit.
What an address is, and what a NAME is
Two identifiers, and the difference matters:
- The source address is one byte, 0–253. It goes in every frame the device transmits, and it can change.
- The J1939 NAME is 64 bits, fixed for the life of the product, and describes what the device is: who made it, what function it performs, which instance of that function it is.
Addresses are negotiated; NAMEs are not. When two devices want the same address, the NAME decides who keeps it, and everything else about the system keys on the NAME rather than the address for exactly that reason — including this daemon's navigation source configuration.
The NAME's fields, from the top bit down:
| Bits | Width | Field |
|---|---|---|
| 63 | 1 | Arbitrary Address Capable |
| 60–62 | 3 | Industry Group |
| 56–59 | 4 | Vehicle System Instance |
| 49–55 | 7 | Vehicle System |
| 48 | 1 | reserved |
| 40–47 | 8 | Function |
| 35–39 | 5 | Function Instance |
| 32–34 | 3 | ECU Instance |
| 21–31 | 11 | Manufacturer Code |
| 0–20 | 21 | Identity Number |
The 8 bits at 32–39 — ECU Instance together with Function Instance — are what NMEA 2000 calls the device instance, and are the value a chartplotter or muxen-nmea2000-config changes when you tell two identical devices apart.
muxen-nmea2000-generate-name builds a NAME from these fields; see Reference.
Four devices, not one
The daemon claims four addresses, not one.
An NMEA 2000 device advertises the list of messages it transmits and receives, and that list is bounded. This gateway handles far more message types than one device may declare, so it presents itself as four cooperating virtual devices, each with its own NAME derived from the configured one and its own claimed address:
| Virtual device | Product name on the bus |
|---|---|
| navigation | Nav Gateway |
| engine | Engine Gateway |
| AIS | AIS Gateway |
| electrical | Electrical Gateway |
Each derived NAME differs from the configured NAME only in its identity number, incremented by the virtual device's index. All four report function code 130, PC Gateway.
The practical consequences:
- A healthy daemon occupies four consecutive addresses, normally 128–131.
- It appears four times in a plotter's device list. This is normal.
- No report is published until all four have claimed. A daemon stuck part-way through claiming is silent on every report topic.
What the daemon does at startup
┌──────────────┐
│ DISCOVERING │ 2 s — ask the whole bus who is where
└──────┬───────┘
▼
┌──────────────┐
│ SELECTING │ pick an address
└──────┬───────┘
▼
┌──────────────┐
│ CLAIMING │ announce it, wait 250 ms for an objection
└──────┬───────┘
▼
┌──────────────┐
│ CLAIMED │ in service
└──────────────┘Discovery is an addition to the bare standard rather than a requirement of it. The daemon broadcasts a request for Address Claimed and listens for 2 seconds, building a picture of which addresses are occupied and by which NAME. That is comfortably longer than the 1.25 s the standard allows every device to answer in, so the picture is complete before anything is claimed.
Claiming without discovering first works, and is what the standard describes; it just means colliding first and resolving afterwards, which is noisier.
Selection takes the preferred address if discovery found it free. Otherwise it walks the configured range looking for a gap.
Claiming announces the chosen address and waits 250 ms. Silence means the address is yours.
The full state machine, including what happens when it goes wrong, is The address claim state machine.
Choosing the addresses
| Option | Default | Meaning |
|---|---|---|
-a, --address ADDR | 128 | the address to ask for first |
--min-addr MIN | 100 | lowest address to fall back to |
--max-addr MAX | 200 | highest address to fall back to |
All three take 0–253. 254 is the null address and 255 is the broadcast address; neither can be claimed. --min-addr above --max-addr is refused at startup.
The preferred address is tried whether or not it is inside the range. The range only governs where the daemon looks when the preferred address is unavailable.
The default range, 100–200, is narrower than the NMEA 2000 dynamic range of 128–247. If you want the standard range:
sh
muxen-nmea2000 … --min-addr 128 --max-addr 247Remember that four addresses are needed, not one, so a range must have at least four free slots.
When the preferred address is taken
If the device is arbitrary-address-capable — bit 63 of the NAME — the daemon walks the range for a free address and claims that instead.
If it is not, there is nowhere to go. The claim fails and the journal says:
ACD: Failed to claim any addressThe stock primary NAME 0x11223344FF467788 has that bit clear. This is fine on a boat where the gateway is the only thing in its part of the address space, and it is exactly why the templated instance's NAME 0x91223344FF467799 has the bit set — an instance must always be able to move out of the primary's way. See More than one bus.
When an address is lost while running
Another device claiming an address this daemon already holds is resolved by NAME: the numerically lower NAME wins.
- We win. The daemon re-announces its claim and carries on. The other device has to move.
- We lose. The virtual device gives up the address and searches for a new one, starting from the address after the one it just lost and wrapping round to the bottom of the range. Reports from that virtual device stop until it has claimed again.
Two devices with identical NAMEs is a configuration error, not an arbitration, and the daemon ignores the frame rather than fighting a copy of itself.
Once claimed
The daemon becomes a full participant:
- It answers ISO Requests for Address Claimed, Product Information, Configuration Information and the transmit/receive PGN lists.
- It sends PGN 126993, Heartbeat, every 60 seconds per virtual device.
- It accepts PGN 65240, Commanded Address, so a bus tool can move it to a specific address.
- It saves the claimed addresses so it can ask for the same ones next time — The state file.
--pgn-list-fp-only limits the transmitted PGN list to what fits in a Fast Packet message — 74 PGNs — instead of using ISO transport for a longer one. Some chartplotters cannot handle the longer form. It is a compatibility workaround, not a tuning knob.
Watching it happen
sh
sudo -u muxen /usr/bin/muxen-nmea2000 --interface=can1 \
--name=0x11223344FF467788 --verbose-controlACD: INIT -> DISCOVERING
ACD: Starting address discovery (2000ms)...
ACD: Discovery complete
ACD: DISCOVERING -> SELECTING
ACD: Selecting address (preferred=0x80, range=100-200, AAC=no, peers=7)
ACD: Selected preferred address 0x80
ACD: SELECTING -> CLAIMING
ACD: Claiming address 0x80...
ACD: CLAIMING -> CLAIMED
VDEV[nav]: Address 0x80 claimedWithout --verbose-control only the final claim of each virtual device and the "all claimed" line are logged. nmea/devices and muxen-nmea2000-inventory show the resulting picture from the bus's point of view.
