Releases: prstoetzer/CardSat
CardSat v0.9.24
Icom CI-V tracking, audited against OscarWatch
Two changes to bring the Icom MAIN/SUB control in line with how the known-good
OscarWatch tracker drives these rigs (especially helpful on slow single-wire rigs
like the IC-821):
-
Uplink write is deferred one tick after a downlink write or knob move. After
CardSat writes the downlink (or the operator moves the receive dial), the uplink
write now waits one Doppler tick so the SUB read and the receive dial settle
before the bus is used for the MAIN uplink. During a fast Doppler slew the uplink
still services every other tick, so it never starves. -
Receive-only birds turn satellite mode off and tune the downlink on MAIN. A
transponder with no uplink (beacon, telemetry, SSTV, CW) now commands the rig's
satellite mode off and routes the downlink to the MAIN band regardless of
the VFO Type setting. This matches OscarWatch and the SDR-Control apps, and on the
IC-821 the MAIN band reads back far more reliably than SUB.
Sat-to-sat window search no longer stalls
The "both satellites visible" finder used to compute its multi-day search in one
long blocking pass, which could starve the system and appear to hang (or never
finish) on hardware. It now runs as an incremental background job: it samples
a few hundred points per loop tick, shows a live progress bar (0→100 %), keeps
the back key responsive throughout, and always completes. The results are
identical to the old one-shot search.
Web sky plot shows the next pass when the satellite is below the horizon
When the active satellite is below your horizon, the web control page's polar plot
now draws the next pass as an arc (azimuth/elevation across the upcoming pass)
instead of an empty plot, so you can see where the satellite will rise and set. The
moment it comes above the horizon the live position dot takes over and the arc
clears. The /api/passes response now also includes an arc array for this.
Fix
-
IC-821 CI-V read reliability. Reworked the Icom CI-V frequency-read flow for
the IC-821, whose SUB band (the satellite downlink) often won't answer the read
command. CardSat now re-selects the band immediately before each read and, when
no valid reply arrives, falls back to the last frequency it commanded instead of
failing — so the downlink keeps Doppler-tracking and a bad read is never mistaken
for an operator knob move. Transponder mode-setting was reordered to set the
uplink (MAIN) leg first and leave the radio on the downlink (SUB) band, which is
where the read happens. The0x1C 0x00poll (read transmit/PTT status, used to
pause knob-follow while transmitting) and the band-select model are documented;
rigs that don't support the status poll are detected and it is dropped. -
DX Doppler starts at the centre of the linear passband. The Doppler table
now opens with the operating point in the middle of the selected linear
transponder's passband (and re-centres when you switch transponders witht),
matching how the on-device tracker centres a linear bird, instead of starting at
the low edge. FM and single-channel transponders are unaffected.
Mobile web control improvements
The web control page (Settings → Network/data → Web control) gained:
- a live sky plot — a polar plot with a moving dot at the satellite's current
azimuth/elevation; - an in-pass indicator and AOS countdown in the header ("IN PASS — LOS in
m:ss" / "Next AOS in m:ss"); - transponder selection from a labelled drop-down (mirrors the
tkey); - direct calibration entry — type exact RX/TX offsets in Hz and Set/Zero them
(saved per-satellite); - a filter box to narrow a long satellite list;
- a responsive layout that uses one column on phones and two columns on
tablets/computers.
Internally, all satellite and transponder names served as JSON are now escaped, so
a name containing a quote or backslash can no longer break the page. Two small
endpoints were added (/api/tx for the transponder list/select, /api/cal for
calibration). As with the rest of the LAN servers, the web page is HTTP on the
local network with no authentication — use it only on trusted networks.
Changes
- OSCARLOCATOR opens in polar view by default (press
mfor the QTH-centred
view); the polar sheet auto-selects N/S and flips at the equator. - Sat-to-sat finder shows a "Calculating windows…" status while it searches,
instead of appearing to pause during the computation. - LoRa region presets. A new LoRa region setting (Settings → Network/data)
seeds a legal amateur frequency for your area: US → 33 cm band, 906.875 MHz
(default); EU → 70 cm band, 433.775 MHz; Japan → 430 MHz band,
431.000 MHz — all at 125 kHz. The default region is now US (906.875 MHz)
instead of 433.775 MHz. You can still set any carrier 150–960 MHz by hand; the
region just provides a sensible, in-band starting point. You remain responsible
for operating within your licence and local rules.
Fixes from device testing
- Sat-to-sat finder no longer freezes. The visibility search was calling the
SGP4 element re-initialiser twice per 30-second step over a 5-day window
(~29,000 full re-inits), which blocked long enough to trip the task watchdog and
freeze the unit. It now samples each satellite once across the window into a
compact in-RAM track (two re-inits total), yields periodically, and scans those
tracks for overlaps — fast and watchdog-safe. - DX Doppler transponder selection works, and the table is readable. The DX
Doppler screen now has atkey to cycle the transponder directly, and each
30-second step is shown on two lines — your dials ("me", green) and the DX
station's ("DX", cyan), each with RX and TX — so the four frequencies no longer
run into each other. Mode changes (true rule / fixed DL / fixed UL) are easier to
read against the clearer layout. - OSCARLOCATOR and Sky-sources plots clear the header. The polar/azimuthal
discs and their compass labels were drawn far enough up that the disc top and the
"N" label overlapped the title bar. The OSCARLOCATOR disc is now centred lower,
and the shared polar-grid compass labels sit just inside the disc edge. - LoRa Messages status bar clears the header. The frequency / SF / bandwidth
line was flush against the title bar; it (and the divider and message list) now
start below it. - SD card stays accessible after using LoRa. The Cap LoRa SX1262 and the
microSD card share one SPI bus (SCK 40 / MISO 39 / MOSI 14, different chip
selects). LoRa bring-up was reconfiguring the bus in a way that left the SD
driver unable to use it. LoRa now shares the existing bus on the SD pins and
keeps the SD chip-select idle, so the card remains reachable.
This release adds three significant new satellite views — an OSCARLOCATOR
azimuthal plot, a 3D globe, and an on-device voice-memo browser — plus a
round of documentation accuracy work across the README and Manual.
New: LoRa text messaging (Home → Messages)
CardSat-to-CardSat broadcast group chat over the M5Stack Cap LoRa (SX1262)
module. Every CardSat tuned to the same frequency, spreading factor and bandwidth
sees every message — no addressing or routing, which keeps it simple for a club
net, a SOTA/portable group, or any outing where there's no cell or internet.
- Selectable band — the SX1262 (and the unfiltered Cap LoRa front-end) covers
150–960 MHz, so the frequency is fully selectable (default 433.775 MHz):
arrow-adjust in 100 kHz steps or type an exact MHz value. Spreading factor is
selectable 7–12 (default 12 for maximum range/sensitivity), and bandwidth
is 62.5 / 125 / 250 kHz. Both ends must match to hear each other. - Messaging screen —
nwrites a message on the full keyboard and ENTER
sends;;/.scroll history. Your messages show in cyan as>me, others in
green by callsign. The status line shows frequency / SF / bandwidth / your call. - Low-footprint by design — fixed character buffers and a fixed 24-message ring
(noStringin the radio path, no heap growth, no SD card). History is lost on
reboot. - Settings (Network/data): LoRa msg on/off, frequency, SF, bandwidth, TX power
(0–22 dBm). Set your callsign first (Station settings / QRZ screen).
⚠️ Untested hardware path, and needs an extra library. The radio send/receive
is written to the M5Stack Cap LoRa reference and the SX1262 datasheet but has not
been confirmed on a device. It requires the RadioLib library (Arduino Library
Manager) and a build withCARDSAT_HAS_LORA=1; without that the firmware
still compiles and the Messages screen reports the radio is off. Verify two units
talk before relying on it, and mind your band's rules — 433.775 MHz at 125 kHz is
the worldwide default but exceeds the US 70 cm 100 kHz occupied-bandwidth limit,
where 915 MHz ISM is the cleaner path. The protocol framing and the message ring
are host-verified; the radio layer is not.
New: OSCARLOCATOR view (Satellites → k)
A live azimuthal-equidistant plotting board — the classic OSCARLOCATOR — that
shows the satellite's sub-point and footprint on the Earth in real time. It's the
graphical companion to the tabular EQX table (e).
- Two projection modes, toggled with
m: a QTH-centred view (your station
at the centre, with the satellite at its true bearing and great-circle distance)
and a polar view (a pole at the centre). In polar mode CardSat picks the
North or South sheet automatically and flips between them live as the bird
crosses the equator, so the satellite always stays on the visible chart. - Draws a coarse coast...
CardSat v0.9.23
Fix
- DX Doppler starts at the centre of the linear passband. The Doppler table
now opens with the operating point in the middle of the selected linear
transponder's passband (and re-centres when you switch transponders witht),
matching how the on-device tracker centres a linear bird, instead of starting at
the low edge. FM and single-channel transponders are unaffected.
Mobile web control improvements
The web control page (Settings → Network/data → Web control) gained:
- a live sky plot — a polar plot with a moving dot at the satellite's current
azimuth/elevation; - an in-pass indicator and AOS countdown in the header ("IN PASS — LOS in
m:ss" / "Next AOS in m:ss"); - transponder selection from a labelled drop-down (mirrors the
tkey); - direct calibration entry — type exact RX/TX offsets in Hz and Set/Zero them
(saved per-satellite); - a filter box to narrow a long satellite list;
- a responsive layout that uses one column on phones and two columns on
tablets/computers.
Internally, all satellite and transponder names served as JSON are now escaped, so
a name containing a quote or backslash can no longer break the page. Two small
endpoints were added (/api/tx for the transponder list/select, /api/cal for
calibration). As with the rest of the LAN servers, the web page is HTTP on the
local network with no authentication — use it only on trusted networks.
Changes
- OSCARLOCATOR opens in polar view by default (press
mfor the QTH-centred
view); the polar sheet auto-selects N/S and flips at the equator. - Sat-to-sat finder shows a "Calculating windows…" status while it searches,
instead of appearing to pause during the computation. - LoRa region presets. A new LoRa region setting (Settings → Network/data)
seeds a legal amateur frequency for your area: US → 33 cm band, 906.875 MHz
(default); EU → 70 cm band, 433.775 MHz; Japan → 430 MHz band,
431.000 MHz — all at 125 kHz. The default region is now US (906.875 MHz)
instead of 433.775 MHz. You can still set any carrier 150–960 MHz by hand; the
region just provides a sensible, in-band starting point. You remain responsible
for operating within your licence and local rules.
Fixes from device testing
- Sat-to-sat finder no longer freezes. The visibility search was calling the
SGP4 element re-initialiser twice per 30-second step over a 5-day window
(~29,000 full re-inits), which blocked long enough to trip the task watchdog and
freeze the unit. It now samples each satellite once across the window into a
compact in-RAM track (two re-inits total), yields periodically, and scans those
tracks for overlaps — fast and watchdog-safe. - DX Doppler transponder selection works, and the table is readable. The DX
Doppler screen now has atkey to cycle the transponder directly, and each
30-second step is shown on two lines — your dials ("me", green) and the DX
station's ("DX", cyan), each with RX and TX — so the four frequencies no longer
run into each other. Mode changes (true rule / fixed DL / fixed UL) are easier to
read against the clearer layout. - OSCARLOCATOR and Sky-sources plots clear the header. The polar/azimuthal
discs and their compass labels were drawn far enough up that the disc top and the
"N" label overlapped the title bar. The OSCARLOCATOR disc is now centred lower,
and the shared polar-grid compass labels sit just inside the disc edge. - LoRa Messages status bar clears the header. The frequency / SF / bandwidth
line was flush against the title bar; it (and the divider and message list) now
start below it. - SD card stays accessible after using LoRa. The Cap LoRa SX1262 and the
microSD card share one SPI bus (SCK 40 / MISO 39 / MOSI 14, different chip
selects). LoRa bring-up was reconfiguring the bus in a way that left the SD
driver unable to use it. LoRa now shares the existing bus on the SD pins and
keeps the SD chip-select idle, so the card remains reachable.
This release adds three significant new satellite views — an OSCARLOCATOR
azimuthal plot, a 3D globe, and an on-device voice-memo browser — plus a
round of documentation accuracy work across the README and Manual.
New: LoRa text messaging (Home → Messages)
CardSat-to-CardSat broadcast group chat over the M5Stack Cap LoRa (SX1262)
module. Every CardSat tuned to the same frequency, spreading factor and bandwidth
sees every message — no addressing or routing, which keeps it simple for a club
net, a SOTA/portable group, or any outing where there's no cell or internet.
- Selectable band — the SX1262 (and the unfiltered Cap LoRa front-end) covers
150–960 MHz, so the frequency is fully selectable (default 433.775 MHz):
arrow-adjust in 100 kHz steps or type an exact MHz value. Spreading factor is
selectable 7–12 (default 12 for maximum range/sensitivity), and bandwidth
is 62.5 / 125 / 250 kHz. Both ends must match to hear each other. - Messaging screen —
nwrites a message on the full keyboard and ENTER
sends;;/.scroll history. Your messages show in cyan as>me, others in
green by callsign. The status line shows frequency / SF / bandwidth / your call. - Low-footprint by design — fixed character buffers and a fixed 24-message ring
(noStringin the radio path, no heap growth, no SD card). History is lost on
reboot. - Settings (Network/data): LoRa msg on/off, frequency, SF, bandwidth, TX power
(0–22 dBm). Set your callsign first (Station settings / QRZ screen).
⚠️ Untested hardware path, and needs an extra library. The radio send/receive
is written to the M5Stack Cap LoRa reference and the SX1262 datasheet but has not
been confirmed on a device. It requires the RadioLib library (Arduino Library
Manager) and a build withCARDSAT_HAS_LORA=1; without that the firmware
still compiles and the Messages screen reports the radio is off. Verify two units
talk before relying on it, and mind your band's rules — 433.775 MHz at 125 kHz is
the worldwide default but exceeds the US 70 cm 100 kHz occupied-bandwidth limit,
where 915 MHz ISM is the cleaner path. The protocol framing and the message ring
are host-verified; the radio layer is not.
New: OSCARLOCATOR view (Satellites → k)
A live azimuthal-equidistant plotting board — the classic OSCARLOCATOR — that
shows the satellite's sub-point and footprint on the Earth in real time. It's the
graphical companion to the tabular EQX table (e).
- Two projection modes, toggled with
m: a QTH-centred view (your station
at the centre, with the satellite at its true bearing and great-circle distance)
and a polar view (a pole at the centre). In polar mode CardSat picks the
North or South sheet automatically and flips between them live as the bird
crosses the equator, so the satellite always stays on the visible chart. - Draws a coarse coastline, a lat/lon graticule, the satellite marker (yellow when
sunlit, cyan in eclipse), and the satellite's ground footprint. - A dashed amber QTH range ring marks the footprint radius at the satellite's
mean altitude, centred on your station — when the sub-point reaches inside it,
you have a workable pass. - The full ground-track arc (one orbit's worth of sub-points) is drawn across
the disc in blue, like a real OSCARLOCATOR; green/orange markers show where the
current pass's AOS and LOS fall along it, with a travel-direction arrow.
New: Live GPS position (Location → v)
A full-precision position readout off the Location screen, for rovers, portable
ops, and grid-line activations. Shows latitude and longitude in
degrees-minutes-seconds to 0.001″ and in decimal degrees, altitude,
Maidenhead grid (recomputed live as you move), and — from a live fix — ground
speed (km/h and knots) and course over ground (degrees true with a cardinal
label), plus a fix/satellite-count/HDOP status line.
New: Sat-to-sat visibility finder (Satellites → 2)
Finds the windows over the next five days when the selected satellite and a second
satellite (chosen from your favorites) are both above your horizon at the same
time — for cross-satellite relay experiments or back-to-back working on one
outing. Each row shows the window's start (UTC), duration, and the peak elevation of
each bird. n cycles the second satellite; r recomputes.
New: Jump to beacon (n on Track / Big readout)
One key on the Track and large-font readout screens tunes straight to the
satellite's beacon — its downlink-only/telemetry entry (preferring one whose
description names a beacon) — with Doppler correction, for finding a bird by its
beacon before working it. If the satellite has no beacon listed, a status note says
so.
New: DX Doppler table (Mutual windows → d)
From a mutual-visibility window, d opens a table of the RX and TX dial
frequencies for both your station and the DX station, every 30 seconds across the
window, for the transponder you've selected (with t on Satellites). Because
each station's Doppler differs, their dials differ — this lays out exactly where
both operators should tune to stay on the same channel through a short pass.
- Three modes (
m): true rule (operating point fixed in the satellite
passband, every dial Doppler-tracks), fixed downlink, and fixed uplink
(the anchor station holds one dial constant in real RF and the other three
follow). acycles the anchor dial (my RX/TX, DX RX/TX); for a linear
transponder,,//(and</>) move the passband operating point.;/.scroll the 30-second steps. RX is shown in gree...
CardSat v0.9.22
v0.9.22 supersedes v0.9.21, which was broken. If you flashed 0.9.21, please
update. 0.9.22 fixes two regressions that made 0.9.21 effectively unusable on the
Cardputer ADV (see "Critical fixes" below). The feature content is otherwise the
same as 0.9.21 (the IR pass beacon, described further down).
Critical fixes (v0.9.22)
-
Voice memo now records on the Cardputer ADV. The ADV's ES8311 mic codec is
driven through M5Unified'sM5.Micwithcfg.internal_micenabled, built against
ESP-IDF 5.4.x (Espressif esp32 Arduino core 3.2.x). See the note at the end and
MANUAL.md §"Voice memo" for the toolchain requirement. -
Downloads no longer freeze the screen. On the ESP-IDF 5.4.x toolchain (required
for the mic), the display canvas was being freed to make heap room for the TLS
handshake and then could not be reallocated — the 64 KB block never returns on this
toolchain — leaving the whole device frozen after any update. The display canvas is
now an 8 bpp palette sprite (~32 KB instead of ~64 KB), which leaves enough free
heap (~85 KB) for the handshake with the sprite kept allocated the whole time. The
sprite is never freed/recreated, so the screen can't freeze, and a real RGB565
palette keeps colors correct. Net result: updates download and the UI stays live and
full-color throughout.
An IR pass-alert beacon: the built-in IR LED now flashes on each pass-alert event,
with a distinct number of flashes per event, so you can build your own
IR-triggered hardware.
Hardware status. Host-verified only (tokenizer-balanced; the carrier timing
and flash-count state machine compiled with mocks and checked off-device). The
actual IR output and a receiver decoding it have not been confirmed on a device —
verify before relying on it.
IR pass beacon (build-your-own trigger)
Enable Settings → Station → IR pass beacon (off by default) and CardSat will
flash the Cardputer's built-in IR LED (GPIO 44) on every existing pass-alert event,
in addition to the usual beeps. Each event sends a distinct number of flashes:
| Event | Flashes |
|---|---|
| T-60 s to AOS | 1 |
| T-30 s to AOS | 2 |
| T-10 s to AOS | 3 |
| AOS (pass start) | 4 |
| TCA (peak elevation) | 5 |
| LOS (pass end) | 6 |
Each flash is a ~60 ms burst of standard 38 kHz IR carrier with ~140 ms gaps —
the kind any common IR receiver/demodulator (TSOP38238, TSOP4838, etc.) detects.
CardSat only transmits the counts; the receiving side is yours to design. Point
a 38 kHz receiver at the Cardputer, count the pulses, and trigger whatever you want:
power up a rotator/preamp at T-10, flash a shack light at AOS, start an SDR
recording, drive a louder external alert, or log events on a second microcontroller.
The flashing is fully non-blocking — one burst at a time between the normal
tracking updates — so radio, rotator, and web control keep running throughout. It's
gated by the AOS-alarm system, so it only fires when the AOS alarm is on.
Host-verified only. The 38 kHz carrier, duty cycle, and burst/gap timing may need
tuning for your particular receiver; treat the flash counts as the stable
contract and the exact waveform as adjustable. The feature uses only GPIO 44 (the
built-in IR LED) and is off until you enable it.
Notes
-
Cardputer ADV voice memo works when built against ESP-IDF 5.4.x. The ADV's
ES8311 mic codec records correctly on the Espressif esp32 Arduino core 3.2.x
(IDF 5.4.2); on the 3.3.x core (IDF 5.5.x) the codec's record clock isn't driven
and recordings are silent — an upstream regression
(espressif/esp-idf#18621),
not a CardSat bug. Voice memo captures via M5Unified'sM5.Micwith
cfg.internal_micenabled. Only voice memo is affected by the toolchain; every
other feature builds and runs on either core. The boot log's IDF version (5.4.x)
confirms a correct build. See MANUAL.md §"Voice memo". -
All host-verified only. The IR carrier generation (LEDC PWM at 38 kHz, gated per
burst) and the flash state machine were checked off-device (balance + g++
semantic compile + a mock-clock run of every flash count), but on-device
confirmation — that a real IR receiver sees and counts the bursts — is still
needed.
CardSat v0.9.21
An IR pass-alert beacon: the built-in IR LED now flashes on each pass-alert event,
with a distinct number of flashes per event, so you can build your own
IR-triggered hardware.
Hardware status. Host-verified only (tokenizer-balanced; the carrier timing
and flash-count state machine compiled with mocks and checked off-device). The
actual IR output and a receiver decoding it have not been confirmed on a device —
verify before relying on it.
IR pass beacon (build-your-own trigger)
Enable Settings → Station → IR pass beacon (off by default) and CardSat will
flash the Cardputer's built-in IR LED (GPIO 44) on every existing pass-alert event,
in addition to the usual beeps. Each event sends a distinct number of flashes:
| Event | Flashes |
|---|---|
| T-60 s to AOS | 1 |
| T-30 s to AOS | 2 |
| T-10 s to AOS | 3 |
| AOS (pass start) | 4 |
| TCA (peak elevation) | 5 |
| LOS (pass end) | 6 |
Each flash is a ~60 ms burst of standard 38 kHz IR carrier with ~140 ms gaps —
the kind any common IR receiver/demodulator (TSOP38238, TSOP4838, etc.) detects.
CardSat only transmits the counts; the receiving side is yours to design. Point
a 38 kHz receiver at the Cardputer, count the pulses, and trigger whatever you want:
power up a rotator/preamp at T-10, flash a shack light at AOS, start an SDR
recording, drive a louder external alert, or log events on a second microcontroller.
The flashing is fully non-blocking — one burst at a time between the normal
tracking updates — so radio, rotator, and web control keep running throughout. It's
gated by the AOS-alarm system, so it only fires when the AOS alarm is on.
Host-verified only. The 38 kHz carrier, duty cycle, and burst/gap timing may need
tuning for your particular receiver; treat the flash counts as the stable
contract and the exact waveform as adjustable. The feature uses only GPIO 44 (the
built-in IR LED) and is off until you enable it.
Notes
- All host-verified only. The IR carrier generation (LEDC PWM at 38 kHz, gated per
burst) and the flash state machine were checked off-device (balance + g++
semantic compile + a mock-clock run of every flash count), but on-device
confirmation — that a real IR receiver sees and counts the bursts — is still
needed.
CardSat v0.9.19
A world-map view you can recenter on your own location, plus a fast update option
that refreshes elements and transponders for just your favorite satellites.
Hardware status. Host-verified (tokenizer-balanced, the projection math and
seam handling checked off-device and rendered at several center longitudes) but
not yet run on a device this release. The exact on-screen look and the footer fit
still want a quick confirmation on a real Cardputer ADV.
Recenter the world map on your location
The World Map (from the Schedule screen, key m) can now be centered on your
QTH instead of always showing the classic 0°-longitude-centered view. Press c
on the map to toggle:
- Centered on QTH — your station sits in the middle of the map, with the world
wrapping around it. Handy when your area would otherwise sit off near the edge. - Classic (0°) — the familiar view centered on the prime meridian.
The choice is remembered across reboots. Only the longitude (left–right) is
recentered; latitude stays fixed so north is always up and the equator stays in the
middle — the standard convention for this kind of map. Satellite sub-points,
footprint circles, the graticule, and the prime-meridian line all follow the
recentered view, and the international date-line seam is handled so coastlines and
footprints don't streak across the map wherever the seam lands.
This affects only the main World Map screen; the ground-track map on the
orbital-analysis page and the simulation map keep their standard 0°-centered view.
The World Map now also has its own entry on the Home menu (right after
Track (sel)), in addition to the existing m shortcut from the Next Passes screen.
Back returns to wherever you opened it from.
Fast update (favorites only)
The Update screen has a new f — fast update key. It refreshes the orbital
elements (GP), the AMSAT activity marks (a single bulk fetch, so it's included),
and the transponder data for your favorites only — skipping the space-weather
and terrestrial-weather fetches that the full k update also pulls. It's the quick way to bring the birds you actually work
current without waiting for the longer full refresh — useful in the field on a
slower link. With no favorites marked, it refreshes the currently active satellite
instead. The existing k (full update) and a (cache all transponders) are
unchanged.
Notes
- Host-verified only: the recenter and seam logic were checked off-device and the
map rendered at several center longitudes (Americas, Europe, Asia/Pacific) to
confirm the seam stays clean even when it falls over land. On-device appearance
still wants a look on real hardware.
CardSat v0.9.18
Refinements to the large-font readout, a matching large-font Manual view, wider
tilt-tuning coverage, an optional second WiFi network for field use, and tidier
frequency formatting on every band.
Hardware status. All of this is host-verified (tokenizer-balanced, the
frequency formatter and tilt logic checked off-device) but has not been run on a
device this release. The large-font layout fit and the tilt feel still want
confirmation on a real Cardputer ADV.
Large-font readout: bigger numbers, follows the tune mode, full tuning
- The AOS/LOS countdown was removed from the large-font view and the RX/TX
frequencies enlarged to use the freed space — they're now the dominant element,
readable at arm's length. (The countdowns remain on the regular Track and Passes
screens.) - The big view now follows the Doppler tuning option selected on Track: the
bottom line shows the active mode (FULL / DL / UL / TUNE / CAL) and, on a
linear bird, the live passband position. - Passband tuning works from the big view. All the in-place Track controls are
available without leaving it —,//tune,s/xstep/recenter,mTUNE/CAL,
dcycle mode,tnext transponder,r/oradio/rotator,ytilt,llog.
This is done by delegating to the Track key handler, so behaviour (including the
FULL/DL knob-driven guard) is identical and lives in one place.
Large-font Manual calculator (z from Manual)
The no-radio Manual frequency calculator gains its own large-font view, opened
with z. It shows the HOLD and TUNE legs in big digits with the fixed
and derived legs labelled, using the same round-trip Doppler maths as the normal
Manual screen. The in-place keys (u swap leg, m CAL, ,// tune, s/x,
t) work there too; z or ` returns to the standard Manual view.
Tilt tuning extended to Manual mode
Accelerometer (tilt) passband tuning — opt-in and ADV-only — now also works on the
Manual and Manual large-font screens, not just Track and the Track
large-font view. A TLT/TILT marker shows when it's armed. (On Track/Big the
FULL/DL modes are knob-driven so tilt stands aside; the Manual screen has no radio,
so it simply moves the passband.)
Mobile web control page (opt-in)
CardSat can now serve a mobile-friendly web page over the WiFi LAN so a phone
or tablet can drive it without touching the keypad. Enable it under Settings →
Network / data → Web control; the row then shows the URL to open (e.g.
http://192.168.1.42). From the page you can:
- select a satellite from your favourites and start tracking it, or add/remove
the chosen satellite from favourites with the ★ button beside the selector, - see upcoming pass times (AOS, peak/closest-approach time, max elevation,
duration, az) for the active satellite, - control the radio and rotator — tune the passband, step the transponder,
cycle tune mode, recenter, and toggle radio/rotator output.
A Manual toggle on the page switches the controls to the no-radio hand-tuning
calculator: it shows the HOLD leg (where to park your own radio) and the
TUNE leg (the Doppler-corrected frequency to follow), with the same round-trip
correction as the on-device Manual screen, plus a Swap leg button to choose
which leg you hold.
An Orbit toggle adds a read-only orbital-analysis view: altitude/footprint,
period, apogee/perigee, inclination/eccentricity, decay estimate, live range-rate
and sub-point, sunlit/eclipse state, beta angle and eclipse fraction, J2 node and
perigee drift (with a sun-sync flag), mean/true anomaly, time to perigee/apogee,
and the multi-day pass outlook — the same numbers the on-device orbital-analysis
pages show, surfaced as one screen. The underlying computation was kept in one
place (buildOrbit() gained a headless mode), so the web view and the device
never disagree.
It's built in the same cooperative, non-blocking style as the existing
rigctld/rotctld servers, and every control drives the same key handlers the
physical keypad uses, so the web UI never re-implements radio or rotator logic.
The page itself is a single self-contained file served from program memory, so it
adds no meaningful pressure to the no-PSRAM heap.
Security note. This is plain HTTP on the local network with no
authentication — anyone on the same WiFi can open it. It's off by default;
turn it on only on networks you trust, and it is not intended to be exposed to the
internet.
Optional second WiFi network
Settings now has an optional second WiFi network (WiFi 2 SSID / WiFi 2 pass,
under Network / data). If the primary network can't be joined, CardSat
automatically falls back to the second one. This is aimed at field use: keep your
home router as the primary and a phone hotspot or portable travel router as the
second, and the device connects to whichever is in range. Leave it blank to keep
the previous single-network behaviour. The fallback applies everywhere CardSat
connects — boot, GP updates, and on-demand fetches.
Tidier frequency readouts on any band
Frequency displays now shed decimal places as the integer part grows, so they
stay within the panel on any band rather than overflowing. Sub-GHz birds keep their
full precision (e.g. 145.99000); higher bands automatically show fewer decimals
(1296.500, and so on up the range). This keeps both the normal and large-font
readouts tidy without truncating the part that matters.
More readable menu selection
The highlighted (selected) row in menus and lists used a pure, fully-saturated
green bar, which glared and bloomed into the black text — a reader reported it as
hard to read. The selection bar is now a calmer medium forest green, keeping the
"green = selected" cue across the whole UI while making the black text comfortably
legible. The change applies everywhere a selection bar appears (home menu, sat
list, schedule, passes, log, settings, GP-source picker, WiFi scan, and mutual
visibility); the destructive "danger" rows stay red.
Reliable downloads on a weak signal
Large downloads (the GP catalog above all) could be silently truncated on a weak
WiFi link — the file would stop part-way, cache as if complete, and only a
handful of satellites would parse. Two causes were fixed: the streaming reader no
longer mistakes a brief TLS burst gap (common at low signal) for the end of the
body when the server has declared a content length, and it now verifies the full
declared size arrived before accepting the file. A short read is treated as a
failure, and the GP fetch now retries (up to three attempts) instead of caching
a partial catalog. Small downloads were unaffected; this specifically rescues the
big ones on marginal links.
Web control: UTC times and downloads while connected
Two fixes for the mobile web page:
- Pass times now show in UTC (with a
Zsuffix) instead of being converted to
the phone or laptop's local timezone — matching how CardSat shows time everywhere
else, which is what satellite operators expect. - Downloads no longer fail while web control is on. Any internet fetch — keps
(GP), weather, space weather, AMSAT status, transponders, or a QRZ lookup — while
the web server was running could be refused ("connection refused"): the LAN
listeners were holding sockets that the outbound HTTPS connection needed on the
socket-limited, no-PSRAM ESP32-S3. The listeners are now briefly released for the
duration of any download and rebuilt automatically afterward, so the browser
simply reconnects on its next refresh. This is handled in one place (around every
TLS session), so it covers all current and future fetches uniformly.
Notes
- Host-verified only; confirm on hardware before relying on the new views during a
pass — in particular the large-font layout and the tilt feel on a real ADV. - Frequencies are stored as 32-bit Hz, so the practical ceiling is about 4294 MHz;
the formatter is bounded well beyond the amateur satellite bands in use.
CardSat v0.9.17
Three operator-facing additions: a large-font operating readout, an adjustable
screen brightness, and opt-in accelerometer (tilt) tuning.
Hardware status. The readout and brightness controls are host-verified
(tokenizer-balanced, logic-checked) but have not been exercised on a device this
release. Tilt tuning is opt-in and ADV-only; its logic is host-tested with a
mocked IMU (the passband moves and clamps correctly), but the live sensor path
and the feel of the rate curve have not been confirmed on hardware — expect
to fine-tune the dead-zone and rate to taste.
Large-font operating readout (press z on Track)
A stripped-down, glanceable view for working a pass without squinting at the small
type. It shows the RX and TX frequencies in large digits, Az/El below
them, and a big LOS countdown — or an AOS countdown when the bird is below
the horizon, or ** WORKABLE ** when it's up. Small badges show RAD /
ROT (radio and rotator state), TILT if tilt tuning is armed, and the
transponder index.
The radio, rotator and Doppler tracking keep running exactly as on Track — this is
purely an alternate view of the same live session (the tracking service is gated on
whether radio/rotator output is on, not on which screen is showing). t (next
transponder), r (radio), o (rotator) and l (log a QSO) all work without
leaving the readout. Press z or ` to return to Track.
(Note: z was chosen because b and h are global hotkeys — screenshot and
help — and never reach the per-screen handlers.)
Screen brightness setting
The active backlight level is now adjustable under Settings → Station / display →
Brightness (,// in ~6% steps, with a live preview). It's saved with the rest
of the configuration and re-applied at boot and whenever the display wakes from the
sleep timeout. Previously the brightness was a fixed compile-time constant.
Accelerometer (tilt) tuning — opt-in, ADV only
The Cardputer ADV carries a motion sensor (the original Cardputer does not).
With Tilt tuning switched on under Settings → Station / display, you can roll
the device left/right to move through a linear transponder's passband instead of —
or alongside — the ,// keys.
It's deliberately a rate control rather than an absolute mapping, which is far
steadier to hold by hand: a gentle tilt nudges slowly for fine work, a firmer tilt
slews faster, and holding the device level holds the frequency. A few-degree
dead-zone around level keeps a hand-held device from drifting, the reading is
low-pass filtered to tame sensor noise, and the rate saturates past roughly 35°.
The feature is off by default and only acts on the Track and large-font
screens, in TUNE mode, on a linear bird; everywhere else it does nothing.
A TLT/TILT marker shows when it's armed, and you can flip it on/off mid-pass
with y on either screen without opening Settings. On a board without the
sensor the setting reads n/a (no IMU) and can't be enabled, so nothing changes
for original-Cardputer users. It's offered as an option, not a default — tilting
the device also moves your antenna and your eyes, so many operators will still
prefer the keys.
Notes
- All three are host-verified only; confirm on hardware before relying on them
during a pass. In particular the tilt rate curve (≈8 kHz/s at full tilt, ~7°
dead-zone) is a first guess and will likely want adjustment once you feel it on
a real ADV.
CardSat v0.9.16
A focused bug-fix release for Manual mode (the no-radio frequency calculator),
correcting the uplink/downlink math when working a linear transponder full
duplex and holding one leg fixed.
Hardware status. The fix is host-verified: the new frequency math is checked
against an independent round-trip Doppler model across the full range-rate span,
for both inverting and non-inverting transponders, holding the operator on their
own signal to within a few Hz. It has not yet been confirmed on the air. A quick
on-air check (park one leg, work yourself across a pass) would close the loop —
see the note below.
Manual mode: round-trip Doppler when holding one leg fixed (bug fix)
On the Manual screen you fix one leg — the frequency you park on your own radio —
and CardSat shows the frequency to tune the other leg to. For a linear
transponder worked full duplex, the goal is to keep hearing yourself on a
stationary frequency while the satellite moves. The previous math handled each leg
independently (the same satellite-frame convention CardSat uses when it drives a
real radio, where you let the downlink drift and chase it). That is the wrong
convention for the Manual calculator's "park one leg, hear yourself" use: it does
not account for the round trip.
The physics: on a linear bird, where your own signal lands on the downlink depends
on where the satellite heard your uplink. So holding one leg stationary requires
the other leg to cancel both Doppler shifts, not just its own. With the old
per-leg math, the operator's own signal drifted off the fixed leg by:
- up to ~3 kHz at ±7 km/s when holding the downlink (tuning the uplink), and
- up to ~10 kHz at ±7 km/s when holding the uplink (tuning the downlink) —
larger because, on an inverting transponder, the fixed-uplink Doppler and the
downlink Doppler add rather than partly cancel.
Either was enough to walk you out of an SSB passband mid-pass.
Both directions are now corrected. Two new predictor helpers,
uplinkForFixedDownlink() and downlinkForFixedUplink(), compute the derived leg
from the round trip and hold the operator on their own signal to within a few Hz
across the pass, for both inverting and non-inverting transponders, with
per-satellite calibration applied. Toggle which leg is fixed with u as
before.
Unaffected on purpose:
- FM birds — the uplink and downlink are independent channels (no shared
passband), so the plain per-leg Doppler is correct; no round-trip term is
applied. - The Track screen (driving a real radio) — it intentionally fixes a point in
the satellite passband and Doppler-corrects both legs around it, letting the
downlink drift on the ground while the operator's knob (or CardSat) follows it.
That convention is correct for live radio control and is unchanged.
Notes
- This release changes only Manual-mode display math and the firmware version
string; nothing else from 0.9.15 is altered. - Still worth an on-air confirmation: park one leg on a linear bird (e.g. an
inverting SSB transponder) and check that you keep hearing yourself on the fixed
frequency as the pass develops. The math is verified against a round-trip model
but has not been flown.
CardSat v0.9.15
A radio- and rotator-control refinement release, with several ideas adapted from
the open-source OscarWatch tracker (Peter Goodhall, MM9SQL) after studying its
Doppler and rotator source. The Doppler-correction math was already on par; the
improvements here are in when and how CardSat talks to the radio and rotator.
This release also documents that per-satellite calibrations can be hand-authored
on the SD card, and makes those files comment-friendly.
Hardware status. Pass prediction, plots, GPS, the AOS alarm, deep sleep, and
the offline caches are confirmed on hardware. The radio and rotator refinements
in this release are host-verified only (tokenizer-balanced, logic-checked)
and have not yet been exercised against a physical rig or rotator. The constants
below use OscarWatch's field-tuned values as a starting point and may want
adjustment for your specific CI-V latency or rotator slew rate.
Doppler / CAT control
Three refinements to the real-time Doppler service, gated so they do nothing on
slow, low-elevation passes and only engage where they help (fast overhead passes):
- Mode-aware write deadband. CardSat already skipped re-sending a leg that
hadn't moved; the deadband is now mode-aware — loose for FM (300 Hz, whose
passband absorbs Doppler) and tight for linear SSB/CW (50 Hz). This cuts
needless CI-V traffic and audible stepping, and matters most on slow-CI-V rigs. - Adaptive threshold near TCA. When the Doppler slew rate is high (the fast
geometry around closest approach), the deadband tightens automatically — ramping
down above 15 Hz/s, halving by 35 Hz/s, with a 25 Hz floor — so tracking keeps
up where it counts and stays relaxed elsewhere. - TCA-tapered predictive lead. The correction can be computed slightly ahead
(up to 50 ms) to mask CAT latency, blended in proportionally to how fast Doppler
is changing and tapered to zero near closest approach, where range rate is
small and a forward lead would overshoot.
All three are compile-time constants (DOPP_* in app.h) — no new settings. The
cost is one extra range-rate evaluation per service tick (a second only when the
lead is active), negligible on the ESP32-S3.
Rotator control
- 450° azimuth lookahead (shortest-path over north). On a 450° rotator,
CardSat already used the 361–450° overlap band to avoid unwinding ~360° when a
pass crosses north — but reactively, after the bearing had already crossed. It
now looks 3 s ahead (one extra propagation per ~1 Hz rotator tick) and
pre-commits to the overlap band before an imminent north wrap, turning a
long unwind into a short move. Two guards keep this safe: it is computed only on
a 450° rotator, and never when a pass is flipped (where the +180° azimuth
makes the overlap reasoning meaningless). The hint is single-shot, so it can
never leak into a later park, pre-position, Sun/Moon, or manual command.
Calibration & tones on the SD card
- Documented: hand-author per-satellite calibrations. Per-sat calibration has
always been stored as a plain-text file; this release documents the format
so you can bulk-edit it on a computer instead of nudging each bird in CAL
mode. Edit/CardSat/calib.txt— onenorad downlink_Hz uplink_Hzline per
satellite — and the values apply the next time you open that bird (no reflash).
CTCSS overrides work the same way in/CardSat/tones.txt
(norad tone_tenths). See Manual §10. - Comment-friendly files. Both files now ignore blank lines and lines starting
with#or;, so you can annotate your calibrations. Saving on the device
preserves your comment lines.
Tunable from Settings (no reflash)
The Doppler and rotator refinements above shipped with sensible compile-time
defaults; the four values most likely to want field-tuning are now adjustable on
the device under Settings, persisted across reboots:
- Dopp FM band (default 300 Hz) and Dopp linear band (default 50 Hz) — the
per-mode CAT write deadbands (Radio / CAT category). - Dopp lead (default 50 ms;
0= off) — the predictive-lead cap. Raise it for
a slow-CI-V rig, or disable it entirely. - Rot az lookahead (default 3 s;
0= off) — the 450° azimuth lookahead
horizon (Rotator category). Tune to your rotator's slew speed, or turn it off to
use the previous reactive-only overlap behaviour.
IC-820H CI-V band-select (bug fix)
CardSat previously shipped the IC-820H with the same MAIN/SUB band-select
sub-commands as the IC-821H — which turns out to be wrong. Confirmed from each
radio's own manual (CI-V command table, command 07):
| Radio | Address | Main band access | Sub band access |
|---|---|---|---|
| IC-821H | 4C |
0x07 D0 |
0x07 D1 |
| IC-820H | 42 |
0x07 D1 |
0x07 D0 |
The IC-820H reverses the two sub-commands relative to the IC-821H. CardSat now
ships the correct mapping for each (selMain/selSub swapped between the two
profiles), so an IC-820H tunes the right VFO out of the box. Previously it would
have Dopplered the wrong band. The IC-820 profile is now marked verified. See
Manual §16.
EQX table for OSCARLOCATOR use
A new EQX table screen (Satellites → e) lists equatorial crossing times
and longitudes for the selected satellite, for plotting passes on a classic
OSCARLOCATOR board.
- Each entry is an ascending-node crossing (ground track crossing the equator
northbound), with the UTC time and sub-satellite longitude in
West-positive notation (123.4 W) — the convention printed on Oscarlocator
dials. - Covers the next 3 days, day-grouped and scrollable (
;/.),rto
recompute,dto toggle ascending ↔ descending node (the header reads
EQX or DEQX), computed entirely on-device from the satellite's GP
elements via SGP4 (no network). Successive crossings step ~28.7°/orbit westward
for an AO-7-class orbit. - Works for any satellite in the catalog, not just AO-7. Mirrors the output of
the AO-7_OSCARLOCATOR generator (N8HM). See Manual §8.
Edit / delete manual satellites & transponders
You can now remove hand-entered data from the device — previously, manually-added
GP satellites and transponders could only be added, never cleaned up.
- Delete a manual satellite — on Satellites, select a sat you added with
nand pressxtwice (arm, then confirm). It's removed from
/CardSat/mgp.jsonand from your favorites. Network-cached sats are protected
(they can't be deleted this way, since Update would just re-fetch them). - Delete a manual transponder — on the Transponder database (
tfrom
Satellites), the list is now selectable (;/.), the selected entry is marked
>, and your own entries are tagged*. Pressxtwice to delete the selected
manual entry; its line is removed from/CardSat/mtx_<norad>.json. SatNOGS
entries are protected the same way. - Editing is delete-then-re-add: remove the entry and recreate it with
n.
This keeps the UI small (no separate edit screen) while covering the need.
Both deletes are two-press confirmed and only ever touch hand-entered data.
CelesTrak GP queries & 9-digit NORAD IDs
Verified CardSat's GP/element requests against CelesTrak's current
specification (A New Way to Obtain GP Data). Requests already conform: host
celestrak.org (the .com host 301-redirects and risks an IP firewall), path
/NORAD/elements/gp.php, uppercase query keys, group/special values matching
CelesTrak's own examples, and an explicit valid FORMAT=JSON (rather than relying
on the server default, which changed to CSV in 2026). Error handling also matches
their guidance — responses are checked for HTTP 200, redirects are followed, and
retries are bounded with backoff rather than hammering.
Also audited and confirmed forward-compatibility with 9-digit catalog
numbers (the Space-Fence / 18 SDS 799xxxxxx analyst ranges that exceed the
classic 5-digit TLE limit). CardSat stores every NORAD id as a 32-bit value
(good past 4.2 billion) and ingests GP only via OMM/JSON NORAD_CAT_ID, so
9-digit ids parse, store, dedup, cache, and propagate correctly — confirmed by a
host test across the full range up to 999999999. The only 5-digit-limited spot is
the catalog field of the synthesized TLE line fed to the SGP4 initializer, which
is cosmetic (the propagator uses the orbital elements, not that field, and CardSat
never reads it back as identity); this is now documented in satdb.cpp.
IC-910 CI-V satellite-mode & tone (bug fix), CAT cross-checked against manuals
Before release, the Icom CI-V profile constants were reconciled against Hamlib and
then against the official Icom manuals (IC-9700 CI-V Reference Guide, IC-910
instruction manual). This surfaced two real IC-910 bugs:
- Satellite mode. CardSat sent
0x16 0x07to engage sat mode on every Icom.
That's correct for the IC-9100/9700 (0x16 0x5A) once you account for the
sub-command, but the IC-910 puts satellite mode under a different command
entirely:0x1A 0x07(verified from the IC-910 CONTROL COMMAND table). The old
code's0x16 0x07doesn't exist on the IC-910, so sat mode silently never
engaged. Fixed: satmode now carries a per-rig command byte (satModeCmd), so
the IC-910 sends0x1A 0x07while the IC-9100/9700 send0x16 0x5A. - CTCSS tone encoder. On the IC-910,
0x16 0x42is the auto-notch filter;
the subaudible-tone encoder is0x16 0x43. CardSat had been sending0x42,
which would toggle the notch instead of the tone. Fixed with a per-rig
toneEncSub(IC-...
CardSat v0.9.14
An offline-readiness release. "Cache all transponders" now reliably caches the
full catalog on a real Wi-Fi link by working with the ESP32's small socket
pool instead of fighting it: the run is split into small batches across automatic
reboots, each batch starting from a fresh network connection. No satellite is
skipped — a sat that fails its retries is re-attempted after the next reboot. The
Update action also runs the space-weather and weather fetches in sequence, and
the slow-first-response NOAA feeds get a longer connect window.
Hardware status. Pass prediction, plots, GPS, the AOS alarm, deep sleep, and
the offline caches are confirmed on hardware. The batched cache-all flow in this
release is confirmed on a Cardputer (full 90-satellite catalog cached over
several automatic reboots, including automatic recovery of a satellite that
failed its in-boot retries). The radio and rotator paths remain host-tested only.
The problem this fixes
Caching every satellite's transponders means ~90 sequential HTTPS requests to the
SatNOGS API. On the no-PSRAM ESP32-S3 the LWIP socket pool is small (~10–16
sockets), and after a few dozen TLS connections in one session the pool is
exhausted: further connect() calls return -1 (connection refused) and the rest
of the run fails. Earlier attempts to fetch the whole transmitter table in one
request were ruled out — the table is ~3.4 MB (too large to stream reliably on a
weak link) and the SatNOGS endpoint supports neither HTTP Range requests nor
pagination on that view.
The fix sidesteps pool exhaustion entirely: cache a small batch, reboot, repeat.
Every reboot gives a pristine socket pool and a fresh Wi-Fi association (which also
resets the RSSI drift seen on long runs), so each batch runs comfortably under the
socket limit.
What's new
- Batched cache-all across reboots.
aon the Update screen now caches
TX_CACHE_BATCHsatellites (default 12) per boot, persists progress to a
marker file (/CardSat/tx_resume.txt), and reboots to continue. The run resumes
automatically on the next boot and finishes on "Cached all N transponders."
The first batch also runs in its own fresh boot, so it doesn't inherit a socket
pool already partly spent by the GP/AMSAT/weather fetches. - No satellite is ever skipped. If a satellite fails all of its retries (the
pool is wedged for that boot), the batch stops at that satellite and the next
boot re-attempts it from a clean pool, rather than advancing past it. A guard
skips a genuinely unreachable satellite after two consecutive stalled boots so a
run can never loop forever. - Resume lands on the Update screen. Each resume boot returns to Update
with a live progress count instead of the Home screen. - Update runs the full refresh chain. One Update now fetches GP → AMSAT status
→ space weather (F10.7 flux + Kp/A) → local weather, in sequence. - Longer connect window for slow-first-response hosts. NOAA SWPC
(government-hosted, load-balanced, strict TLS) can be slow on the first
response/handshake from a fresh client. The flux and Kp fetches now allow a
longer connect/first-byte window (25 s) before timing out, while keeping the
normal mid-stream stall timeout once data is flowing. All other fetches are
unaffected.
Removed
- The dead bulk-table code paths explored on the way to this fix were removed:
the whole-table fetch URL/scratch file, the streaming JSON splitter
(splitBulkTransmittersand helpers), and the HTTPRange/resumable-download
functions (httpsGetRange,httpsGetResumableToFile). The per-sat fetch path
is the one true cache path.
Notes
- The whole cache-all pass takes a few minutes and several automatic reboots —
this is expected. Let it run to completion before going offline. - Satellites with no transmitters in SatNOGS are cached as an empty list (
[]),
which is correct and handled by the loader. - To cancel a pending run, delete
/CardSat/tx_resume.txtfrom the card. - The
setBufferSizes()/ ESP32-core-version constraint described in earlier
release notes no longer applies to cache-all: the batched approach succeeds
regardless, by keeping each boot's connection count low.