mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feature(pluto): компенсация hardwaregain в уровнях + живое усиление в блоке RF AGC
На Pluto шкала dBm ничего не значила: усиление тракта 0..73 дБ входит в показания напрямую, а в режимах AGC железо крутит его само, и картинка «дышит» вместе с ним. - RadioBackend: виртуальный RxGainNowDb (TELEMETRY_NONE = регулируемого усиления нет, как у openHPSDR с его аттенюатором). - PlutoBackend: в MANUAL отдаёт FGainDb (точно, без опроса железа), в режимах AGC — hardwaregain из телеметрического потока (читается там же, где rssi, ~2 Гц, не блокируя UI). - RadioController: AttenCalDB -> FrontEndCalDB, общее понятие «регулируемое усиление входа»: openHPSDR +FAtten (аттенюатор режет), AD936x -hardwaregain (усиление поднимает). Постоянная часть тракта (LNB, кабель, конвертер) остаётся за таблицами калибровки на диапазон/трансвертер. - UI: в блоке RF AGC при режиме != MANUAL вместо надписи «AGC» — фактическое усиление («~38dB», тильда = измеренное), ползунок ездит сам. Видно, что цифра гуляет, а уровни на спектре стоят. Ограничения: FAST AGC крутит усиление быстрее опроса (2 Гц), для стабильной шкалы нужен MANUAL или SLOW; шумовая полка при смене усиления немного едет — это физика (input-referred NF), компенсацию проверять по сигналу. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+28
-10
@@ -391,6 +391,9 @@ type
|
||||
// RSSI приёмника дБ. Опрашиваются ServicePlutoTelemetry с UI-таймера;
|
||||
// TELEMETRY_NONE = нет данных.
|
||||
FLastPlutoTempC, FLastPlutoSocTempC, FLastPlutoRSSIdB: Double;
|
||||
// Фактическое усиление RX-тракта AD936x (дБ) — в режимах AGC его крутит
|
||||
// железо. Снимается тем же опросом; UI показывает его в блоке RF AGC.
|
||||
FLastPlutoGainDb: Double;
|
||||
FPlutoTeleTick: QWord; // GetTickCount64 последнего опроса (троттлинг)
|
||||
FPlutoTempBad: Integer; // подряд отброшенных выбросов температуры (анти-залипание)
|
||||
|
||||
@@ -635,8 +638,9 @@ type
|
||||
// Офсет спектра/водопада (дБ) для дисплея: PanId 0 = главный, 1..N — пан.
|
||||
// Колбэк движка (display-поток), см. TOnDispCalQuery.
|
||||
function DispCalFor(PanId: Integer): Double;
|
||||
// Поправка на шаговый аттенюатор ADC (дБ) — входит в оба офсета выше.
|
||||
function AttenCalDB: Double;
|
||||
// Поправка на регулируемое усиление входа (аттенюатор ADC у openHPSDR,
|
||||
// hardwaregain у AD936x) — входит в оба офсета выше.
|
||||
function FrontEndCalDB: Double;
|
||||
procedure SetSliceDevice(Id, DevIndex: Integer; const DevName: string);
|
||||
function SliceCount: Integer;
|
||||
function GetSlice(Id: Integer; out S: TCtrlSlice): Boolean;
|
||||
@@ -966,6 +970,7 @@ begin
|
||||
FLastSMeter := -130; FLastSWR := 1; FLastSupplyV := -1; FLastSupplyA := -1;
|
||||
FLastPlutoTempC := TELEMETRY_NONE; FLastPlutoSocTempC := TELEMETRY_NONE;
|
||||
FLastPlutoRSSIdB := TELEMETRY_NONE;
|
||||
FLastPlutoGainDb := TELEMETRY_NONE;
|
||||
FPlutoTeleTick := 0; FPlutoTempBad := 0;
|
||||
FillChar(FDevMAC, SizeOf(FDevMAC), 0);
|
||||
end;
|
||||
@@ -2097,16 +2102,25 @@ end;
|
||||
function TRadioController.SMeterCalFor(VisibleHz: Double): Double;
|
||||
begin
|
||||
Result := CalLookup(VisibleHz, FCal.SMeterBandDB, FCal.SMeterXvtrDB)
|
||||
+ AttenCalDB;
|
||||
+ FrontEndCalDB;
|
||||
end;
|
||||
|
||||
function TRadioController.AttenCalDB: Double;
|
||||
// Шаговый аттенюатор ADC режет вход — чтобы шкала dBm оставалась абсолютной,
|
||||
// его дБ возвращаются в показания (так же делают Thetis и piHPSDR). У AD936x
|
||||
// такого аттенюатора нет: там усиление тракта — hardwaregain.
|
||||
function TRadioController.FrontEndCalDB: Double;
|
||||
// Поправка на регулируемое усиление входного тракта — то, что меняется ручкой
|
||||
// или само и не должно двигать абсолютную шкалу dBm.
|
||||
// openHPSDR: шаговый аттенюатор ADC режет вход → его дБ возвращаем в
|
||||
// показания (так же делают Thetis и piHPSDR).
|
||||
// AD936x: hardwaregain поднимает уровень (а в режимах AGC железо крутит
|
||||
// его само) → вычитаем текущее значение.
|
||||
// Постоянная часть тракта (LNB, кабель, конвертер) остаётся за таблицами
|
||||
// калибровки на диапазон/трансвертер.
|
||||
var G: Double;
|
||||
begin
|
||||
if IsPluto then Result := 0.0
|
||||
else Result := FAtten;
|
||||
if not IsPluto then Exit(FAtten);
|
||||
Result := 0.0;
|
||||
if FNetwork = nil then Exit;
|
||||
G := FNetwork.RxGainNowDb;
|
||||
if G > TELEMETRY_NONE then Result := -G;
|
||||
end;
|
||||
|
||||
function TRadioController.DispCalFor(PanId: Integer): Double;
|
||||
@@ -2117,7 +2131,7 @@ begin
|
||||
if (PanId > 0) and (PanId < MAX_PANS) then Hz := FPanFreqHz[PanId]
|
||||
else Hz := FCenterFreq;
|
||||
if Hz <= 0 then Exit(0.0);
|
||||
Result := CalLookup(Hz, FCal.DispBandDB, FCal.DispXvtrDB) + AttenCalDB;
|
||||
Result := CalLookup(Hz, FCal.DispBandDB, FCal.DispXvtrDB) + FrontEndCalDB;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetSliceDevice(Id, DevIndex: Integer;
|
||||
@@ -5046,6 +5060,7 @@ begin
|
||||
FActiveDDC := 0;
|
||||
FLastPlutoTempC := TELEMETRY_NONE; FLastPlutoSocTempC := TELEMETRY_NONE;
|
||||
FLastPlutoRSSIdB := TELEMETRY_NONE;
|
||||
FLastPlutoGainDb := TELEMETRY_NONE;
|
||||
FPlutoTeleTick := 0; FPlutoTempBad := 0;
|
||||
Changed(rfRunning); // безусловный сброс run-кнопки/MOX.Enabled/sleep (как старый хвост STOP)
|
||||
end;
|
||||
@@ -5504,6 +5519,9 @@ begin
|
||||
|
||||
// RSSI быстро меняется с сигналом — без сглаживания; обновляем, только если валиден.
|
||||
if r > TELEMETRY_NONE then FLastPlutoRSSIdB := r;
|
||||
// Фактическое усиление тракта (в MANUAL = заданное, в AGC — снятое с железа).
|
||||
FLastPlutoGainDb := FNetwork.RxGainNowDb;
|
||||
Changed(rfRxGain); // UI: живая цифра усиления в блоке RF AGC
|
||||
|
||||
Changed(rfSupply); // поле телеметрии статус-бара (поле 3); web-адаптер тоже
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user