# Lab043 — фактический checkpoint Технический снимок состояния для продолжения работы без истории чата. Только факты и результаты измерений. Дата снимка: 27 августа 2026 года. Пометки источника: **[файл]** — подтверждено чтением raw/analysis/report; **[handoff]** — со слов оператора/handoff-промпта, в файлах не найдено; **[расчёт]** — вычислено из существующих artifacts при этом снимке. Сокращения при первом употреблении: TX (Transmitter) — передатчик; RX (Receiver) — приёмник; LNA (Low-Noise Amplifier) — малошумящий входной усилитель; VGA (Variable-Gain Amplifier) — усилитель с регулируемым коэффициентом; ADC (Analog-to-Digital Converter) — аналого-цифровой преобразователь; BPSK (Binary Phase Shift Keying) — двоичная фазовая манипуляция, два состояния фазы, один бит на символ; QPSK (Quadrature Phase Shift Keying) — четырёхпозиционная фазовая манипуляция, два бита на символ; SNR (Signal-to-Noise Ratio) — отношение сигнал/шум; BER (Bit Error Rate) — доля ошибочных битов; SER (Symbol Error Rate) — доля ошибочных символов, для BPSK совпадает с BER; CFO (Carrier Frequency Offset) — остаточное смещение несущей; TCXO — термокомпенсированный кварцевый генератор; CRC (Cyclic Redundancy Check) — циклический контроль избыточности. ## 1. Цель Lab043 Довести цифровой канал HackRF → HackRF при общей опоре до устойчивого приёма BPSK, затем последовательно перейти: BPSK → QPSK → бинарные данные → пакет → CRC → файл → сжатое изображение → редкие видеокадры. Не превращать диагностику BPSK в бесконечное исследование, но перейти дальше только после подтверждённого рабочего BPSK. ## 2. Оборудование Две платы HackRF One r9. Host tools 2024.02.1, libhackrf 2024.02.1 (API 0.9), прошивка обеих 2024.02.1 (API 1.08). Обе — клоны, hackrf_info сообщает, что железо не выглядит произведённым Great Scott Gadgets; это известно и само по себе не STOP. Инструменты: `C:\Users\user\Tools\HackRF\Library\bin\`. **Pluto+ в текущем тракте не используется.** **[файл: hackrf_info]** ## 3. Serial - MASTER / TX: `000000000000000097c063dc323b97d3` - SLAVE / RX: `000000000000000097c063dc2e5327d3` **[файл: hackrf_info]** ## 4. Внешняя опора JYEC TCXO 10.000000 MHz, 0.1 ppm, установлен на MASTER. **[handoff]** ## 5. Физическая схема опоры TCXO 10 MHz → MASTER → MASTER CLKOUT → SLAVE CLKIN → SLAVE. SLAVE CLKOUT должен оставаться OFF, clock loop не создавать. ## 6. Доказательство выбора внешней опоры через reg29 Si5351 register 29: до запуска трансивера 0x0e; после RX при внешней 10 MHz опоре 0x26. Это переключение PLLA с внутреннего 25 MHz кварца на внешний 10 MHz CLKIN. Цепь подтверждена: MASTER после RX reg29=0x26, MASTER CLKOUT ON, SLAVE до CLKOUT сигнала нет, после CLKOUT сигнал обнаружен, SLAVE после RX reg29=0x26. **Считать доказанным, заново не исследовать.** **[файл: оба report.txt подтверждают reg29=0x26 у MASTER и SLAVE]** ## 7. Тоновый опыт до правильной синхронизации Наблюдался значительный уход несущей. **[handoff]** ## 8. Старый CFO Примерно +1165.124 Hz до общей опоры. **[handoff; в файлах тонового опыта только сырые IQ, отчёт не сохранён]** ## 9. Результат после общей опоры Residual CFO примерно +0.041 Hz. Улучшение примерно в 28417 раз. Килогерцовый CFO устранён общей 10 MHz опорой. **К программной компенсации большого CFO как к причине отказа BPSK не возвращаться.** **[handoff; тоновый raw существует, файла анализа с этим числом нет]** ## 10. Параметры RF-тракта - RF center: 1080 MHz - Fs (частота дискретизации): 8 000 000 отсчётов/с - symbol rate: 20 000 символов/с - samples/symbol: 400 - digital carrier offset: +50 000 Hz - MASTER TX VGA: 10 dB - TX RF amp: OFF; antenna bias/power: OFF - SLAVE RX RF amp: OFF; bias: OFF; RX gain — по текущей точке лестницы **[файл: metadata.json, rx_stdout.txt]** ## 11. Параметры BPSK-формы 17664 символов = 17664 бита. Преамбула 1280 символов (источник pilot_prbs7, initial_state 0x7f). Payload 16384 бита (NumPy PCG64, seed 0x043). Rolloff 0.35, RRC span 10 символов, guard 16 символов с каждой стороны. bits SHA-256: `aeae114e831ac6b20a82d70fa5153072f574ef04ea2aec8d9f6d0103100107c2`. Программный roundtrip формы: корреляция преамбулы 0.99995, bit errors 0, BER 0. **[файл: source_waveform_metadata.json]** ## 12. SHA-256 эталонной TX-формы `fed634fb2a4fbf41ea5a1fce547447b8e3e6dbe8110b8429c507637c6d2d1baa` Проверено при этом снимке: SHA файла `tx_bpsk_cs8.iq` во внешнем каталоге лестницы совпал с эталоном. **До любого TX сверять SHA; при отличии STOP.** **[файл + расчёт]** ## 13. Результат первого BPSK при общей опоре Каталог `20260827_125733_common_clock_bpsk`, RX LNA 8 / VGA 16. **[файл: analysis.json]** - независимая преамбула: НЕ найдена (preamble_found=False) - symbol SNR: −28.31 dB - BER (forced diagnostic): 47.88 % - constellation separation/spread: 0.0767 - clipping: 0; peak ADC: I=2, Q=3 - классификация: C Примечание: handoff-промпт для этого опыта приводил SNR −26.20 dB, BER 47.70 %, separation 0.0978. Расхождение с файлом небольшое; при конфликте источником считается файл analysis.json. ## 14. Первая RX gain ladder Каталог `20260827_130958_common_clock_bpsk_gain_ladder`. TX постоянно VGA 10 dB, RF amp OFF. |h| — комплексный коэффициент канала rx ≈ h·tx, здесь абсолютный RMS полезного сигнала в кодах ADC (rms_centered_complex); шкала ADC HackRF: int8, −128…127. Δ|h| — изменение относительно предыдущей точки. **[файл: analysis.json по точкам; Δ|h| и dBFS — расчёт]** | LNA | VGA | peak, кодов | \|h\| (RMS), кодов | \|h\|, dBFS | Δ\|h\| | symbol SNR, dB | separation | BER | preamble | clipping | status | |---:|---:|---:|---:|---:|---:|---:|---:|---:|:--:|:--:|---| | 8 | 8 | 3 | 0.176 | −57.2 | — | −51.70 (diag) | 0.0053 (diag) | 49.98 % (diag) | NO | 0 | нет синхр. | | 16 | 8 | 3 | 0.264 | −53.7 | +3.5 dB | −20.81 (diag) | 0.1823 | 44.87 % (diag) | NO | 0 | нет синхр. | | 16 | 16 | 4 | 0.579 | −46.9 | +6.8 dB | −10.62 | 0.5892 | 33.84 % | YES | 0 | порог не достигнут | | 24 | 16 | 3 | 0.346 | −51.4 | −4.5 dB | −2.62 | 1.4795 | 14.70 % | YES | 0 | порог не достигнут | Классификация ladder: B. ## 15. Лучшая текущая точка LNA 24 / VGA 16: preamble YES; symbol SNR −2.62 dB; BER 14.70 %; separation 1.4795; clipping 0. Это лучший проверенный результат, но не рабочая рекомендация. **[файл]** ## 16. Почему QPSK не запущен Рабочий порог не достигнут: BER 14.70 % при цели ≤ 1 %; SNR −2.62 dB при цели ≥ 6 dB; separation 1.4795 при цели ≥ 2. QPSK, JPEG, пакеты, видео до подтверждённого BPSK не запускать. ## 17. Текущая гипотеза и открытый вопрос Формально задача — продолжить RX gain ladder выше 24/16 и одновременно проверять физический рост полезного |h|. Но данные уже показывают проблему: полезный сигнал занимает лишь единицы кодов ADC (peak ≤ 4 из 128, RMS ≤ 0.58), и рост номинального усиления на 24 dB (8/8 → 24/16) дал прирост |h| лишь около +6 dB, немонотонно, с падением на 4.5 dB при переходе 16/16 → 24/16. Это близко к STOP-условию: усиление не превращается в амплитуду на ADC. Прежде чем крутить усиление выше, проверить, растёт ли физически |h|, и почему полезный сигнал оцифровывается всего 2 битами из 8. **[расчёт из analysis.json]** ## 18. Рабочие критерии BPSK Все одновременно: independent preamble YES; BER ≤ 1 %; symbol SNR ≥ 6 dB; constellation separation ≥ 2; без clipping и перегруза ADC. Цель — не максимальный gain, а минимальная безопасная рабочая точка. ## 19. Пути к raw / report / analysis Внешний корень (в Git не хранить): `C:\Users\user\Documents\SDR_Rover_Lab043_raw\` - `20260827_common_clock_tone\` — тоновый опыт, только сырые IQ. - `20260827_125733_common_clock_bpsk\` — первый BPSK: `report.txt`, `analysis.json`, `rx_cs8.iq`. - `20260827_130958_common_clock_bpsk_gain_ladder\` — лестница: `report.txt`, `summary.json`, `source_waveform_metadata.json`, `tx_bpsk_cs8.iq`, подкаталоги `lnaXX_vgaXX\` (`rx_cs8.iq`, `background_cs8.iq`, `analysis.json`, `metadata.json`, `constellation.png`, `correlation.png`, `rx_stdout.txt`, `rx_stderr.txt`). ## 20. Следующий конкретный эксперимент Продолжить лестницу выше 24/16 (кандидаты 24/24, 32/24, 32/32, 40/32 после проверки допустимых ступеней libhackrf 2024.02.1), TX не менять, RF amp OFF, TX VGA 10 dB. Каждая точка — отдельный опыт: preflight общей опоры, RX до TX, один короткий BPSK TX, сохранить raw, измерить |h| и Δ|h| dB, проверить перегруз, и только затем решать о следующей точке. STOP немедленно при достижении рабочей точки, при clipping/перегрузе, или если рост gain не даёт роста |h|. **Критический разрыв передачи (обнаружен при этом снимке):** инструмент, которым выполнялись BPSK-опыты HackRF → HackRF (генерация формы, вызовы `hackrf_transfer` для TX/RX, анализ преамбулы/SNR/BER/созвездия), **в репозитории отсутствует** — ни отслеженного, ни неотслеженного `.py`. В репозитории есть только `experiments/lab043_hackrf_gain_ladder.py`, но это Pluto+ → HackRF и один непрерывный тон, не BPSK, потолок 24/24. Внешние artifacts (TX-форма, RX-захваты, analysis.json) существуют, но порождающий код — нет. Для воспроизводимого продолжения «той же формой и тем же анализом» этот инструмент нужно закоммитить в проект либо написать заново отдельной согласованной задачей. **[расчёт: полный поиск по репозиторию]** ## 21. Запреты - Не возвращаться без причины к Pluto+ в текущем тракте. - Не пересматривать доказанный common clock и reg29. - Не запускать QPSK, JPEG, пакеты и видео до BPSK PASS. - Raw-файлы IQ в Git не добавлять; хранить во внешнем каталоге. - Форму BPSK не менять; до TX сверять SHA-256, при отличии STOP. - Усиление вслепую не крутить: каждая точка — отдельный контролируемый опыт. ## 22. Common-clock recheck 28 августа 2026 года Повторная аппаратная проверка после восстановления кабеля MASTER CLKOUT → SLAVE CLKIN завершена с результатом PASS: MASTER после короткого RX имел reg29=0x26; SLAVE дословно вернул `CLKIN status: clock signal detected`; SLAVE после короткого RX имел reg29=0x26. После проверки CLKOUT обеих плат переведены в `Down`, процессов `hackrf_transfer` не осталось. RF TX не выполнялся. Обнаруженный false-positive parser исправлен fail-closed: полные строки `clock signal detected` и `no clock signal detected` распознаются раздельно; пустой или неожиданный вывод даёт UNKNOWN. Продолжение разрешает только DETECTED. ## 23. Offline reconciliation старой BPSK gain ladder Фактический анализатор первой лестницы восстановлен из журнала запуска Codex от 27 августа. Git, PowerShell history, временные `.py/.ps1` и каталог raw исходного кода не содержали. Старый код сначала находил oracle-start полной известной 17664-битной формой, а затем проверял близость глобального пика преамбулы. Поэтому историческая реализация содержала data leakage в одной из проверок, хотя сам preamble-only пик вычислялся отдельно. Причина расхождения нового runner: старый detector исключал вокруг главного пика ±0.05 с, то есть ±1000 символов, а первая версия runner сравнивала с PRBS7-повтором через 127 символов за пределами лишь ±4 символов. Дополнительно runner применял `10*log10` к отношению амплитуд корреляции вместо исторического `20*log10`. До этого этапа signed int8, I/Q, DC removal, перенос `exp(-j...)`, 50 кГц, 400 отсчётов/символ и timing совпадали. Исправленный официальный путь глобально ищет start и timing только по преамбуле. Полная форма не влияет на preamble PASS и хранится только как явно помеченная oracle diagnostic. Остаточный CFO оценивается non-data-aided по фазе квадрата BPSK-потока; квадрат устраняет неизвестные знаки payload. Полярность и начальная фаза снимаются по преамбуле. Regression четырёх неизменённых raw: | LNA | VGA | sync | \|h\| | Δ\|h\| | SNR, dB | separation | BER | |---:|---:|---|---:|---:|---:|---:|---:| | 8 | 8 | oracle diagnostic | 3.6166e-6 | — | -51.70 diag | 0.0053 diag | NOT COMPUTED; 49.98% diag | | 16 | 8 | oracle diagnostic | 1.8902e-4 | +34.36 dB | -20.81 diag | 0.1823 diag | NOT COMPUTED; 44.87% diag | | 16 | 16 | independent | 1.3641e-3 | +17.17 dB | -10.62 | 0.5892 | 33.78% | | 24 | 16 | independent | 2.1859e-3 | +4.10 dB | -2.62 | 1.4795 | 14.78% | Первые два `|h|` являются oracle diagnostic при почти случайном BER, поэтому их большие дельты нельзя считать точной физической калибровкой gain. Между двумя независимо синхронизированными точками 16/16 → 24/16 полезная BPSK- компонента выросла на 4.10 dB: RX gain физически помогал, но прирост оказался меньше номинальных 8 dB. Для 24/16 научно корректный результат: preamble YES только по преамбуле; detected sample 6263020, refined start 6263013, timing phase -1; correlation 29.43 dB над median и 12.41 dB над независимым вторым кандидатом; CFO -0.01224 Hz; carrier phase 122.17°; preamble errors 200/1280; официальный BER 14.78%; измерительный symbol SNR -2.62 dB; separation 1.4795. Старые 14.70% воспроизводятся только при full-frame-aided оценке carrier и остаются сравнительной, а не официальной величиной. Offline analyzer, deterministic waveform, direct invocation и fail-closed common-clock skeleton покрыты тестами. Реальный hardware RX/TX режим по-прежнему не реализован: `run_one_gain_point()` намеренно заканчивается `NotImplementedError`, RF TX calls=0. Следующую gain ladder не запускать до отдельной реализации и проверки аппаратного режима. ## 24. Hardware runner и остановка ladder 31 августа 2026 года `run_one_gain_point()` завершён как fail-closed аппаратная процедура: детерминированная форма и SHA-gate выполняются до обращения к HackRF; затем common-clock preflight, старт SLAVE RX до TX, ровно один разрешённый TX, штатное завершение RX, двойная проверка SHA-256 и размера raw, проверка overrun/underrun, независимый preamble-only анализ и безусловное выключение обоих CLKOUT. Последовательный режим создаёт каталог только для фактически начатой точки и после каждого анализа проверяет PASS/STOP. Mock-проверки воспроизвели preflight failure, SHA failure, RX startup failure, успешный единичный TX, TX failure без повтора, analysis failure без повтора, cleanup процесса и обоих CLKOUT, а также запрет второго TX. Перед аппаратной попыткой: `python tools/quick_gate.py` PASS; `python -m pytest tests/ -q`: 343 passed; `git diff --check` PASS. Предупреждение pytest относилось только к невозможности создать `.pytest_cache` и не затрагивало тесты. Разрешённая лестница 24/24 → 32/24 → 32/32 → 40/32 была запущена через репозиторный `experiments/lab043_hackrf_bpsk.py`, но common-clock preflight остановил её до первой точки: MASTER прошёл свою часть проверки, после включения MASTER CLKOUT SLAVE дословно вернул `CLKIN status: no clock signal detected`. Классификация запуска D, выполненных gain points 0, RF TX calls 0, RECOMMENDED RX GAIN отсутствует. Итоговый отчёт: `C:\Users\user\Documents\SDR_Rover_Lab043_raw\20260831_110014_common_clock_bpsk_gain_ladder_2\ladder_report.json`. После STOP обе платы явно получили команду CLKOUT OFF; процессов `hackrf_transfer`, `hackrf_clock` и `hackrf_debug` не осталось. Следующий шаг: физически проверить соединение MASTER CLKOUT → SLAVE CLKIN и отдельным common-clock preflight восстановить тройной PASS до нового разрешения RF. После физического восстановления соединения отдельная ручная проверка дала тройной PASS: MASTER reg29=0x26, точная строка SLAVE `CLKIN status: clock signal detected`, SLAVE reg29=0x26; оба коротких RX имели 0 overruns. Однако немедленно запущенный репозиторный runner повторил свой обязательный preflight и получил от SLAVE `CLKIN status: no clock signal detected`. Поэтому лестница снова остановлена до первой точки: gain points 0, RF TX calls 0, классификация D. Отчёт второй попытки: `C:\Users\user\Documents\SDR_Rover_Lab043_raw\20260831_111352_common_clock_bpsk_gain_ladder_2\ladder_report.json`. Противоречие PASS → NOT_DETECTED означает нестабильное соединение или детектирование общей опоры; повторять RF-запуск автоматически нельзя. После замены пользователем провода общей опоры выполнена ещё одна явно разрешённая попытка runner. Его обязательный preflight снова получил точную строку `CLKIN status: no clock signal detected`; gain points 0, RF TX calls 0, классификация D. Отчёт: `C:\Users\user\Documents\SDR_Rover_Lab043_raw\20260831_111801_common_clock_bpsk_gain_ladder_2\ladder_report.json`. Поскольку отдельная ручная последовательность ранее дала PASS, а runner проверяет CLKIN сразу после включения MASTER CLKOUT, следующая программная гипотеза — недостаточная выдержка перед чтением CLKIN. До её согласованной реализации и mock-проверки новые RF-попытки не выполнять. ## 25. Common-clock settle-time 31 августа 2026 года Timing/race hypothesis подтверждена измерением без RF TX. В исходном измерительном цикле запросы после MASTER CLKOUT ON дали NOT_DETECTED на 37.9 и 115.3 мс, затем DETECTED на 171.0 мс. MASTER и SLAVE после коротких RX имели reg29=0x26, cleanup обеих плат завершился без ошибок. В runner реализован fail-closed bounded polling на монотонных часах: `initial_settle_s=0.050`, `poll_interval_s=0.050`, `timeout_s=0.500`. UNKNOWN, ненулевой exit code и subprocess exception немедленно закрывают gate; постоянный NOT_DETECTED заканчивается TIMEOUT. Предел 500 мс выбран почти втрое больше первого измеренного времени 171 мс и более чем вдвое больше максимума подтверждающей серии 196.55 мс, но не допускает неограниченного ожидания. Пять полностью раздельных common-clock-only циклов дали 5/5 PASS: | cycle | time to DETECTED, ms | queries | MASTER reg29 | SLAVE CLKIN | SLAVE reg29 | |---:|---:|---:|---:|---|---:| | 1 | 132.27 | 2 | 0x26 | DETECTED | 0x26 | | 2 | 134.45 | 2 | 0x26 | DETECTED | 0x26 | | 3 | 130.76 | 2 | 0x26 | DETECTED | 0x26 | | 4 | 130.17 | 2 | 0x26 | DETECTED | 0x26 | | 5 | 196.55 | 3 | 0x26 | DETECTED | 0x26 | Во всех циклах первый запрос после initial settle ещё возвращал NOT_DETECTED. Поэтому одиночная мгновенная проверка была реальной гонкой, а не доказательством отсутствия общей опоры. Common-clock gate: STABLE. RF TX count 0; после серии оба CLKOUT выключены, процессов HackRF не осталось. Артефакты: `C:\Users\user\Documents\SDR_Rover_Lab043_raw\20260831_112534_common_clock_settle_test\settle_report.json` и `settle_report.txt`. Mock tests покрывают первый DETECTED, delayed DETECTED, TIMEOUT, UNKNOWN, subprocess exception, PASS на границе timeout, конечность polling и cleanup. После изменения: quick_gate PASS, pytest 350 passed, `git diff --check` PASS. BPSK gain ladder на этом этапе не запускалась. ## 26. Первая рабочая BPSK-точка 31 августа 2026 года После закрытия common-clock timing issue репозиторный runner выполнил первую разрешённую точку LNA 24 / VGA 24 и немедленно остановил ladder по BPSK PASS. Точки 32/24, 32/32 и 40/32 не запускались. Выполнен ровно один RF TX; waveform SHA-256 совпал с эталоном `fed634fb2a4fbf41ea5a1fce547447b8e3e6dbe8110b8429c507637c6d2d1baa`. Common-clock preflight перед TX: MASTER reg29=0x26; SLAVE DETECTED через 132.74 мс и два запроса; SLAVE reg29=0x26. Официальная синхронизация найдена глобально только по преамбуле: peak/median 38.02 dB, peak/second independent candidate 10.98 dB, detected start 6231460, refined start 6231458, timing +1 sample. Payload не использовался для start/timing/carrier phase/polarity. Результат LNA 24 / VGA 24: preamble YES, errors 9/1280; CFO +0.00475 Hz; carrier phase -132.45°; |h|=4.5363e-2; symbol SNR 7.94 dB; centers примерно (-0.9936-0.0056j) и (+0.9912+0.0089j); within-cluster RMS 0.3980; separation 4.9867; официальный BER=SER=0.4586% (81 ошибок из 17664 бит). Все рабочие критерии выполнены: BER≤1%, SNR≥6 dB, separation≥2, independent preamble, clipping 0 и отсутствие ADC overload. Raw: mean I/Q 0.948/1.837 кода; RMS после DC removal 0.791; p95 3.162; p99 3.606; p99.9 3.606; peak component 5; ADC headroom 122 кода; clipping 0/32000000. Файл имеет 64000000 байт, 32000000 complex samples, длительность 4.0 с. Две проверки SHA-256 совпали: `a8d857a7fdd895475d8c58b56d8f1778ffce96966709ce98d691e078b4a832c8`. RX overruns 0, TX underruns 0. Относительно старой точки 24/16 runner получил Δ|h|=+26.34 dB. Это намного больше номинального изменения VGA +8 dB; после замены кабеля и физических переподключений дельту нельзя интерпретировать как чистую калибровку RX gain. Она не отменяет достоверность текущего внутрикадрового результата и отсутствие перегруза, но для калибровки тракта требует отдельного опыта. Классификация A. RECOMMENDED RX GAIN: LNA 24 / VGA 24. Практически BER 0.4586% означает около 4.6 ошибочных битов на 1000 до коррекции ошибок. Артефакты: `C:\Users\user\Documents\SDR_Rover_Lab043_raw\20260831_114210_common_clock_bpsk_gain_ladder_2\`. После опыта MASTER и SLAVE CLKOUT явно выключены с exit code 0, процессов HackRF нет. Послеруновые проверки: quick_gate PASS, pytest 351 passed, `git diff --check` PASS. QPSK/JPEG/video не запускались. Следующий этап — переход к полезным данным, но только отдельной согласованной задачей.