From a5d08fe3d66e95f8360639535a5e3316f320cef6 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Tue, 28 Apr 2026 19:00:19 +0300 Subject: [PATCH] Fix supply voltage: apply PCB voltage dividers and read correct ADC source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Protocol Appendix A documents only the ADC reference voltage constant; the PCB voltage divider must also be applied (from Thetis source): - Boards 1-3 (Hermes/Angelia): ×(4.7+0.82)/0.82 ≈ 6.73, Vref=3.3V - Board 5 (Orion MkII): ×(22+1)/1.1 ≈ 20.9, Vref=5.0V For board type 5, supply voltage is measured via UserADC0 (bytes 57-58), not the supply_volts field (bytes 49-50), matching Thetis behaviour. Co-Authored-By: Claude Sonnet 4.6 --- HPSDRProtocol.pas | 16 ++++++++++------ MainForm.pas | 12 ++++++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/HPSDRProtocol.pas b/HPSDRProtocol.pas index 84da714..c480085 100644 --- a/HPSDRProtocol.pas +++ b/HPSDRProtocol.pas @@ -440,13 +440,17 @@ end; function ADCToSupplyVolts(RawADC: Word; BoardType: Integer): Double; begin - // 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) + // Protocol Appendix A gives the ADC reference voltage only. + // The PCB voltage divider (from Thetis source) must also be applied. + // Board 0 (Atlas): no supply voltage measurement. + // Boards 1,2,3 (Hermes/Angelia): Vref=3.3V, PCB divider R1=4.7kΩ/R2=0.82kΩ. + // Board 5 (Orion MkII): Vref=5.0V, PCB divider R1=22kΩ/R2=1.1kΩ. + // NOTE: for board 5 caller must pass UserADC0, not supply_volts bytes. + // Board 4 (Orion) and others: not available (return -1). 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 + 1, 2, 3: Result := (RawADC / 4095.0) * 3.3 * ((4.7 + 0.82) / 0.82); + 5: Result := (RawADC / 4095.0) * 5.0 * ((22.0 + 1.0) / 1.1); + else Result := -1.0; end; end; diff --git a/MainForm.pas b/MainForm.pas index 1bb311a..be3f9c7 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -2461,8 +2461,16 @@ 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, - FNetwork.Device.BoardType); + // Board 5 (Orion MkII) measures supply voltage via UserADC0 (bytes 57-58), + // not the supply_volts field (bytes 49-50) — matching Thetis behaviour. + if FNetwork.Device.BoardType = 5 then + SupplyV := ADCToSupplyVolts( + (Status.UserADC0Hi shl 8) or Status.UserADC0Lo, + FNetwork.Device.BoardType) + else + SupplyV := ADCToSupplyVolts( + (Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo, + FNetwork.Device.BoardType); // FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick — // ExciterPwr это мощность TX, не уровень принятого сигнала. FwdW := ADCToWatts100(FwdPwr);