Nexus 0.21.5
Nexus 0.21.5
Nexus 0.21.5 is an APRS release. APRS gains the internet side of the network, real
station symbols, a detail card per station, and a decode readout that names why it is not hearing
anything instead of showing an empty screen. Alongside it, mode-aware radio routing lets a
multi-radio station send each mode to the rig that does it best, and a third radio works properly
for the first time.
Nothing in this release starts transmitting on its own. The receive-only iGate and the N1MM
broadcast are both off after upgrading and only that switch can turn them on.
Downloads
| Platform | File |
|---|---|
| Windows 10/11 (x64) | Nexus_0.21.5_x64-setup.exe |
| Linux (x86-64) | Nexus_0.21.5_amd64.AppImage or Nexus_0.21.5_amd64.deb |
| Raspberry Pi / arm64, Debian 12 | Nexus_0.21.5_arm64_bookworm.deb |
| Raspberry Pi / arm64, Debian 13 | Nexus_0.21.5_arm64_trixie.deb |
Checksums for every file are in SHA256SUMS.txt. To verify before installing:
sha256sum -c SHA256SUMS.txt --ignore-missing
On Windows, in PowerShell:
Get-FileHash Nexus_0.21.5_x64-setup.exe -Algorithm SHA256
Upgrading
Install over the top; your settings, logbook and memories are kept. Three things worth knowing:
- The receive-only iGate is off. Contributing to a global network under your callsign stays a
deliberate choice, so it never switches itself on. - The N1MM per-QSO broadcast is off, even if you already had an N1MM address configured. The
fix below gives it its own switch. - Radio routing is unchanged until you add a rule. With no rules, routing stays band-only
exactly as before.
APRS now sees the whole network, and can contribute to it
APRS used to show you exactly what your own antenna decoded, and nothing else. That is the honest
picture of what your radio can reach, but on a quiet channel it is also indistinguishable from a
broken receiver — which is what several operators were looking at.
Nexus can now also connect to APRS-IS, the internet side of APRS, and plot what the wider
network is reporting near you alongside what you actually hear. Turn it on in
Settings ▸ Modes ▸ APRS, where every APRS setting now lives, beside RTTY and CW.
- Every station is tagged with how it reached you —
RFwhen your own receiver decoded it,
netwhen only the internet reported it,RF+netwhen both did. You can never mistake "the
network says this station exists" for "my antenna can hear this station", and one click hides the
internet stations entirely, leaving the view of what this radio genuinely reaches. - It is also a diagnostic. The internet feed runs whether or not the APRS decoder is armed, and
gets its own status chip beside the decoder's. Internet stations appearing while the RF chip stays
silent tells you the fault is in the radio chain — antenna, cable, sound card, tuning — and not in
the app. That was previously guesswork. - You choose what comes through. A radius around your grid square (150 km by default — APRS is
a local mode), a list of watched callsigns that come through from anywhere however far away they
are, and switches for weather stations, objects and items, and text messages. - No passcode needed to watch. The feed connects read-only, which every APRS-IS server accepts
from any licensed operator.
The internet status chip on the APRS board is also its control: click it for the feed switch, the
range radius, and your watched callsigns. The radius is there because the chip's own advice when the
feed goes quiet is "widen the radius" — the control belongs where the advice is. Both places edit
the same settings, so they can never disagree about whether the feed is on.
With the feed running you can also switch on a receive-only iGate: packets your own antenna
hears are contributed to APRS-IS, so stations around you reach the global map through your station.
It is a separate switch from the feed, and it stays in Settings rather than on the cockpit, because
it publishes under your callsign — contributing to a global network under your own call should be a
considered decision, not something a stray click can start.
Nexus only ever sends packets it actually heard on the air, and honours every rule the network asks
of an iGate: it never re-sends a packet that already came from the internet, never sends one whose
sender marked it NOGATE or RFONLY, suppresses duplicates, and caps its own upload rate so a
stuck transmitter nearby cannot flood the network in your name.
Nexus does not gate the other way — internet traffic is never transmitted on the air. That
direction means a radio keying up unattended, which is not something this app will do.
The APRS map grows up
Every station on the APRS map was the same grey dot. The packets were carrying the answer the whole
time — APRS stations pick their own icon, and Nexus was throwing it away.
Stations now draw as their actual APRS symbol, on the map and in the station list: cars, trucks,
bicycles and people, weather stations, digipeaters and iGates, campsites, balloons, boats and
aircraft. Vehicles under way point the way they are heading. Where an operator has put an overlay
character on their symbol — the I on a full iGate, the R on a receive-only one, the hop count
on a digipeater — it shows on top of the icon, because that character is often the most useful thing
about the station. A symbol Nexus does not recognise draws the standard "unknown" glyph, never a
blank. The icons are drawn in Nexus rather than borrowed, so there is nothing extra to install.
Symbols also carry a colour for their family: homes and portable stations, vehicles, aircraft,
boats, weather stations, digipeaters and gateways, and hand-placed objects. Colour says what a
station is — nothing here means urgency. The palette varies brightness as well as hue so the
families stay apart for colourblind operators, and it has a separate version for the light theme.
You can still tell what your own antenna heard. That used to be the solid-versus-hollow dot.
The shape now says what a station IS, so the ring around it says how it reached you: solid for RF,
doubled when you heard it both ways, dashed and dimmed for internet-only. Solid still means yours.
Below a local scale the map goes back to plain dots — a continent covered in icons answers a
question nobody asked.
The map opens on the local picture. APRS is a local mode — 2 m simplex plus a digipeater or two
reaches tens of kilometres — so the map now opens reaching about 275 km in each direction, and you
can zoom in much further than before. Previously it opened at a scale where roughly 23 km fell on a
single pixel, so a station 40 km away drew less than two pixels from your own marker and an entire
local net stacked up underneath it as one dot. A freshly decoded station now appears the moment it
lands rather than waiting up to a minute for something unrelated to repaint the screen, and clicking
a station in the list highlights it on the map immediately. With no grid square set, the map centres
on the traffic you are hearing instead of painting an empty box with no coastline and no stations.
Click a station for everything known about it. Clicking used to highlight it and nothing else.
It now opens a detail card, from either the map or the list:
- The symbol at readable size, with what it actually means in words.
- How it reached you, per source, with separate ages — "your receiver decoded this station
4 min ago; the internet feed reported it 20 s ago". Those are two different facts and only one of
them says anything about your antenna, so they are never merged into a single "last heard". - Position with grid square, and distance and bearing from your station.
- Course, speed and altitude when the station is moving.
- The weather, when it is a weather station. Those readings used to be shown as the raw field
string —220/004g011t085r000p000P000h68b10156. Nexus now reads it: temperature, wind direction
and speed, gusts, rainfall, humidity and barometric pressure. A sensor a station does not have is
left out rather than shown as zero —r...on the wire means "no rain gauge fitted", not "no
rain", and reporting 0.00 in would be inventing a measurement. - The comment text, the digipeater path, and whether the packet reached you direct or digipeated.
- The raw packet, collapsed until you want it.
- One click to QRZ, or to the station's page on aprs.fi.
Behind all of it, the map keeps stations, each with its own history: last position, when it was
last heard by your radio and by the internet, symbol, course and speed. A station stays for an hour
after its last packet and starts to fade after twenty minutes of silence, so a quiet station recedes
instead of vanishing. You can change the hour in Settings ▸ Modes ▸ APRS, and setting "Keep
stations for" to 0 means exactly that — no fade, no removal, every station kept until the
2000-station ceiling — because some operators genuinely want an all-day picture.
APRS tells you exactly why it is not decoding
An empty APRS screen used to mean half a dozen very different things and looked identical for all of
them: the app listening to the wrong sound card, the radio parked on another frequency, a signal
arriving too corrupted to check, or a genuinely quiet channel. Only packets that passed their
checksum ever reached the screen, so everything else vanished without trace.
The APRS header now carries a decode readout that names which one you are looking at, in six honest
states: no input, silent, wrong frequency or mode, bursts heard but failing their
checksum, listening on a quiet channel, and decoding with a count and how long ago the
last packet landed. Beside them it shows the input level in dBFS, so what the decoder is hearing
is a number you can read rather than something to infer from which message appeared. Hovering
explains what to check, and the empty list and empty map say the same thing rather than a generic
"nothing here".
A closed squelch is not a broken audio device. A squelched radio does not send the app silence
in the sense of nothing; its USB codec keeps streaming a continuous run of digital zeros. Audio is
arriving the whole time — it just has no level. So "Silent" (the input alive with nothing on it,
almost always the squelch closed between packets) is a separate state from "No input" (no audio
samples arriving at all), and only the second is a fault. An idle FM channel between packets is what
APRS looks like nearly all the time, so "Silent" is not coloured as a problem; it says to open the
squelch and watch for hiss if you want to confirm the routing. "No input" really does mean the
capture device is wrong or gone, and still points you at Settings.
A mistuned radio is named as one. FT8 decoding beautifully on 2 m at the same moment the APRS
screen insists there is no audio are both true statements: the radio has one receiver and one dial,
and parked on the FT8 frequency in USB it is never receiving the APRS channel at all — so every
message about audio levels would be advice about the wrong problem. The readout now looks at the
radio itself, says so first, and offers a one-click fix: "The radio is on 144.174 USB — APRS needs
144.390 FM", with a Tune button beside it. It judges against the APRS channel you have selected,
so 144.800 in Europe or 145.175 in Australia is correct, not a warning. Sitting on the right
frequency in the wrong mode is its own trap — the signal looks strong and decodes nothing — so that
case reads "on 144.390 but in USB — APRS needs FM" and explains that FM packet audio demodulated
as SSB is garbled. Data-FM submodes such as PKTFM count as FM, because on the air they are. Tuning
while an FT8 over is in flight cannot move the radio immediately — the rig will not accept a
frequency change mid-transmission — so rather than appearing to do nothing, the Tune button says the
radio will move when the over ends.
It says which radio it is listening to. If more than one of your radios covers the APRS band,
the readout names the one it is actually listening to — "on FT-991A" — and its tooltip explains that
APRS follows the active radio and that routing rules decide which radio a band goes to. Without
that, a station whose APRS audio is set up on one rig while the app listens to the other has exactly
one symptom: silence. A working station looks like a dead band. With the radio named, that is a
glance instead of an afternoon. On a single-radio station, or when only one radio covers the band,
nothing is shown — there was no choice to make and saying so would just be clutter.
Every claim says when it was true. The packet counts run from the moment you arm the decoder,
while the level is whatever the radio is doing this instant, and mixing the two produces sentences
that contradict themselves: "2 packets were heard but none passed the checksum... peak -99 dBFS."
Nothing is heard at -99 dBFS. A failed-checksum count now only speaks in the present tense while
bursts are still arriving, within the last minute, and dates itself when it does: "2 bursts heard
since arming, last one 20s ago — none passed the checksum", with the live level on its own clause.
Decodes are treated differently on purpose — a packet that passed its checksum proves the whole
chain works, and that stays worth knowing however long ago it was, so it keeps its place and carries
its age instead: "18 packets decoded since arming, last one 12m ago." The level reading says what
window it measures, the most recent tenth of a second, so a low number reads as the gap between
packets rather than something being wrong. And once packets are decoding, the readout stays on the
decode count instead of flicking back to a warning during the quiet gaps between them.
Three smaller pieces of the same honesty. A failed-checksum count explains that a packet caught
part-way through — which is what happens when the squelch opens mid-burst — can never pass its
checksum, so some failures on a busy channel are expected rather than a sign of a misconfigured
radio. Packet-shaped patterns found in silence do not count as packets at all: given enough minutes
the decoder will eventually find one in the noise floor, and reporting that as "packets heard"
invents evidence for a problem that is not there. And the Monitor button, the decode readout and the
empty-state text all report the decoder's actual state rather than the button's own guess, so
leaving the APRS screen and coming back can never show "Monitor" — as though nothing were running —
while packets keep decoding into the list beside it.
None of this is covering for a fragile decoder. The packet decoder was measured against "twist" —
the two packet tones arriving at unequal volume, which is the classic reason packet decoders
struggle on real signals — and packets still decode with the tones up to 24 dB apart, far beyond the
roughly 9 dB that real signals show.
APRS starts listening when you open it — receive only
Opening APRS now starts the decoder for you, so the screen is not dead until you find the Monitor
button. This is strictly receive: a decoder started this way will never send an automatic ack,
whatever your TX setting.
Automatic acks stay behind two deliberate acts, and opening a screen is not one of them: you arm
Monitor yourself, and TX is on. That is now enforced rather than assumed — an unattended
transmission should never follow from navigating somewhere. The Monitor button says which state you
are in, reading "Monitoring (auto)" when APRS started it for you, and its tooltip spells out whether
acks can go out.
Clicking Monitor always means start or stop, as before. It never quietly upgrades an
automatically-started decoder into one that can transmit — to allow acks, stop it and start it
yourself. And if you stop the decoder, it stays stopped: coming back to the APRS screen will not
restart it behind you.
Route each mode to the radio that does it best
Nexus already handed a band to the radio configured for it: pick 2 m and it switched to your VHF
rig. But a band is not fine enough. If you have a 2 m/70 cm rig for weak-signal digital and a
different rig for FM and APRS, both of them cover 2 m — and Nexus had no way to tell them apart, so
a 2 m FT8 spot and an APRS tune went to whichever radio it happened to pick first.
You can now route on the band and the mode. In Settings ▸ Radio there is a routing table
under your radios: pick a set of bands, pick a mode class, pick the radio. Rules are checked top to
bottom and the first match wins, so a specific rule above a broad one takes precedence — and the
arrows beside each rule let you reorder them. Anything no rule matches falls back to the band
coverage you already set on each radio, and then to a default radio you can nominate for everything
else.
A three-radio shack maps onto two rules. Digital to the 9700, APRS and repeaters to the 991A, HF to
the FTdx10:
| Bands | Mode | Radio |
|---|---|---|
| 2 m, 70 cm | FM & APRS | FT-991A |
| 2 m, 70 cm | Weak-signal digital | IC-9700 |
| (everything else) | FTdx10 |
The mode classes are deliberately coarse — weak-signal digital, FM & APRS, SSB phone, CW, RTTY —
so a whole station fits in a handful of rules rather than one per submode. Every action that used
to consult the band table now consults band + mode: the band picker, a typed frequency, clicking a
spot on the Needed board or a DXpedition card, and APRS Tune. Peg-lock still pins your radio and
stops all of it, exactly as before.
There is a "Where would this go?" control under the table. Pick a band and a mode and it tells
you which radio that combination resolves to, without touching a rig — it asks the same code the
radio does, so it cannot tell you one thing and then do another.
If you never add a rule, nothing changes: routing stays band-only, as it was.
And a third radio now works properly. Two radios worked. A third did not, for a reason that
only ever shows up at three: each radio's window keeps its own settings file, seeded once from the
shared one the first time that window opens. With two radios you always add the second one before
those per-window files exist, so both windows learn about both radios. The third radio is the first
one you add after they exist — so it landed in exactly one window's settings and nowhere else. The
launch picker (which reads the shared file) never offered it, the other window never monitored it,
and there was no way to repair it from inside the app.
Adding or removing a radio now updates the shared config too, and every window picks up radios added
elsewhere when it starts. The routing table above is shared the same way, since which rig does 2 m
FM is a decision about your station, not about one window.
Three smaller things that also only bite at three radios: a band claimed by two rigs now always goes
to the same one (it used to depend on the order they happened to sit in the list); adding a radio
after removing one no longer produces two radios with the same name, which made the port and audio
conflict warnings ambiguous; and a window launched pointing at a radio that no longer exists now
says so instead of quietly driving the first radio's serial port — which is the port another window
is already using.
Star a repeater straight from the search results
Program's repeater search has a star on every result row. Starring one saves it into Memories as a
proper FM channel, with the machine's shift, offset and access tone, and puts it on the quick-recall
strip in the Phone, Operate and CW cockpits — where one click, or Ctrl+1 through Ctrl+9, tunes it.
Previously the only route from a search result to your favorites ran through the channel-list
builder and a second trip into the Memories section to star each row by hand.
Starring the same machine twice does not duplicate it: if that frequency, mode and tone are already
saved, the star lights on the row you already have. The star toggles back off and leaves the channel
in Memories, so unstarring only takes it off the cockpit strip.
Starred repeaters also remember where the machine physically is, so Memories shows how far away and
in what direction each one is. That is measured from your current grid every time it is displayed
rather than stored, so the distances follow you when you operate portable.
Program's per-repeater Tune button tunes in a single step that knows it is FM, which is what makes
it land correctly on a multi-radio station and after you have been operating something other than
voice. Naming FM explicitly settles both decisions at once: the machine's frequency, shift, offset
and tone all go to the radio you mapped for FM, and the rig ends up in FM rather than in whatever
data mode the last section you operated left it in — a repeater is inaudible in a data mode. Tuning
does not move you out of Program or arm transmit; it puts the radio on the repeater so you can
listen. Any later retune, section change, radio switch, or a turn of the VFO knob down to HF
releases the FM hold, so FM never follows you somewhere it does not belong.
DXpedition calendar: one operation, one bar
A multi-day DXpedition was drawn as a separate little chip on each of its days, so a ten-day
operation looked like ten unrelated things. Each operation is now a single bar running across the
days it is on the air. Where a run crosses into the next week it picks up again on the following
row, named and flagged so you can follow it.
Every operation also gets its own colour, and keeps it — on its calendar bar, on its dot in the
"what to chase" summary, and on the rail beside its entry in Details. The colour means nothing but
"this is that one", which is what lets you pick an operation out of a busy fortnight without
reading a single callsign. Today is still the strongest thing on the grid, and an operation you are
chasing still stands out from the rest.
Bars wide enough to hold it now carry the bands the operation announced, low bands first, so
whether they are bringing 160 and 80 is visible without opening anything. Hovering any bar gives
the full picture: entity, dates, every band, the modes, and your modelled best shot.
When more operations overlap than a week has room for, the day says "+2" instead of quietly hiding
them; clicking opens that week out and clicking again closes it. Operations that do not overlap in
time now share a row rather than each burning one, so the calendar stays short.
Clicking an operation also opens its webpage in your browser, so the announcement you are
looking at is one click from the team's own page — bands, schedule, QSL route, pilot station. The
Details rail carries the same link on each entry, labelled, so you can see where it goes before you
click it. About a third of announced operations publish a website, and the calendar source has been
carrying those links all along — Nexus was throwing them away while reading the page. The rest now
open the callsign's QRZ page instead, which is where their details and QSL route live when there is
no expedition site. Either way the tooltip names the destination first, and says plainly when it is
the QRZ fallback rather than the operation's own page. Clicking a calendar bar still selects that
operation in the Details rail as it did before, so nothing that used to work costs you an extra
click now.
Fixed: the N1MM contact broadcast sent nothing unless Field Day was running
Set the N1MM address, log QSOs, watch the network: nothing. An operator running it alongside Ham
Radio Deluxe saw HRD's packets go out on 12060 and not one from Nexus on 12061. The address had
looked like a standing integration sitting next to HRD, and it was not one — the broadcast only
ever fired during a Field Day event, and said so nowhere.
Settings ▸ Logging & Connectors ▸ N1MM+ Integration now has a Broadcast every QSO switch.
Turn it on and each logged contact goes out as an N1MM contact packet, event or not — from the
digital modes, from the CW and Phone cockpits, from a hand-typed logbook entry, all of them. Point
OpenHamClock or GridTracker at the address and every QSO plots on its map as you log it. The
packet leaves at the moment the QSO is logged, in the same breath as the HRD one. Turn the switch
on with the address field empty and Nexus fills in the usual local target for you. The address
field now also states which of the two it is doing, so a configured-but-silent output can never
look like a working one again.
It is off after an upgrade, and nothing but that switch can turn it on — your contacts do not
start going out over the network because you installed a new version.
Field Day is untouched. During an event, contest contacts still go out the way they always have,
carrying your class, section and points; the standing broadcast only ever carries the contacts in
your regular log. A contact is never sent twice, so it is safe to leave the switch on through a
Field Day weekend. An ordinary QSO carries what a map needs — call, grid, band, frequency, mode,
time — and honestly claims no contest points.
If you run several consumers on one machine, name the port. 12060 is often already taken (HRD
listens there), and the port you type is the port that is used.
CW keying now works with rigs that refuse 1200 baud on their keying port
A tester with a new Yaesu FTX-1 could not key CW through the rig's built-in Standard COM port.
Nexus reported that it could not open the port; Windows, asked directly, said "a device attached to
the system is not functioning." The port was fine. Nexus was asking for it at 1200 baud, and the
FTX-1's firmware refuses that one rate while accepting every other.
A keying port sends no data at all — Nexus only flips a control line up and down, and the rig shapes
the CW — so the baud rate never meant anything on the air. It was a number we had to name to open
the port, and 1200 was an arbitrary choice that eventually met a radio that says no. Nexus now asks
for 9600, and if a port refuses that it works down through 19200, 4800, 2400 and 1200 until one is
accepted, then keys normally. Nothing to set, and nothing to notice: existing keying interfaces
behave exactly as before.
The same fix covers the other two places a control line is used this way — true-FSK RTTY keying
and serial PTT — because the same port on the same radio would have refused those too.
When a keying port genuinely cannot be opened, the message now quotes what the system actually said
and which rates were tried, instead of guessing at causes. The tester above had to diagnose this in
PowerShell because our error message withheld the one useful sentence.
Opening APRS on an HF-only radio no longer breaks CAT
Reported on an FTdx10, which covers HF and 6 m and has no 2 m at all. Rig control worked normally
in the Phone and CW cockpits; clicking into APRS killed it, and it stayed dead until Nexus was
restarted. Going back to Phone afterwards showed the dial parked on 144.390 — a frequency the
radio had never been on.
Opening the APRS cockpit tunes your radio to the APRS channel, which is on 2 m. On a radio that
cannot go there the radio refused the command, and Nexus did not notice: it took the refusal for
success, wrote 144.390 into its own idea of where the radio was, and stopped checking. Everything
after that followed from believing a thing that never happened.
Three fixes, and each one stands on its own:
Nexus now knows what your radio covers before it commands it anywhere. It reads the receive
range straight out of the radio's own capability table over CAT, so an HF-only radio is never sent
to 2 m in the first place. Where the ranges cannot be read — no rig control, or a rig-control
daemon that does not report them — nothing is blocked; the check only ever refuses on information
it actually has.
A refused command is now treated as a refusal. Nexus checks what the radio said back, keeps
showing where the radio really is rather than where it was asked to go, tells you the radio would
not accept that frequency, and stops asking after a few tries instead of hammering the link. A
command your rig will not take no longer wedges rig control until you restart the app, whatever the
rig and whatever the command.
Rig control recovers on its own. Nexus stops polling a radio that has stopped answering, which
is right — but that state used to be permanent, so any hiccup meant no rig control until you
restarted. It now retries quietly, backing off to about once every thirty seconds, and picks the
radio back up within a couple of seconds of it answering again. This one is not specific to APRS:
anything that interrupted the link used to cost you rig control for the rest of the session, on
every rig Nexus talks to.
In the cockpit, an HF-only station now reads "No 2 m radio" with an explanation, instead of a
Tune button that could only ever fail. The internet feed is genuinely useful without a VHF radio —
it shows APRS traffic other stations have reported — so the view tells you that rather than
looking broken.
Credit where the code came from
Two of the modes Nexus decodes stand on other people's work, and the NOTICE file — the document
that records exactly what Nexus borrowed and from whom — did not say so. It does now.
The RTTY decoder is a port of fldigi's receive path, by Dave Freese W1HKJ and Stefan Fendt
DL1SMF, whose own lineage runs back to Tomi Manninen OH2BNS's gmfsk. The threshold detector that
makes it print through noise is a design Kok Chen W7AY published and gave away. The SSTV receiver
is vendored from slowrx by Oona Räisänen OH2EIQ, reaching Nexus through Jason Herald's Rust
port of it. Each now has a full entry in NOTICE naming the project, the author, the license, and
which files came from where, plus a line in the README credits.
Nothing about how the radio behaves changes — these are comments and documents. What changes is
that anyone reading the source can now trace every borrowed line to the person who wrote it.
Two smaller corrections in the same pass. The RTTY transmitter is Nexus's own code, not fldigi's,
and its file header now says so outright, so no future reader assumes the transmit side came along
with the receive side. That header also credited "the W7AY dual-oscillator scheme" without naming
Kok Chen or linking what he actually published; it now cites the paper, and is honest that the
shaped edge treatment is Nexus's answer to the problem that paper measures, not something taken
from it.
Full commit history: v0.21.0...v0.21.5