fix: read the real SWR on the Yaesu, and show the ratio
A second measurement at a known mismatch settled both the index and the scale. At SWR 1.1: RM6=0. At SWR 1.5: RM6=52, while RM4 kept tracking the power. 52/255 = 0.204, which is the reflection coefficient of a 1.5 SWR to three decimals. So the raw value is rho scaled to 255, and the ratio is (1+rho)/(1-rho) — physics, not a curve fitted through two points, which is why 2.0 and 3.0 fall out of it correctly without ever having been measured. The panel now shows that ratio, the number the operator reads on the rig, rather than a percentage of meter travel — and a dash while receiving, since a stale SWR from the last transmission reads as a live one. Both measurements are recorded in the code and in a test, so the mapping is evidence rather than a table borrowed from another model — which is exactly how it came to read 81 in the first place.
This commit is contained in:
@@ -38,3 +38,41 @@ func TestYaesuDefaultSplitOffset(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The SWR scale, pinned to the two measurements it was derived from.
|
||||
//
|
||||
// Taken on an FTDX10 (2026-07-29) against an operator watching the rig's own
|
||||
// meter: raw 0 at SWR 1.1, raw 52 at SWR 1.5. The second point is what proved
|
||||
// the raw value is the reflection coefficient scaled to 255 — 52/255 = 0.204,
|
||||
// rho for a 1.5 SWR — rather than a percentage of meter travel, which is how the
|
||||
// bar came to read 81 on a perfect antenna.
|
||||
func TestSWRFromReflection(t *testing.T) {
|
||||
cases := []struct {
|
||||
raw int
|
||||
want float64
|
||||
tol float64
|
||||
}{
|
||||
{0, 1.0, 0.01}, // no reflected power
|
||||
{52, 1.5, 0.02}, // the measured mismatch
|
||||
{85, 2.0, 0.05}, // rho = 1/3
|
||||
{128, 3.0, 0.1}, // rho = 0.5
|
||||
{-5, 1.0, 0.01}, // nonsense reading — never below 1.0, which is physical
|
||||
{255, 9.9, 0.01}, // full scale is capped rather than infinite
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := swrFromReflection(c.raw)
|
||||
if got < c.want-c.tol || got > c.want+c.tol {
|
||||
t.Errorf("swrFromReflection(%d) = %.2f, want %.2f ±%.2f", c.raw, got, c.want, c.tol)
|
||||
}
|
||||
}
|
||||
// It must rise with the reflected power, or a worsening match would read
|
||||
// better on the panel than on the rig.
|
||||
prev := 0.0
|
||||
for raw := 0; raw <= 200; raw += 20 {
|
||||
v := swrFromReflection(raw)
|
||||
if v < prev {
|
||||
t.Fatalf("SWR fell from %.2f to %.2f at raw=%d", prev, v, raw)
|
||||
}
|
||||
prev = v
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user