Add supply current display for Orion MkII (Board 5)

UserADC1 (bytes 55-56) carries current sensor data on the ANAN-8000DLE.
Formula from Thetis: amps = ((adc/4095 * 5000) - 360) / 120 (Voff=360mV,
Sens=120mV/A). Status bar now shows "Supply: 13.8V / 2.3A | PLL OK"
when current is available.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 12:29:45 +03:00
co-authored by Claude Sonnet 4.6
parent d823106366
commit d8050576a9
2 changed files with 54 additions and 13 deletions
+37 -13
View File
@@ -148,10 +148,11 @@ type
FFwdW: Double;
FSWRV: Double;
FSupplyV: Double;
FSupplyA: Double;
FPLLLock: Boolean;
FHWPTT: Boolean;
public
constructor Create(AForm: TObject; FW, SW, SV: Double; PLL, HWPTT: Boolean);
constructor Create(AForm: TObject; FW, SW, SV, SA: Double; PLL, HWPTT: Boolean);
procedure Execute;
end;
@@ -244,6 +245,7 @@ type
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
// из MeterTimerTick (10 Гц), чтобы цифры/полоски не дёргались.
FLastSupplyV: Double;
FLastSupplyA: Double;
FLastPLLLock: Boolean;
// ---- Spectrum / Waterfall view ----
@@ -460,7 +462,7 @@ type
// Public UI update (called from sync objects)
procedure DoAddDevice(const Dev: THPSDRDevice; const Entry: string);
procedure DoUpdateStatus(FwdW, SWRV, SupplyV: Double; PLLLock, HWPTT: Boolean);
procedure DoUpdateStatus(FwdW, SWRV, SupplyV, SupplyA: Double; PLLLock, HWPTT: Boolean);
procedure UpdateTXMeters;
procedure DoUpdateDDCSeq(DDCIdx: Integer; Seq: LongWord);
procedure DoUpdateDDCSeqOrNoDevice(DDCIdx: Integer; Seq: LongWord);
@@ -869,20 +871,21 @@ begin
end;
constructor TStatusUISync.Create(AForm: TObject;
FW, SW, SV: Double; PLL, HWPTT: Boolean);
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean);
begin
inherited Create;
FForm := AForm;
FFwdW := FW;
FSWRV := SW;
FSupplyV := SV;
FSupplyA := SA;
FPLLLock := PLL;
FHWPTT := HWPTT;
end;
procedure TStatusUISync.Execute;
begin
TMainForm(FForm).DoUpdateStatus(FFwdW, FSWRV, FSupplyV, FPLLLock, FHWPTT);
TMainForm(FForm).DoUpdateStatus(FFwdW, FSWRV, FSupplyV, FSupplyA, FPLLLock, FHWPTT);
end;
constructor TDDCSeqSync.Create(AForm: TObject; Idx: Integer; Seq: LongWord);
@@ -1298,6 +1301,7 @@ begin
FLastFwdW := 0;
FLastSWR := 1;
FLastSupplyV:= -1;
FLastSupplyA:= -1;
FLastPLLLock:= False;
FDeviceCount := 0;
FDeviceDialog := TDeviceDialog.Create(Self);
@@ -3088,7 +3092,7 @@ const
SWR_CAP = 9.9;
var
ExcPwr, FwdPwr, RevPwr: Word;
SupplyV, FwdW, SWRV, Rho: Double;
SupplyV, SupplyA, FwdW, SWRV, Rho: Double;
IsTx: Boolean;
Sync: TStatusUISync;
M: TThreadMethod;
@@ -3096,16 +3100,23 @@ 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;
// Board 5 (Orion MkII) measures supply voltage via UserADC0 (bytes 57-58),
// not the supply_volts field (bytes 49-50) — matching Thetis behaviour.
// Board 5 (Orion MkII): voltage on UserADC0 (bytes 57-58),
// current on UserADC1 (bytes 55-56) — matching Thetis behaviour.
if FNetwork.Device.BoardType = 5 then
begin
SupplyV := ADCToSupplyVolts(
(Status.UserADC0Hi shl 8) or Status.UserADC0Lo,
FNetwork.Device.BoardType)
else
FNetwork.Device.BoardType);
SupplyA := ADCToSupplyCurrent(
(Status.UserADC1Hi shl 8) or Status.UserADC1Lo,
FNetwork.Device.BoardType);
end else
begin
SupplyV := ADCToSupplyVolts(
(Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo,
FNetwork.Device.BoardType);
SupplyA := -1.0;
end;
// FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
// ExciterPwr это мощность TX, не уровень принятого сигнала.
FwdW := ADCToWatts100(FwdPwr);
@@ -3132,7 +3143,7 @@ begin
end else
SWRV := 1.0;
if not IsTx then FwdW := 0;
Sync := TStatusUISync.Create(Self, FwdW, SWRV, SupplyV,
Sync := TStatusUISync.Create(Self, FwdW, SWRV, SupplyV, SupplyA,
(Status.StatusBits and HPS_PLL_LOCKED) <> 0,
(Status.StatusBits and HPS_PTT) <> 0);
try
@@ -3143,7 +3154,7 @@ begin
end;
end;
procedure TMainForm.DoUpdateStatus(FwdW, SWRV, SupplyV: Double; PLLLock, HWPTT: Boolean);
procedure TMainForm.DoUpdateStatus(FwdW, SWRV, SupplyV, SupplyA: Double; PLLLock, HWPTT: Boolean);
const
// Thetis/piHPSDR PEP-style баллистика для FwdW и SWR: атака мгновенная
// (peak-hold), спад медленный — стрелка «висит» на пике и плавно опускается.
@@ -3177,6 +3188,13 @@ begin
else
FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FLastSupplyV;
end;
if SupplyA >= 0 then
begin
if FLastSupplyA < 0 then
FLastSupplyA := SupplyA
else
FLastSupplyA := ALPHA_SUPPLY * SupplyA + (1.0 - ALPHA_SUPPLY) * FLastSupplyA;
end;
FLastPLLLock := PLLLock;
// Hardware PTT (foot switch / mic PTT) — обнаружение фронта (нужно делать
@@ -3200,8 +3218,14 @@ var
begin
if FLastPLLLock then PLLStr := 'PLL OK' else PLLStr := 'PLL?';
if FLastSupplyV >= 0 then
StatusBar1.Panels[2].Text := Format('Supply: %.1fV | %s', [FLastSupplyV, PLLStr])
else
begin
if FLastSupplyA >= 0 then
StatusBar1.Panels[2].Text :=
Format('Supply: %.1fV / %.1fA | %s', [FLastSupplyV, FLastSupplyA, PLLStr])
else
StatusBar1.Panels[2].Text :=
Format('Supply: %.1fV | %s', [FLastSupplyV, PLLStr]);
end else
StatusBar1.Panels[2].Text := PLLStr;
end;