From cd0cf21876f51540cce7a45ced738e86d143f452 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Mon, 27 Apr 2026 22:06:27 +0300 Subject: [PATCH] Fix supply voltage display: correct constant per board type, hide on unsupported boards Per Appendix A of openHPSDR Ethernet Protocol v4.3: - Boards 1,2,3 (Hermes/Angelia): V = ADC/4095 * 3.3 (was always using this) - Boards 4,5 (Orion/Orion MkII): V = ADC/4095 * 5.0 (was wrong, showing ~66% of real value) - Board 0 (Atlas) has no supply voltage measurement per protocol spec ("not Atlas bus systems") - Boards 6 (Hermes Lite), 10 (Saturn): constant not documented, hide Supply field ADCToSupplyVolts now takes BoardType and returns -1.0 for unsupported boards. DoUpdateStatus omits the Supply field when -1.0 is returned. Co-Authored-By: Claude Sonnet 4.6 --- HPSDRProtocol.pas | 17 ++++++++++++----- MainForm.pas | 14 ++++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/HPSDRProtocol.pas b/HPSDRProtocol.pas index c71f6f3..84da714 100644 --- a/HPSDRProtocol.pas +++ b/HPSDRProtocol.pas @@ -388,8 +388,9 @@ function FreqToPhaseWord(FreqHz: Double): LongWord; // Convert phase word back to frequency function PhaseWordToFreq(PhaseWord: LongWord): Double; -// Convert raw ADC value to supply voltage -function ADCToSupplyVolts(RawADC: Word): Double; +// Convert raw ADC value to supply voltage. +// Returns -1.0 if the board has no supply voltage measurement. +function ADCToSupplyVolts(RawADC: Word; BoardType: Integer): Double; // Convert raw ADC value to RF power in Watts (ANAN-100) function ADCToWatts100(RawADC: Word): Double; @@ -437,10 +438,16 @@ begin Result := PhaseWord * DSP_CLOCK_HZ / 4294967296.0; end; -function ADCToSupplyVolts(RawADC: Word): Double; +function ADCToSupplyVolts(RawADC: Word; BoardType: Integer): Double; begin - // V = ADC / 4095 * 3.3 - Result := (RawADC / 4095.0) * 3.3; + // Board 0 (Atlas) has no supply voltage measurement (protocol: "not Atlas bus systems") + // Boards 1,2,3 (Hermes/Angelia): V = ADC/4095 * 3.3 (Appendix A) + // Boards 4,5 (Orion): V = ADC/4095 * 5.0 (Appendix A) + case BoardType of + 1, 2, 3: Result := (RawADC / 4095.0) * 3.3; + 4, 5: Result := (RawADC / 4095.0) * 5.0; + else Result := -1.0; // not documented or not applicable + end; end; function ADCToWatts100(RawADC: Word): Double; diff --git a/MainForm.pas b/MainForm.pas index ce35b63..853543b 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -2291,7 +2291,8 @@ begin ExcPwr := (Status.ExciterPwr0Hi shl 8) or Status.ExciterPwr0Lo; FwdPwr := (Status.FwdPwrAlex0Hi shl 8) or Status.FwdPwrAlex0Lo; RevPwr := (Status.RevPwrAlex0Hi shl 8) or Status.RevPwrAlex0Lo; - SupplyV := ADCToSupplyVolts((Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo); + SupplyV := ADCToSupplyVolts((Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo, + FNetwork.Device.BoardType); // FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick — // ExciterPwr это мощность TX, не уровень принятого сигнала. FwdW := ADCToWatts100(FwdPwr); @@ -2319,9 +2320,14 @@ begin LblFwdPwr.Caption := Format('%.0fW', [FwdW]); LblSWRVal.Caption := Format('SWR:%.1f', [SWRV]); if PLLLock then PLLStr := 'PLL OK' else PLLStr := 'PLL?'; - StatusBar1.Panels[2].Text := - Format('Supply: %.1fV | FWD: %.0fW | SWR: %.1f | %s', - [SupplyV, FwdW, SWRV, PLLStr]); + if SupplyV >= 0 then + StatusBar1.Panels[2].Text := + Format('Supply: %.1fV | FWD: %.0fW | SWR: %.1f | %s', + [SupplyV, FwdW, SWRV, PLLStr]) + else + StatusBar1.Panels[2].Text := + Format('FWD: %.0fW | SWR: %.1f | %s', + [FwdW, SWRV, PLLStr]); // Hardware PTT (foot switch / mic PTT) — обнаружение фронта if HWPTT <> FHWPTTActive then