From b2eb6a4b1e67291ca0db09f8adad56540a8219e5 Mon Sep 17 00:00:00 2001 From: rouggy Date: Sat, 29 Aug 2026 16:06:05 +0200 Subject: [PATCH] fix(icom): the 7760 power meter interpolates between MEASURED anchors A known 50 W read raw ~89 where the two-segment curve said 62: the face is not linear in watts below half scale. Watts now interpolate through the measured points (50 W, 100 W, full-scale 250 W); refining the curve is adding a row to the table. --- frontend/src/components/IcomPanel.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/IcomPanel.tsx b/frontend/src/components/IcomPanel.tsx index 0d6cd1d..84506be 100644 --- a/frontend/src/components/IcomPanel.tsx +++ b/frontend/src/components/IcomPanel.tsx @@ -135,10 +135,20 @@ function fmtVFO(hz?: number): string { // and raw 213 is full scale. On a real 7760 a measured 100 W sits at half // deflection of the 250 W face — the linear ×2.5 first tried showed 140 W for // it. Below half scale watts run 0→100, above it 100→250. +// The anchors are MEASURED on the real radio, not derived: a known 50 W read +// raw ≈89 and a known 100 W read raw 143 (Icom's documented half-deflection), +// with raw 213 = full scale = 250 W. The face is not linear in watts at the +// bottom — a two-segment guess showed 50 W as 62 — so watts interpolate +// between the measured anchors, and a new measurement just adds a row. +const ICOM_7760_PO: [number, number][] = [[0, 0], [89, 50], [143, 100], [213, 250]]; function icomWatts(pct: number): { w: number; defl: number } { const raw = Math.max(0, pct * 2.55); const defl = raw <= 143 ? (raw / 143) * 50 : Math.min(100, 50 + ((raw - 143) / 70) * 50); - const w = raw <= 143 ? (raw / 143) * 100 : Math.min(250, 100 + ((raw - 143) / 70) * 150); + let w = 250; + for (let i = 1; i < ICOM_7760_PO.length; i++) { + const [r0, w0] = ICOM_7760_PO[i - 1], [r1, w1] = ICOM_7760_PO[i]; + if (raw <= r1) { w = w0 + ((raw - r0) / (r1 - r0)) * (w1 - w0); break; } + } return { w: Math.round(w), defl }; }