switch controller: shorten the gap-minimum window to adapt to dwell changes
Окно минимума было 4096 отсчётов, и это давало опасную асимметрию: при УМЕНЬШЕНИИ межстадийной паузы минимум падает мгновенно, а при УВЕЛИЧЕНИИ (подняли dwell_us или задержку PLL прибора) устаревшее маленькое значение живёт тысячи стадий. Порог оказывался ниже реальной межстадийной паузы, детектор границы срабатывал на каждой стадии и залипал ключ в положении A на пару развёрток. Окно сокращено до 16 отсчётов. Длинное окно не давало точности: пауза задаётся счётчиком в FPGA и детерминирована, а межстадийная — самая частая (три из четырёх при четырёх стадиях), так что минимум по десятку отсчётов уже равен ей. Зато теперь смена настроек подхватывается за считанные точки, и случайная короткая пауза от помехи вымывается так же быстро. IFBW на порог не влияет и влиять не может: он меняет длительность оцифровки (фронт-спад), а меряется пауза (спад-фронт). Плюс ключ переключается по спаду, когда оцифровка закончена, а детектор границы во время оцифровки неактивен — boundaryPending_ сбрасывается на фронте. Разобрано в README. Прошито и проверено: после сброса ядро в loop, Verified OK. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,29 @@
|
|||||||
умноженный на `kBoundaryFactorNum / kBoundaryFactorDen` (по умолчанию 1.5). Пока
|
умноженный на `kBoundaryFactorNum / kBoundaryFactorDen` (по умолчанию 1.5). Пока
|
||||||
минимум не набран, восстановление молчит — чередование корректно и без него.
|
минимум не набран, восстановление молчит — чередование корректно и без него.
|
||||||
|
|
||||||
|
### Надо ли перекалибровывать паузу под каждую настройку
|
||||||
|
|
||||||
|
Нет, порог подстраивается сам, и вот что на него влияет, а что нет.
|
||||||
|
|
||||||
|
**IFBW не влияет.** Он меняет длительность оцифровки, то есть интервал от фронта
|
||||||
|
до спада, а контроллер меряет паузу от спада до следующего фронта. Это разные
|
||||||
|
интервалы. Плюс переключение делается по спаду, когда оцифровка уже закончилась,
|
||||||
|
а детектор границы во время оцифровки вообще неактивен — так что сдвинуть ключ
|
||||||
|
посреди измерения он не может ни при каком IFBW.
|
||||||
|
|
||||||
|
**Число точек, полоса, мощность не влияют** — паузы от них не зависят.
|
||||||
|
|
||||||
|
**Влияют `dwell_us` и задержка PLL прибора**: они и есть время успокоения, то
|
||||||
|
есть сама пауза. Но подстройка на это и рассчитана — окно минимума короткое (16
|
||||||
|
отсчётов), поэтому новое значение подхватывается за считанные точки. Ручной
|
||||||
|
калибровки не требуется.
|
||||||
|
|
||||||
|
**Смена диапазона внутри развёртки безопасна.** На точках нижнего диапазона
|
||||||
|
прибор останавливает развёртку и работает с Si5351 по I2C — такие паузы намного
|
||||||
|
длиннее обычных. Логика от этого не ломается: остановка всегда происходит на
|
||||||
|
границе точки, перед стадией 0, а значит «длинная пауза → следующая стадия
|
||||||
|
нулевая → положение A» остаётся верным.
|
||||||
|
|
||||||
Множитель намеренно щедрый. Ложное срабатывание **посреди** точки испортит
|
Множитель намеренно щедрый. Ложное срабатывание **посреди** точки испортит
|
||||||
данные, а несрабатывание всего лишь отключит страховку. Если по отчёту видно,
|
данные, а несрабатывание всего лишь отключит страховку. Если по отчёту видно,
|
||||||
что границы не распознаются вообще (`point boundaries` близко к нулю при
|
что границы не распознаются вообще (`point boundaries` близко к нулю при
|
||||||
|
|||||||
@@ -63,9 +63,20 @@ constexpr bool kSwitchActiveLow = false;
|
|||||||
constexpr uint32_t kBoundaryFactorNum = 3;
|
constexpr uint32_t kBoundaryFactorNum = 3;
|
||||||
constexpr uint32_t kBoundaryFactorDen = 2;
|
constexpr uint32_t kBoundaryFactorDen = 2;
|
||||||
|
|
||||||
// Окно, по которому берётся минимальная пауза. Двух окон хватает, чтобы
|
// Окно, по которому берётся минимальная пауза. Оно намеренно КОРОТКОЕ.
|
||||||
// оценка пережила смену настроек развёртки за пару секунд.
|
//
|
||||||
constexpr uint32_t kGapWindowSamples = 4096;
|
// Межстадийная пауза — самая частая: при четырёх стадиях на точку это три паузы
|
||||||
|
// из четырёх, при двух — одна из двух. Значит минимум даже по десятку отсчётов
|
||||||
|
// уже равен ей, и длинное окно не даёт никакой точности (пауза задаётся
|
||||||
|
// счётчиком в FPGA, она детерминирована).
|
||||||
|
//
|
||||||
|
// Зато длинное окно вредит. Если пауза ВЫРОСЛА — подняли dwell_us или задержку
|
||||||
|
// PLL прибора — устаревший маленький минимум держит порог ниже реальной
|
||||||
|
// межстадийной паузы, и детектор границы начинает срабатывать на каждой стадии,
|
||||||
|
// залипая ключ в положении A. С таким окном это самоустраняется за считанные
|
||||||
|
// точки, а не за развёртку. По той же причине короткое окно быстро вымывает
|
||||||
|
// случайную короткую паузу от помехи.
|
||||||
|
constexpr uint32_t kGapWindowSamples = 16;
|
||||||
|
|
||||||
// Защита от шума: пауза короче этого не считается настоящей стадией.
|
// Защита от шума: пауза короче этого не считается настоящей стадией.
|
||||||
constexpr uint32_t kMinPlausibleGapMicroseconds = 2;
|
constexpr uint32_t kMinPlausibleGapMicroseconds = 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user