Lab 1.1 — Управляемый DDS-тон Zynq с приемом на RTL-SDR¶
Назначение¶
Эта лабораторная работа замыкает первый управляемый RF-цикл курса:
Zynq + AD9361 DDS tone -> короткий RF-путь -> захват RTL-SDR -> WAV IQ -> офлайн-анализ спектра
В отличие от Lab 1.0, источник сигнала теперь известен заранее. Студент не просто наблюдает эфир, а проверяет, подтверждает ли внешний приемник именно тот сигнал, который должен формировать передатчик.
Зачем это нужно¶
Одиночный тон удобен как первый управляемый witness для:
- настройки несущей;
- проверки согласованности sample rate;
- дисциплины по уровням TX/RX;
- поиска клиппинга и перегрузки;
- воспроизводимой IQ-записи с метаданными.
Если этот шаг работает, то дальнейшие лабораторные по BPSK/QPSK уже опираются на проверенный RF-baseline.
Живой опорный прогон¶
В репозитории теперь есть реальный stock-shell прогон, снятый 2026-06-24, со следующими параметрами:
| Параметр | Значение |
|---|---|
| Несущая | 915 MHz |
| Tone offset | 200 kHz |
| Sample rate на Zynq | 3.84 MS/s |
| Sample rate RTL-SDR | 2.4 MS/s |
| TX attenuation | -40 dB |
| Tuner gain RTL-SDR | 20.0 dB |
| Масштаб тона | 0.25 |
Измеренный результат офлайн-анализатора WAV:
| Метрика | Значение |
|---|---|
| Измеренный пик | 202624.512 Hz |
| Ошибка частоты | +2624.512 Hz |
| Оценка SNR | 66.40 dB |
| Доля клиппинга | 0 |
| Quality gate | PASS |
Артефакты¶
- Capture report:
docs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_stock_dds_tone_ref_a.json - Metrics JSON:
docs/assets/lab11_24_dds_tone_rtl_monitor_live_20260624_stock_dds_tone_ref_a_metrics.json - Dataset manifest:
datasets/lab11_24_dds_tone_rtl_monitor/manifest_live_20260624_stock_dds_tone_ref_a.yaml - График спектра:

- Краткий time preview:

Воспроизведение¶
Захват:
python blocks/block_11_integrated_sdr_project/python/lab_11_24_capture_dds_tone_rtl_monitor_wav.py `
--mode stock `
--run-tag live_20260624_stock_dds_tone_ref_a `
--tone-offset-hz 200000 `
--tone-scale 0.25 `
--tx-attenuation-db -40 `
--rx-gain-db 10 `
--rtl-tuner-gain-db10 200 `
--no-reboot-after
Офлайн-анализ:
python blocks/block_09_recording_and_analysis_tools/python/lab_9_4_read_wav_iq_and_analyze.py `
--manifest datasets/lab11_24_dds_tone_rtl_monitor/manifest_live_20260624_stock_dds_tone_ref_a.yaml
Инженерная интерпретация¶
Этот прогон закрывает первый управляемый пример с внешним приемником для Block 1:
- тон виден на ожидаемом смещении;
- частотная ошибка невелика и объяснима рассогласованием LO/tuner;
- SNR достаточно высокий для хорошего учебного отчета;
- тот же WAV manifest потом можно напрямую переиспользовать в Block 9.
Runtime-расширение¶
Тот же helper сначала был запущен на настоящем runtime bridge_txrx_mux overlay:
- report:
docs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_runtime_dds_tone_ref_a.json - metrics:
docs/assets/lab11_24_dds_tone_rtl_monitor_live_20260624_runtime_dds_tone_ref_a_metrics.json
Этот runtime-прогон tone quality gate не прошел: ожидаемый тон на 200 kHz исчез, а главный внешний пик схлопнулся почти в DC.
После этого witness был повторен и на более минимальных runtime-payload'ах:
| Payload | Измеренный пик | Оценка SNR | Quality gate | Интерпретация |
|---|---|---|---|---|
stock-shell |
202624.5 Hz |
66.4 dB |
PASS |
Ожидаемый внешний тон 200 kHz хорошо виден |
vendor_only |
2600.1 Hz |
35.9 dB |
FAIL |
Доминирующий пик схлопывается к DC |
gpreg_only |
2636.7 Hz |
36.9 dB |
FAIL |
Тот же near-DC collapse |
bridge_rx_only |
2636.7 Hz |
36.9 dB |
FAIL |
Тот же near-DC collapse |
bridge_txrx_mux |
2636.7 Hz |
38.7 dB |
FAIL |
Тот же near-DC collapse |
Расширенные артефакты:
docs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_vendor_only_dds_tone_a.jsondocs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_gpreg_only_dds_tone_a.jsondocs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_bridge_rx_only_dds_tone_a.jsondocs/assets/lab1125_stock_vs_runtime_dds_tone_sweep_live_20260624_sync_arm_test_a.json
Это уже было сильнее исходного наблюдения только для bridge_txrx_mux. Даже минимальные editable non-stock shell-варианты теряли внешний DDS witness, а значит текущий Block 11 blocker сидел в самом runtime shell / hot-load RF path, а не в более поздней course BPSK bridge-логике.
После этого был проведен repair-эксперимент с явной post-reload переинициализацией DDS-core:
| Payload + repair | Измеренный пик | Оценка SNR | Quality gate | Интерпретация |
|---|---|---|---|---|
vendor_only + cf_axi_dds rebind + RATECNTRL=3 |
202624.5 Hz |
66.5 dB |
PASS |
Внешний тон 200 kHz полностью восстановлен |
bridge_txrx_mux + cf_axi_dds rebind + RATECNTRL=3 |
202624.5 Hz |
66.0 dB |
PASS |
Полный course overlay снова дает внешний TX witness |
Артефакты repair-ветки:
docs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_vendor_only_dds_tone_rebind_dds_a.jsondocs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_vendor_only_dds_tone_rebind_dds_rate3_a.jsondocs/assets/lab1124_dds_tone_rtl_monitor_live_20260624_bridge_txrx_mux_dds_tone_rebind_dds_rate3_a.json
Промежуточный прогон только с cf_axi_dds rebind уже возвращал сигнал, но примерно на 800 kHz вместо 200 kHz. Это локализовало еще один недостающий post-reload шаг: нужно было вернуть DAC rate-control register в штатное значение 3.
Из-за этого лабораторная теперь полезна далеко не только для Block 1. Она одновременно служит:
- первым управляемым external-receiver experiment курса;
- чистым Block 11 witness, который доказывает, что внешний TX-path failure после runtime reload в принципе исправим через post-reload AXI DDS re-initialization.