mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feature(settings): вкладка Calibration — детектор мощности/КСВ, V/A, S-метр
Паритет с Thetis-Enhanced (Det. Cal. / Volts&Amps правки): - TCalibration в TGlobalSettings (JSON cal_*): модель детектора Alex-моста, per-band множитель FWD/REV 0.5..2.0, множитель напряжения, Voff/Sens датчика тока, офсет S-метра. - AlexDetToWatts: константы Thetis computeAlexFwdPower/computeRefPower по моделям (ANAN-100 / 200D / 7000DLE-Anvelina Pro 3 / 8000DLE-Orion MkII, 6m-спецкейс REV). Дефолт = прежняя формула ANAN-100 (поведение не меняется). - OnHPStatus: FWD и REV через модельную формулу x множитель банда; КСВ = (1+p)/(1-p), p=sqrt(RevW/FwdW) (Thetis) вместо отношения сырых ADC; напряжение x SupplyVoltCal; ток с калибруемыми Voff/Sens. - WDSPEngine.SMeterCalDB: офсет в GetSMeterDBm/GetSliceSMeter (главный S-метр, slice-флаги, web). - Выбор модели в комбо подставляет модельные дефолты датчика тока (Anvelina Pro 3/7000DLE: 340 мВ / 88 мВ/А — Thetis GetDefaultVoltCalibration). - Фиксы: гард FLoading при постройке вкладки (SetItemIndex стреляет OnChange на программном присвоении -> AV на nil-контролах), FPageCalib/FNavCalib в списках SelectPage (вкладка была невидимой). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+41
-7
@@ -375,6 +375,10 @@ type
|
||||
FBandCache: array[0..CFG_BAND_COUNT-1] of TBandSettings;
|
||||
FPABandCal: array[0..CFG_BAND_COUNT-1] of Double;
|
||||
FVHFBandCal: array[0..CFG_XVTR_COUNT-1] of Double;
|
||||
// Калибровки (детектор мощности/КСВ, напряжение/ток, S-метр) — вкладка
|
||||
// Calibration. Читается сетевым потоком в OnHPStatus (double-поля, torn
|
||||
// read безопасен как у FPABandCal); менять через SetCalibration.
|
||||
FCal: TCalibration;
|
||||
FDevMAC: array[0..5] of Byte;
|
||||
// Глобальные настройки устройства, загруженные ConnectDevice. Хранятся для
|
||||
// UI-рендера полей, которых нет в контроллере (DisplayFPS/FreqMhzDigits/CAT).
|
||||
@@ -681,6 +685,7 @@ type
|
||||
function PlutoTxAttForDrive: Double; // дБ<0 под текущий FDrivePercent
|
||||
procedure ApplyPlutoTxAtten; // ставит att по FTransmitting/FTuning
|
||||
procedure SetPlutoTxMaxAtt(Db: Double); // потолок на drive=100% (внешний усилитель)
|
||||
procedure SetCalibration(const C: TCalibration); // вкладка Calibration → FCal + офсет S-метра в DSP
|
||||
procedure ApplyWDSPDrive(Pct: Integer); // цифровой drive WDSP: Pluto=1.0 (мощность — атт), HPSDR=Pct/100
|
||||
|
||||
// Диапазоны / трансвертеры / спан
|
||||
@@ -943,6 +948,7 @@ begin
|
||||
FFMStepOn := True;
|
||||
FRawFMDeviation := RAW_FM_DEV_DEFAULT;
|
||||
FLocalAudio := True; // GUI: звук на локальную карту; демон выключит явно
|
||||
TSettingsManager.DefaultCalibration(FCal);
|
||||
FLastSMeter := -130; FLastSWR := 1; FLastSupplyV := -1; FLastSupplyA := -1;
|
||||
FLastPlutoTempC := TELEMETRY_NONE; FLastPlutoSocTempC := TELEMETRY_NONE;
|
||||
FLastPlutoRSSIdB := TELEMETRY_NONE;
|
||||
@@ -965,6 +971,7 @@ begin
|
||||
FDSPEngine.OnSliceDemodAudio := OnSliceDemodAudioReady;
|
||||
FDSPEngine.OnDemodAudio := OnDemodAudioReady;
|
||||
FDSPEngine.SetDisplayResLimit(FDisplayPixels);
|
||||
FDSPEngine.SMeterCalDB := FCal.SMeterOffsetDB;
|
||||
|
||||
// QO-100 beacon lock: эталон частоты = декодер (см. ServiceBeaconLock).
|
||||
FBeaconRefHz := 10489750000.0; // центральный BPSK-маяк NB-транспондера (downlink)
|
||||
@@ -1186,10 +1193,12 @@ procedure TRadioController.OnHPStatus(const Status: THighPriorityStatus);
|
||||
const
|
||||
SWR_MIN_FWD_W = 1.0; // ниже — fwd это ADC-шум, SWR не считаем
|
||||
SWR_CAP = 9.9;
|
||||
BAND_6M = 10; // индекс 6m в HF-плане (160m..6m)
|
||||
var
|
||||
FwdPwr, RevPwr: Word;
|
||||
SupplyV, SupplyA, FwdW, SWRV, Rho: Double;
|
||||
IsTx: Boolean;
|
||||
SupplyV, SupplyA, FwdW, RevW, SWRV, Rho, DetK: Double;
|
||||
Bi: Integer;
|
||||
Is6m, IsTx: Boolean;
|
||||
begin
|
||||
FwdPwr := (Status.FwdPwrAlex0Hi shl 8) or Status.FwdPwrAlex0Lo;
|
||||
RevPwr := (Status.RevPwrAlex0Hi shl 8) or Status.RevPwrAlex0Lo;
|
||||
@@ -1208,19 +1217,31 @@ begin
|
||||
SupplyV := ADCToSupplyVolts(
|
||||
(Status.SupplyVoltsHi shl 8) or Status.SupplyVoltsLo,
|
||||
FNetwork.Device.BoardType);
|
||||
if SupplyV >= 0 then SupplyV := SupplyV * FCal.SupplyVoltCal;
|
||||
|
||||
if BoardSupportsSupplyCurrent(FNetwork.Device.BoardType) then
|
||||
SupplyA := ADCToSupplyCurrent(
|
||||
(Status.UserADC1Hi shl 8) or Status.UserADC1Lo,
|
||||
FNetwork.Device.BoardType);
|
||||
FNetwork.Device.BoardType,
|
||||
FCal.AmpVoffMV, FCal.AmpSensMVA);
|
||||
end;
|
||||
FwdW := ADCToWatts100(FwdPwr);
|
||||
// Детектор Alex-моста: константы по модели (вкладка Calibration) + per-band
|
||||
// множитель. Множитель общий для FWD/REV, поэтому КСВ от него не зависит
|
||||
// (как Thetis PABandCalMult).
|
||||
Bi := TxBandIdx;
|
||||
Is6m := Bi = BAND_6M;
|
||||
DetK := 1.0;
|
||||
if (Bi >= 0) and (Bi < CFG_BAND_COUNT) and (FCal.PADetCal[Bi] > 0) then
|
||||
DetK := FCal.PADetCal[Bi];
|
||||
FwdW := AlexDetToWatts(FwdPwr, FCal.PwrDetModel, False, Is6m) * DetK;
|
||||
RevW := AlexDetToWatts(RevPwr, FCal.PwrDetModel, True, Is6m) * DetK;
|
||||
// FTransmitting — программный флаг; HPS_PTT — вход HW-PTT (footswitch/mic).
|
||||
IsTx := FTransmitting or ((Status.StatusBits and HPS_PTT) <> 0);
|
||||
// SWR = (1+ρ)/(1-ρ), ρ = adc_r/adc_f; только при значимой fwd-мощности.
|
||||
if IsTx and (FwdW >= SWR_MIN_FWD_W) and (FwdPwr > 0) then
|
||||
// SWR = (1+ρ)/(1-ρ), ρ = sqrt(RevW/FwdW) (Thetis); только при значимой
|
||||
// fwd-мощности.
|
||||
if IsTx and (FwdW >= SWR_MIN_FWD_W) then
|
||||
begin
|
||||
Rho := RevPwr / FwdPwr;
|
||||
Rho := Sqrt(RevW / FwdW);
|
||||
if Rho >= 0.99 then
|
||||
SWRV := SWR_CAP
|
||||
else
|
||||
@@ -2794,6 +2815,7 @@ begin
|
||||
Result.PlutoTxMaxAttDb := FPlutoTxMaxAttDb;
|
||||
for i := 0 to CFG_BAND_COUNT - 1 do Result.PABandCal[i] := FPABandCal[i];
|
||||
for i := 0 to CFG_XVTR_COUNT - 1 do Result.VHFBandCal[i] := FVHFBandCal[i];
|
||||
Result.Cal := FCal;
|
||||
Result.ActiveVfo := FActiveVfo;
|
||||
Result.NRMode := FNRMode;
|
||||
Result.NBMode := FNBMode;
|
||||
@@ -3539,6 +3561,17 @@ begin
|
||||
SaveGlobalSettings; // персист потолка (per-device)
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetCalibration(const C: TCalibration);
|
||||
begin
|
||||
FCal := C;
|
||||
// Санитизация: битый конфиг не должен дать деление на ноль/абсурдные ватты.
|
||||
FCal.PwrDetModel := EnsureRange(FCal.PwrDetModel, 0, 3);
|
||||
if FCal.AmpSensMVA <= 0 then FCal.AmpSensMVA := 120.0;
|
||||
if Assigned(FDSPEngine) then
|
||||
FDSPEngine.SMeterCalDB := FCal.SMeterOffsetDB;
|
||||
SaveGlobalSettings; // персист (гейт по FDevConnected внутри)
|
||||
end;
|
||||
|
||||
procedure TRadioController.ApplyWDSPDrive(Pct: Integer);
|
||||
// На Pluto мощность задаётся ОДИН раз — железной аттенюацией (PlutoTxAttForDrive),
|
||||
// поэтому цифровой уровень WDSP держим на максимуме (1.0), а не режем по drive%.
|
||||
@@ -5018,6 +5051,7 @@ begin
|
||||
FPABandCal[i] := FLoadedGlobal.PABandCal[i];
|
||||
for i := 0 to CFG_XVTR_COUNT - 1 do
|
||||
FVHFBandCal[i] := FLoadedGlobal.VHFBandCal[i];
|
||||
SetCalibration(FLoadedGlobal.Cal);
|
||||
// drive% (0..100) — раньше грузился через TrkDrive.Position; теперь напрямую,
|
||||
// слайдер выставит rfDevice-рендер. Калиброванный байт считаем после FCurrentBand.
|
||||
FDrivePercent := EnsureRange(FLoadedGlobal.DriveLevel, 0, 100);
|
||||
|
||||
Reference in New Issue
Block a user