fix(icom): power in watts on the 7760, and Listening restarts clean
The power meter applies Icom's own meter calibration (raw 143 = half deflection, 213 = full scale) anchored against the real radio: a measured 100 W sits at half deflection of the 7760's 250 W face — the linear guess showed it as 140. The RF power slider says watts on a 200 W rig instead of a percentage the operator has to convert. And the Listening button, pressed while a network Icom is connected, restarts the monitor render-only: it used to open a USB capture from the From-radio device as well, and that second producer interleaved with the network pushes chopped the audio to pieces.
This commit is contained in:
@@ -129,6 +129,19 @@ function fmtVFO(hz?: number): string {
|
||||
}
|
||||
|
||||
// modeMatches marks a mode button active, folding the rig's USB/LSB into SSB.
|
||||
// icomWatts turns the backend's 0-100 meter percentage back into watts on the
|
||||
// IC-7760's own meter face. The backend value is linear in the RAW meter byte
|
||||
// (0-255 → 0-100), but Icom's calibration is not: raw 143 is half deflection
|
||||
// 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.
|
||||
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);
|
||||
return { w: Math.round(w), defl };
|
||||
}
|
||||
|
||||
function modeMatches(btn: string, cur?: string): boolean {
|
||||
if (!cur) return false;
|
||||
if (btn === 'SSB') return cur === 'SSB' || cur === 'USB' || cur === 'LSB';
|
||||
@@ -743,11 +756,13 @@ export function IcomPanel({ onReportRST, isNetwork = false }: { onReportRST?: (r
|
||||
title={onReportRST ? t('rst.clickToFill') : undefined}
|
||||
onClick={onReportRST ? () => onReportRST(sMeterRST(sp.s, sp.over, st.mode)) : undefined} />
|
||||
); })()}
|
||||
{/* The meter reads 0-100% of the rig's own scale. On a 100 W rig the
|
||||
percentage IS the watts; the IC-7760's meter runs to 250 W (the rig
|
||||
makes 200), so its percentage is worth 2.5 W a point — same face as
|
||||
the radio's. */}
|
||||
<Meter label="Po" value={st.power_meter} accent="#ef4444" scale={`${Math.round(st.power_meter * (((st.model ?? '').includes('7760')) ? 2.5 : 1))} W`} />
|
||||
{(() => {
|
||||
if ((st.model ?? '').includes('7760')) {
|
||||
const { w, defl } = icomWatts(st.power_meter);
|
||||
return <Meter label="Po" value={defl} accent="#ef4444" scale={`${w} W`} />;
|
||||
}
|
||||
return <Meter label="Po" value={st.power_meter} accent="#ef4444" scale={`${st.power_meter} W`} />;
|
||||
})()}
|
||||
<Meter label="SWR" value={st.swr_meter} accent="#f59e0b" scale={st.swr_meter > 0 ? `${(1 + st.swr_meter / 33.3).toFixed(1)}` : '1.0'} />
|
||||
</div>
|
||||
|
||||
@@ -793,7 +808,11 @@ export function IcomPanel({ onReportRST, isNetwork = false }: { onReportRST?: (r
|
||||
<Card icon={Mic} title={t('icmp.transmit')} accent="#ef4444">
|
||||
<Row label={t('icmp.power')}>
|
||||
<Slider value={st.rf_power} accent="#ef4444" onChange={(v) => set({ rf_power: v }, () => IcomSetRFPower(v))} />
|
||||
<span className="w-8 text-right text-xs font-mono tabular-nums text-muted-foreground">{st.rf_power}</span>
|
||||
{/* PC is a percentage of the rig's rated power; on a 200 W rig the
|
||||
operator thinks in watts, so say it in watts there. */}
|
||||
<span className="w-12 text-right text-xs font-mono tabular-nums text-muted-foreground">
|
||||
{(st.model ?? '').includes('7760') ? `${st.rf_power * 2} W` : st.rf_power}
|
||||
</span>
|
||||
</Row>
|
||||
{isPhone && (
|
||||
<Row label={t('icmp.mic')}>
|
||||
|
||||
Reference in New Issue
Block a user