mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
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:
@@ -392,6 +392,10 @@ function PhaseWordToFreq(PhaseWord: LongWord): Double;
|
|||||||
// Returns -1.0 if the board has no supply voltage measurement.
|
// Returns -1.0 if the board has no supply voltage measurement.
|
||||||
function ADCToSupplyVolts(RawADC: Word; BoardType: Integer): Double;
|
function ADCToSupplyVolts(RawADC: Word; BoardType: Integer): Double;
|
||||||
|
|
||||||
|
// Convert raw ADC value to supply current in Amps (Board 5 / Orion MkII only)
|
||||||
|
// Uses UserADC1 (bytes 55-56). Returns -1 for unsupported boards.
|
||||||
|
function ADCToSupplyCurrent(RawADC: Word; BoardType: Integer): Double;
|
||||||
|
|
||||||
// Convert raw ADC value to RF power in Watts (ANAN-100)
|
// Convert raw ADC value to RF power in Watts (ANAN-100)
|
||||||
function ADCToWatts100(RawADC: Word): Double;
|
function ADCToWatts100(RawADC: Word): Double;
|
||||||
|
|
||||||
@@ -454,6 +458,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ADCToSupplyCurrent(RawADC: Word; BoardType: Integer): Double;
|
||||||
|
begin
|
||||||
|
// Board 5 (Orion MkII): UserADC1, Vref=5V → mV = adc/4095*5000.
|
||||||
|
// Current sensor: Voff=360mV, Sens=120mV/A (Thetis defaults, ACS712-style).
|
||||||
|
// Formula: amps = (mV - Voff) / Sens.
|
||||||
|
if BoardType = 5 then
|
||||||
|
begin
|
||||||
|
Result := ((RawADC / 4095.0) * 5000.0 - 360.0) / 120.0;
|
||||||
|
if Result < 0.0 then Result := 0.0;
|
||||||
|
end else
|
||||||
|
Result := -1.0;
|
||||||
|
end;
|
||||||
|
|
||||||
function ADCToWatts100(RawADC: Word): Double;
|
function ADCToWatts100(RawADC: Word): Double;
|
||||||
var
|
var
|
||||||
V: Double;
|
V: Double;
|
||||||
|
|||||||
+37
-13
@@ -148,10 +148,11 @@ type
|
|||||||
FFwdW: Double;
|
FFwdW: Double;
|
||||||
FSWRV: Double;
|
FSWRV: Double;
|
||||||
FSupplyV: Double;
|
FSupplyV: Double;
|
||||||
|
FSupplyA: Double;
|
||||||
FPLLLock: Boolean;
|
FPLLLock: Boolean;
|
||||||
FHWPTT: Boolean;
|
FHWPTT: Boolean;
|
||||||
public
|
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;
|
procedure Execute;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -244,6 +245,7 @@ type
|
|||||||
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
|
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
|
||||||
// из MeterTimerTick (10 Гц), чтобы цифры/полоски не дёргались.
|
// из MeterTimerTick (10 Гц), чтобы цифры/полоски не дёргались.
|
||||||
FLastSupplyV: Double;
|
FLastSupplyV: Double;
|
||||||
|
FLastSupplyA: Double;
|
||||||
FLastPLLLock: Boolean;
|
FLastPLLLock: Boolean;
|
||||||
|
|
||||||
// ---- Spectrum / Waterfall view ----
|
// ---- Spectrum / Waterfall view ----
|
||||||
@@ -460,7 +462,7 @@ type
|
|||||||
|
|
||||||
// Public UI update (called from sync objects)
|
// Public UI update (called from sync objects)
|
||||||
procedure DoAddDevice(const Dev: THPSDRDevice; const Entry: string);
|
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 UpdateTXMeters;
|
||||||
procedure DoUpdateDDCSeq(DDCIdx: Integer; Seq: LongWord);
|
procedure DoUpdateDDCSeq(DDCIdx: Integer; Seq: LongWord);
|
||||||
procedure DoUpdateDDCSeqOrNoDevice(DDCIdx: Integer; Seq: LongWord);
|
procedure DoUpdateDDCSeqOrNoDevice(DDCIdx: Integer; Seq: LongWord);
|
||||||
@@ -869,20 +871,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TStatusUISync.Create(AForm: TObject;
|
constructor TStatusUISync.Create(AForm: TObject;
|
||||||
FW, SW, SV: Double; PLL, HWPTT: Boolean);
|
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FForm := AForm;
|
FForm := AForm;
|
||||||
FFwdW := FW;
|
FFwdW := FW;
|
||||||
FSWRV := SW;
|
FSWRV := SW;
|
||||||
FSupplyV := SV;
|
FSupplyV := SV;
|
||||||
|
FSupplyA := SA;
|
||||||
FPLLLock := PLL;
|
FPLLLock := PLL;
|
||||||
FHWPTT := HWPTT;
|
FHWPTT := HWPTT;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TStatusUISync.Execute;
|
procedure TStatusUISync.Execute;
|
||||||
begin
|
begin
|
||||||
TMainForm(FForm).DoUpdateStatus(FFwdW, FSWRV, FSupplyV, FPLLLock, FHWPTT);
|
TMainForm(FForm).DoUpdateStatus(FFwdW, FSWRV, FSupplyV, FSupplyA, FPLLLock, FHWPTT);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TDDCSeqSync.Create(AForm: TObject; Idx: Integer; Seq: LongWord);
|
constructor TDDCSeqSync.Create(AForm: TObject; Idx: Integer; Seq: LongWord);
|
||||||
@@ -1298,6 +1301,7 @@ begin
|
|||||||
FLastFwdW := 0;
|
FLastFwdW := 0;
|
||||||
FLastSWR := 1;
|
FLastSWR := 1;
|
||||||
FLastSupplyV:= -1;
|
FLastSupplyV:= -1;
|
||||||
|
FLastSupplyA:= -1;
|
||||||
FLastPLLLock:= False;
|
FLastPLLLock:= False;
|
||||||
FDeviceCount := 0;
|
FDeviceCount := 0;
|
||||||
FDeviceDialog := TDeviceDialog.Create(Self);
|
FDeviceDialog := TDeviceDialog.Create(Self);
|
||||||
@@ -3088,7 +3092,7 @@ const
|
|||||||
SWR_CAP = 9.9;
|
SWR_CAP = 9.9;
|
||||||
var
|
var
|
||||||
ExcPwr, FwdPwr, RevPwr: Word;
|
ExcPwr, FwdPwr, RevPwr: Word;
|
||||||
SupplyV, FwdW, SWRV, Rho: Double;
|
SupplyV, SupplyA, FwdW, SWRV, Rho: Double;
|
||||||
IsTx: Boolean;
|
IsTx: Boolean;
|
||||||
Sync: TStatusUISync;
|
Sync: TStatusUISync;
|
||||||
M: TThreadMethod;
|
M: TThreadMethod;
|
||||||
@@ -3096,16 +3100,23 @@ begin
|
|||||||
ExcPwr := (Status.ExciterPwr0Hi shl 8) or Status.ExciterPwr0Lo;
|
ExcPwr := (Status.ExciterPwr0Hi shl 8) or Status.ExciterPwr0Lo;
|
||||||
FwdPwr := (Status.FwdPwrAlex0Hi shl 8) or Status.FwdPwrAlex0Lo;
|
FwdPwr := (Status.FwdPwrAlex0Hi shl 8) or Status.FwdPwrAlex0Lo;
|
||||||
RevPwr := (Status.RevPwrAlex0Hi shl 8) or Status.RevPwrAlex0Lo;
|
RevPwr := (Status.RevPwrAlex0Hi shl 8) or Status.RevPwrAlex0Lo;
|
||||||
// Board 5 (Orion MkII) measures supply voltage via UserADC0 (bytes 57-58),
|
// Board 5 (Orion MkII): voltage on UserADC0 (bytes 57-58),
|
||||||
// not the supply_volts field (bytes 49-50) — matching Thetis behaviour.
|
// current on UserADC1 (bytes 55-56) — matching Thetis behaviour.
|
||||||
if FNetwork.Device.BoardType = 5 then
|
if FNetwork.Device.BoardType = 5 then
|
||||||
|
begin
|
||||||
SupplyV := ADCToSupplyVolts(
|
SupplyV := ADCToSupplyVolts(
|
||||||
(Status.UserADC0Hi shl 8) or Status.UserADC0Lo,
|
(Status.UserADC0Hi shl 8) or Status.UserADC0Lo,
|
||||||
FNetwork.Device.BoardType)
|
FNetwork.Device.BoardType);
|
||||||
else
|
SupplyA := ADCToSupplyCurrent(
|
||||||
|
(Status.UserADC1Hi shl 8) or Status.UserADC1Lo,
|
||||||
|
FNetwork.Device.BoardType);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
SupplyV := ADCToSupplyVolts(
|
SupplyV := ADCToSupplyVolts(
|
||||||
(Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo,
|
(Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo,
|
||||||
FNetwork.Device.BoardType);
|
FNetwork.Device.BoardType);
|
||||||
|
SupplyA := -1.0;
|
||||||
|
end;
|
||||||
// FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
|
// FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
|
||||||
// ExciterPwr это мощность TX, не уровень принятого сигнала.
|
// ExciterPwr это мощность TX, не уровень принятого сигнала.
|
||||||
FwdW := ADCToWatts100(FwdPwr);
|
FwdW := ADCToWatts100(FwdPwr);
|
||||||
@@ -3132,7 +3143,7 @@ begin
|
|||||||
end else
|
end else
|
||||||
SWRV := 1.0;
|
SWRV := 1.0;
|
||||||
if not IsTx then FwdW := 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_PLL_LOCKED) <> 0,
|
||||||
(Status.StatusBits and HPS_PTT) <> 0);
|
(Status.StatusBits and HPS_PTT) <> 0);
|
||||||
try
|
try
|
||||||
@@ -3143,7 +3154,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.DoUpdateStatus(FwdW, SWRV, SupplyV: Double; PLLLock, HWPTT: Boolean);
|
procedure TMainForm.DoUpdateStatus(FwdW, SWRV, SupplyV, SupplyA: Double; PLLLock, HWPTT: Boolean);
|
||||||
const
|
const
|
||||||
// Thetis/piHPSDR PEP-style баллистика для FwdW и SWR: атака мгновенная
|
// Thetis/piHPSDR PEP-style баллистика для FwdW и SWR: атака мгновенная
|
||||||
// (peak-hold), спад медленный — стрелка «висит» на пике и плавно опускается.
|
// (peak-hold), спад медленный — стрелка «висит» на пике и плавно опускается.
|
||||||
@@ -3177,6 +3188,13 @@ begin
|
|||||||
else
|
else
|
||||||
FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FLastSupplyV;
|
FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FLastSupplyV;
|
||||||
end;
|
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;
|
FLastPLLLock := PLLLock;
|
||||||
|
|
||||||
// Hardware PTT (foot switch / mic PTT) — обнаружение фронта (нужно делать
|
// Hardware PTT (foot switch / mic PTT) — обнаружение фронта (нужно делать
|
||||||
@@ -3200,8 +3218,14 @@ var
|
|||||||
begin
|
begin
|
||||||
if FLastPLLLock then PLLStr := 'PLL OK' else PLLStr := 'PLL?';
|
if FLastPLLLock then PLLStr := 'PLL OK' else PLLStr := 'PLL?';
|
||||||
if FLastSupplyV >= 0 then
|
if FLastSupplyV >= 0 then
|
||||||
StatusBar1.Panels[2].Text := Format('Supply: %.1fV | %s', [FLastSupplyV, PLLStr])
|
begin
|
||||||
else
|
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;
|
StatusBar1.Panels[2].Text := PLLStr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user