fix(icom): needle inertia for the TX meters, and room for three digits

The CI-V meters are point samples: between two SSB syllables a poll lands on
0 W and a perfect SWR, so a 150 W transmission read 0-10 W most of the time
and the SWR sat at 1.0. Power now decays like a needle and SWR holds its peak
then snaps to the live value — the same meterPeak the Yaesu and Kenwood
consoles already use. The readout column also widens so '180 W' stays on one
line.
This commit is contained in:
2026-08-30 02:40:07 +02:00
parent db7ac771b1
commit dc94aa94b6
3 changed files with 18 additions and 6 deletions
+13 -3
View File
@@ -116,7 +116,13 @@ type IcomSerial struct {
// "alive but silent" tolerance below, which used to be
// unbounded and left the display frozen for ever
silentGrace time.Duration // current width of that tolerance (backs off, see ReadState)
dspLoaded bool // readDSP has run since the rig became responsive (loads all
// Needle inertia for the TX meters — the CI-V meters are point samples, and
// between two SSB syllables a poll lands on 0 W and a perfect SWR. See
// meterPeak (yaesu_panel.go): power decays like a needle, SWR holds then
// snaps back to the live truth.
powerPeak meterPeak
swrPeak meterPeak
dspLoaded bool // readDSP has run since the rig became responsive (loads all
// the panel's set-once controls once the rig actually answers)
// When the console last asked for the DSP snapshot. The meters and the
// front-panel rotation are polled ONLY while something is displaying them:
@@ -456,12 +462,16 @@ func (b *IcomSerial) ReadState() (RigState, error) {
sm, _ = b.readMeter(civ.SubMeterS)
po, swr = 0, 0
if tx {
now := time.Now()
if v, ok := b.readMeter(civ.SubMeterPo); ok {
po = v
po = b.powerPeak.update(v, now)
}
if v, ok := b.readMeter(civ.SubMeterSWR); ok {
swr = v
swr = b.swrPeak.updateSnap(v, now)
}
} else {
// Cleared with the carrier, so the next transmission starts fresh.
b.powerPeak, b.swrPeak = meterPeak{}, meterPeak{}
}
}
b.dspMu.Lock()