ESPradio
Web-SDR приёмник EradioSDR на Antminer S9

Web-SDR приёмник на базе платы управления Antminer S9 (Zynq-7010) с внешним АЦП AD9226 и генератором 61.44 МГц. Позволяет принимать весь КВ-диапазон 0–30 МГц через браузер, с 8 независимыми каналами приёма и 12+ декодерами цифровых видов связи. Проект является форком OpenZynqSDR, который в свою очередь основан на Web-888 и KiwiSDR.

Родословная проекта

KiwiSDR — John Seamons (ZL4VO/KF6VO) — оригинальный Web-SDR на BeagleBone + FPGA.
Web-888 — RaspSDR — порт на Zynq, более мощное железо.
OpenZynqSDR — iliasam — порт на плату Antminer S9, открытые исходники FPGA и Linux.
EradioSDR — espradio.ru — доработки: RF-аттенюатор релейный, антенный коммутатор, MAC-генератор, U-Boot-баннеры.

Ссылки на первоисточники:

github.com/iliasam/OpenZynqSDRApp — приложение.
github.com/iliasam/OpenZynqSDR_HW — железо + FPGA.
habr.com/ru/articles/898490 — статья iliasam.

Что получится в итоге

Возможности приёмника: водопад 0–30 МГц, метки вещательных диапазонов (MW, 49m, 41m, …, 11m), режимы AM, SAM, DRM, LSB, USB, CW, NBFM, IQ, декодеры FT8/FT4, WSPR, DRM, SSTV, CW, NAVTEX, FAX, FSK, ALE-2G, Loran-C, timecode, IBP scan, переключатель антенн ant_switch, кнопка RF (управление аттенюатором), S-метр с калибровкой, запись демодулированного сигнала в браузере. Реализован почти полный функционал как у WEB-888.

Для примера прием FT8:

Дисклеймер: pet-project. Автор не несёт ответственности за сожжённое железо:).

Теория

Этот раздел — для тех, кто впервые сталкивается с SDR и Zynq. Если вы уже понимаете, что такое DDC, децимация и зачем нужна FPGA — можете сразу перейти к разделу «Конструкция».

Что такое SDR

Классический радиоприёмник — это набор аналоговых узлов: входной фильтр, смеситель, гетеродин, усилитель промежуточной частоты, детектор, усилитель низкой частоты. Каждый диапазон и каждый вид модуляции требует своих катушек, конденсаторов и кварцев. Переключение между ними — механическое или релейное.

SDR (Software Defined Radio) — принципиально другой подход. Сигнал с антенны оцифровывается как можно раньше, а вся дальнейшая обработка — фильтрация, перенос частоты, демодуляция, декодирование — делается в цифре, программно. Один приёмник охватывает сразу весь КВ-диапазон, а разные виды модуляции — это просто разные алгоритмы, выполняемые на одном и том же потоке данных.

Преимущества SDR:

— один приёмник — все диапазоны. Не нужно переключать катушки, достаточно поменять цифровой фильтр.
— гибкость. Новый вид модуляции — это новая программа, а не новая плата.
— запись. IQ-поток можно записать и потом «покрутить» в SDR-программе.
— водопад. Одновременно видно всю полосу — все сигналы на диапазоне.
— декодеры. Цифровые виды (FT8, WSPR, DRM, SSTV) декодируются программно.

Аппаратная платформа: почему Zynq

Для настоящего SDR нужен быстрый цифровой тракт. Оцифрованный сигнал с полосой 30 МГц — это поток в 61.44 млн комплексных отсчётов в секунду. Обрабатывать его в реальном времени на обычном процессоре невозможно — не хватит ни скорости, ни предсказуемости.

Решений два:

1. Специализированный DSP-процессор. Быстро, но негибко. Каждый чип — под конкретную задачу.

2. FPGA. Field-Programmable Gate Array — «программируемая логика». Чип, который можно сконфигурировать под любую цифровую схему: фильтр, сумматор, умножитель, генератор. Работает параллельно, с жёстким предсказуемым таймингом, на частотах в сотни мегагерц. Идеален для потоковой обработки сигналов.

Zynq — это SoC (System-on-Chip) от Xilinx, в котором объединены ARM Cortex-A9 (обычный процессор, на котором работает Linux) и FPGA (программируемая логика). Обе части связаны между собой шинами AXI, имеют общий доступ к DDR3 и могут обмениваться данными через прерывания и регистры.

Такое сочетание — идеально для SDR:

— FPGA делает то, что должно быть быстрым и предсказуемым: принимает сэмплы с АЦП, переносит частоту, фильтрует, децимирует, накапливает буферы, генерирует прерывания.
— ARM делает то, что должно быть гибким: демодуляцию, декодирование, работу с пользователем, веб-сервер, отправку звука в браузер.

В нашем проекте используется Zynq-7010 (XC7Z010) — младший чип серии, но его ресурсов хватает на 8 каналов приёма + waterfall. Тот же чип стоит в Web-888.

Тракт сигнала

Общая схема от антенны до браузера выглядит так:

Антенна → ФНЧ → аттенюатор → AD9226 → FPGA (DDC, CIC, децимация) → DDR3 → ARM (websdr.bin) → браузер

Разберём каждый блок.

Антенна — принимает радиоволны и превращает их в электрический сигнал. Для КВ подходят: MiniWhip (активная штыревая), Magnetic Loop (магнитная рамка, малошумная), диполь, длинный провод. Каждая имеет свои плюсы и минусы — выбор зависит от условий приёма и места установки.

ФНЧ (фильтр низких частот) — отсекает сигналы выше 30 МГц, которые нам не нужны. Если их не отфильтровать, они «наложатся» на полезный сигнал из-за эффекта наложения спектров (aliasing) и испортят приём. Фильтр собран на катушках и конденсаторах (L1/C4, L2/C5, L3/C6 + C1/C2/C3 на схеме).

Аттенюатор — ослабляет сигнал, если он слишком сильный. AD9226 — 12-битный АЦП, его диапазон ограничен. Если подать слишком мощный сигнал, АЦП «захлебнётся» и весь водопад превратится в мусор. Аттенюатор на двух реле TQ2 даёт ослабление 0 / −10 / −20 / −30 дБ. Управляется через MIO-пины Zynq. Подробнее — в разделе «RF-аттенюатор».

AD9226 — 12-битный АЦП (аналого-цифровой преобразователь) с частотой до 65 MSPS. Превращает аналоговый сигнал в поток 12-битных чисел. Подключается к Zynq по параллельному интерфейсу: 12 линий данных + линия тактирования. Работает от внешнего генератора 61.44 МГц.

FPGA — самая интересная часть. Она выполняет несколько операций:

1. Приём сэмплов. Считывает 12-битные числа от AD9226 на частоте 61.44 МГц. Это ~737 Мбит/с входного потока — обычный процессор такое не потянет.

2. DDC (Digital Down-Converter). Цифровое понижение частоты. Мы хотим «вырезать» узкую полосу (например, 3 кГц SSB-сигнала) из широкого спектра 30 МГц. Для этого FPGA умножает входной поток на комплексную экспоненту вида e^(−j2πft) — это переносит нужную полосу в 0 Гц. Умножение делается на быстром умножителе, результат — комплексный сигнал I + jQ.

3. CIC-фильтр и децимация. После DDC сигнал всё ещё «широкий» — частота дискретизации 61.44 МГц. Чтобы снизить поток, применяется децимация — уменьшение частоты дискретизации в N раз. Перед децимацией сигнал фильтруется CIC-фильтром (Cascaded Integrator-Comb) — это специальный фильтр, который эффективно работает на высоких частотах и не требует умножителей. Результат — узкополосный сигнал с частотой дискретизации, скажем, 12 кГц.

4. Разделение на каналы. FPGA делает это одновременно для 8 независимых каналов — то есть 8 пользователей могут слушать 8 разных частот в одно и то же время. Каждый канал имеет свой DDC, свой CIC, свою децимацию. Плюс отдельный канал для waterfall (быстрый FFT по всей полосе).

5. Буферизация. Готовые потоки данных FPGA складывает в DDR3 (общая память с ARM). Когда буфер заполнен, FPGA поднимает прерывание для ARM.

DDR3 — оперативная память, разделяемая между FPGA и ARM. Сюда FPGA пишет готовые буферы, отсюда ARM их читает через драйвер sdrdma.

ARM — процессор Cortex-A9, на котором работает Linux. Занимается всем, что связано с логикой и пользователем:

— читает буферы из FPGA через драйвер sdrdma;
— демодулирует сигнал (AM, SSB, CW, FM, SAM, DRM, IQ);
— применяет DSP: AGC, шумоподавление, noise blanker, squelch;
— декодирует цифровые виды (FT8, WSPR, DRM, SSTV, CW, NAVTEX, FAX, FSK, ALE-2G, Loran-C, timecode, IBP scan);
— обслуживает WebSocket — отправляет звук и водопад в браузер пользователя;
— принимает команды от браузера (переключение режима, частоты, аттенюатора, антенн);
— ведёт логи, работает с конфигами, обслуживает веб-интерфейс.

Браузер — получает по WebSocket два потока: звук (сжатый ADPCM или PCM) и водопад (по одной строке на кадр). Рисует водопад на canvas, проигрывает звук через WebAudio API, отправляет команды обратно по тому же WebSocket.

Почему 61.44 МГц

Частота дискретизации АЦП определяет максимальную полосу, которую можно принимать. По теореме Котельникова, чтобы корректно оцифровать сигнал с полосой F, нужно дискретизировать его с частотой не менее 2F. То есть при частоте 61.44 МГц мы можем принимать сигналы до 30.72 МГц — это ровно весь КВ-диапазон.

Но есть более тонкий момент. Децимация — уменьшение частоты дискретизации — делается многократным делением на 2, 4, 8, 16 и так далее. Если частота 61.44 МГц делится на степень двойки без остатка, то каждая ступень децимации даёт «красивое» целое число:

61.44 МГц / 2    = 30.72 МГц
61.44 МГц / 4    = 15.36 МГц
61.44 МГц / 8    = 7.68 МГц
61.44 МГц / 16   = 3.84 МГц
61.44 МГц / 32   = 1.92 МГц
61.44 МГц / 64   = 960 кГц
61.44 МГц / 512  = 120 кГц
61.44 МГц / 5120 = 12 кГц

Если бы частота была, скажем, 60 МГц, то после деления на 512 получилось бы 117.1875 кГц — не целое. Это создавало бы «плавающие» частоты дискретизации, ошибки округления и проблемы с демодуляцией. Число 61.44 МГц выбрано специально, чтобы все коэффициенты децимации были точными.

Стандартный KiwiSDR работает на 66.666 МГц — тоже «красивое» число, но менее удобное для 30-мегагерцовой полосы. OpenZynqSDR и EradioSDR перешли на 61.44 МГц именно чтобы получить ровно 30 МГц обзора.

Внешний генератор. Обычно Zynq тактируется от встроенного кварца. Но для SDR это плохо — встроенный кварц имеет точность порядка 50–100 ppm, что на частотах 30 МГц даёт ошибку в 1.5–3 кГц. Поэтому в проекте используется внешний генератор 61.44 МГц с точностью 10–20 ppm. Он подключается к Zynq через пин CLK 61.440Mhz — на фото платы это красная стрелка с подписью «CLK 61.440MHz». Генератор можно заменить на TCXO с точностью 0.5–2 ppm, но это уже опционально.

Джиттер внешнего генератора

Точность частоты — это только половина истории. Вторая, не менее важная характеристика — джиттер (фазовый шум) тактового сигнала.

Джиттер — это кратковременные случайные отклонения фронта тактового сигнала от идеального положения во времени. Если точность (ppm) говорит о том, насколько генератор «уехал» за длительное время (минуты, часы), то джиттер — это дрожание каждого отдельного фронта, измеряемое в пикосекундах.

Почему это критично для SDR? АЦП оцифровывает сигнал в моменты, определяемые тактовым сигналом. Если фронт «дрожит» на Δt пикосекунд, то выборка берётся не в момент t, а в момент t+Δt. Для сигнала с частотой f это эквивалентно фазовой ошибке 2πf·Δt. Чем выше частота входного сигнала, тем сильнее сказывается джиттер.

Формула SNR, ограниченного джиттером:

SNR = −20·log10(2π · f_вх · t_jitter)

Пример: сигнал 30 МГц, джиттер 1 пс.

SNR = −20·log10(2π · 30e6 · 1e-12) ≈ 74.5 дБ

Уже 74 дБ — это меньше, чем даёт сам AD9226 (около 80 дБ SFDR). То есть джиттер генератора начинает ограничивать динамику приёмника.

При джиттере 10 пс (типичный дешёвый генератор):

SNR = −20·log10(2π · 30e6 · 10e-12) ≈ 54.5 дБ

Это уже заметно. На водопаде вы увидите «размазанные» пики — несущие станций становятся шире, а слабые сигналы рядом с сильными станциями «тонут» в шумах.

При джиттере 100 пс — SNR всего 34 дБ, приёмник становится бесполезен для серьёзной работы.

Для EradioSDR с AD9226 и 12 битами оптимальный джиттер — 1–3 пс. Всё, что хуже 10 пс, уже заметно ограничивает приём. Всё, что лучше 0.5 пс — избыточно, эфирный шум станет основным ограничителем раньше.

Требования к генератору

Минимальные требования к тактовому генератору для SDR-приёмника 0–30 МГц с 12-битным АЦП:

Джиттер (RMS)не хуже 1–3 псИначе SNR ограничивается генератором, а не АЦП
Точность10–20 ppmМожно скорректировать программно (clk_adj)
Фазовый шум @ 10 кГц−140 дБн/Гц или лучшеОпределяет джиттер в рабочей полосе
Стабильность при прогреве±5 ppmДешёвые генераторы уплывают на 20–50 ppm
Питание3.3 В, LDOИмпульсный БП добавит джиттер
Какие генераторы подходят

Все генераторы делятся на несколько классов:

SPXO (Simple Packaged Crystal Oscillator) — простой кварцевый генератор. Точность 20–100 ppm, джиттер 5–50 пс. Дёшево (100–300 ₽). Годится для «поиграть», но SNR ограничен джиттером.

TCXO (Temperature Compensated) — с термокомпенсацией. Точность 0.5–5 ppm, джиттер 1–10 пс. Стоит 500–2000 ₽. Хороший выбор для домашнего приёмника — точность почти GPS-дисциплинированная, джиттер приемлемый.

OCXO (Oven Controlled) — с термостатом. Точность 0.01–0.1 ppm, джиттер 0.3–2 пс. Стоит 3000–15000 ₽. Применяется в профессиональных SDR и в измерительных приборах. Для EradioSDR избыточен.

GPSDO (GPS-Disciplined) — OCXO, подстраиваемый по сигналу GPS. Точность 0.001 ppm, джиттер 0.1–1 пс. Стоит 10000+ ₽. Используется для TDoA (Time Difference of Arrival), где нужна синхронизация нескольких приёмников между собой. Для одиночного приёмника избыточен.

Для EradioSDR оптимальный выбор — TCXO 61.44 МГц с джиттером 1–3 пс. Стоит на Али около 500–800 ₽. Даёт SNR около 65–70 дБ — это уже выше уровня, на котором шум эфира становится основным ограничителем.

Практические замечания по генератору

Питание. Даже хороший генератор легко «испортить» плохим питанием. Импульсный БП даёт пульсации 50–200 кГц, которые модулируют частоту генератора и добавляют джиттер. Для TCXO и OCXO используйте LDO-стабилизатор (AMS1117, LT3045) с хорошей фильтрацией по питанию.

Разводка. Тактовый сигнал — самый чувствительный в плате. Дорожка от генератора к пину CLK_ADC должна быть короткой, экранированной, желательно с согласованием по импедансу (50 Ом). Если генератор далеко от Zynq — используйте коаксиальный кабель или витую пару.

Термостабилизация. TCXO и OCXO прогреваются до рабочей температуры за 1–5 минут после включения. В первые минуты точность может быть хуже паспортной. Если вы калибруете частоту — дайте приёмнику прогреться 15–20 минут.

Земля. У генератора должен быть отдельный полигон земли, подключённый к основной земле в одной точке. Это предотвращает «земляные петли», которые добавляют шум.

Как оценить джиттер на слух и по водопаду. Джиттер проявляется не как шум сам по себе, а как «расширение» спектральных линий. Посмотрите на водопаде на узкополосную несущую (например, точный сигнал частоты на 9996 кГц от RWM): если она выглядит как тонкая вертикальная линия — джиттер мал. Если линия «размазана» на несколько пикселей — джиттер большой. Второй признак — сильные станции «мешают» слабым, приёмник не может одновременно слушать мощный сигнал и слабый рядом с ним (плохая динамика).

Почему AD9226

AD9226 — это классический АЦП для SDR-самодельщиков. Он не самый быстрый (65 MSPS — средний показатель) и не самый точный (12 бит, ENOB порядка 11 бит), но у него есть несколько преимуществ:

—дёшево. Модуль с Али стоит 500–1200 ₽ — в разы дешевле специализированных SDR-АЦП.
—простой параллельный интерфейс. 12 линий данных + линия тактирования — легко подключается к FPGA без сложных протоколов вроде LVDS.
—питание 5 В. Не требует отдельных напряжений, легко запитать.
—широкий вход. Работает с сигналами от ±1 В, что просто согласуется с антенной при помощи ОУ или простого трансформатора.
—хорошая динамика. SFDR (Spurious-Free Dynamic Range) около 80 дБ — достаточно для качественного приёма КВ.

AD9226 подключается к «красным меткам» на плате Antminer S9. Эти контакты изначально использовались для чипов BM1387 — хэш-чипов майнера. Распиновка: 12 линий данных идут на LSB-BITS 12..1 Zynq (BANK 500 платы). На модуле AD9226 с Али по умолчанию резистор R35 запаян не туда — его нужно перепаять на позицию R34 (см. раздел «Конструкция»).

Что происходит в веб-интерфейсе

Когда пользователь открывает http://IP:8073, происходит следующее:

1. Браузер загружает HTML/JS/CSS из встроенных в websdr.bin ресурсов (не с диска — они вшиты в бинарник для скорости).

2. JavaScript устанавливает WebSocket-соединение с сервером.

3. Сервер отправляет начальные сообщения: MSG с параметрами (sample rate, frequency, режимы), MSG load_cfg с конфигом, MSG load_dxcfg с базой меток.

4. Пользователь настраивается на частоту. JavaScript отправляет SET mod=lsb low_cut=... high_cut=... freq=... — сервер принимает команду, обновляет NCO в FPGA (DDS-фаза), пересчитывает фильтры.

5. FPGA начинает выдавать узкополосный поток для этого пользователя. ARM демодулирует, пакует в пакеты SND и WF, отправляет по WebSocket.

6. Браузер принимает пакеты, проигрывает звук через WebAudio, рисует строку водопада на canvas. При 10 кадрах водопада в секунду получается плавная «прокрутка» спектра.

7. Кнопки UI (RF, mode, antenna, zoom) отправляют свои команды. Сервер применяет их и отвечает подтверждением.

Сводная таблица
Антенна          — принимает радиоволны
ФНЧ              — отсекает сигналы выше 30 МГц
Аттенюатор       — ослабляет сильный сигнал (0/−10/−20/−30 дБ)
AD9226           — оцифровывает аналоговый сигнал (12 бит, 61.44 MSPS)
FPGA (в Zynq)    — DDC, CIC-фильтр, децимация, 8 каналов, буферизация в DDR3
ARM (в Zynq)     — чтение буферов, демодуляция, DSP, декодеры, WebSocket
Linux на ARM     — процесс, файлы, сеть, драйвер sdrdma
websdr.bin       — основное приложение (демодуляция + сервер)
Браузер          — UI, водопад, звук, команды

Антенный коммутатор (до 6 антенн через MIO32–MIO39) и RF-аттенюатор (2 реле TQ2) — необязательные опции. Приёмник полноценно работает и без них. Подробнее — в соответствующих разделах.

Компоненты и инструменты

Antminer S9 Control Board — 500₽. Модуль AD9226 — 1500 ₽. Генератор 61.440 МГц — 200 ₽. 2 реле TQ2 (5 В) — 200 ₽. SD-карта 8 ГБ (Class 10) — 500 ₽. Блок питания 5 В, 3 А — 300 ₽. Антенна — MiniWhip / Magnetic Loop / диполь.

Итого: ~2500–3000 ₽.

Инструменты: паяльник с тонким жалом, мультиметр, USB-TTL (CP2102/CH340) для UART, картридер для SD-карты, осциллограф (желательно).

Конструкция

Общий вид платы Antminer S9 с точками подключения. Внимание! для подключения AD9226 использовать "красные метки".

Схема

Схема.

Модернизация модуля AD9226

Для того чтобы использовать модуль в нашем приемнике нужно его немного модернизировать. Модернизация заключается в следующем: удаляем резистор R8, R5 меняем на конденсатор 0.1мкф, R2 и R14 меняем на 820Ом.

Важно: на модулях AD9226 с Али резистор R35 запаян не туда. Его нужно перепаять на позицию R34. Это меняет режим выходных данных АЦП. Без перепайки данные придут в неверном формате.

AD9226 до переделки, заводской вариант.

После модернизации.

AD9226 подключается к «красным меткам» — 12 линий данных D0-11 Zynq. CLK_ADC отмеченные на плате antminer s9 не подключать никуда. Рядом расположены точки подключения питания платы antminer s9, отсюда берем питание для всего остального. Питание Antminer S9 Control Board — 5 В.

Нужно обратить внимание на длинну соединительных проводов, рекомендую подключать отрезками 15мм МГТФ. Фото приведено для примера.

Так подключается OSC 61.440Mhz к Zynq-7010 и AD9226. Подключение осуществляется коаксиальным кабелем. Обратите внимание: на фото обозначена точка подключения управления антенным коммутатором (см.ниже описание).

Мной использовался такой генератор. Запитывал от 3.3В.

Точки подключения управления аттенюатором. Важно: R34 и R35 нужно удалить.

Готовый вид. Экранирование рекомендуется, но не обязательно.

RF-аттенюатор и ФНЧ

Приёмник полностью работает и без аттенюатора — это дополнительная опция. Если у вас слабые сигналы или вы не работаете с мощными станциями рядом — можно вообще не собирать эту часть. Плата antminer s9 + AD9226 + генератор уже дают полноценный WebSDR.

Аттенюатор нужен, когда: мощные вещательные станции рядом с вами, любительские передатчики в вашем же доме, грозовые разряды и широкополосные помехи, AD9226 перегружается — водопад становится мусором.

Описание схемы

ФНЧ (L1/C4, L2/C5, L3/C6 + C1/C2/C3) отсекает ВЧ выше 30 МГц. Аттенюатор −10 дБ на реле K1.2 (TQ2-5V): резисторы R1 (75Ω), R3/R4 (91Ω). Аттенюатор −20 дБ на реле K2.2 (TQ2-5V): резисторы R2 (240Ω), R5/R6 (82Ω). Реле включаются по отдельности или вместе: 0 / −10 / −20 / −30 дБ.

Разъём J3: pin 3 — +5V (питание обмоток), pin 2 — −10dB (подкл. D, Q2) (управление K1.2), pin 1 — −20dB (подкл. D, Q3) (управление K2.2). Диоды D1, D2 1n4148 — защита от обратного выброса на обмотках реле.

Подключение к Zynq

Управление через транзисторы Q2 и Q3 (2N7002, MOSFET):

−10dBQ2MIO38
−20dBQ3MIO37

Перед подключением уберите резисторы R34 и R35 с платы.

Порядок подключения

Обмотки реле подключаются к стокам (D) транзисторов. При логической 1 на MIO — транзистор открывается, реле срабатывает, аттенюатор включается.

Соответствие команд
SET rf_attn=0MIO37=0, MIO38=00 дБ
SET rf_attn=-10MIO37=0, MIO38=1−10 дБ
SET rf_attn=-20MIO37=1, MIO38=0−20 дБ
SET rf_attn=-30MIO37=1, MIO38=1−30 дБ
Проверка

1. Откройте веб-интерфейс.
2. На панели нажмите RF — появятся кнопки выбора (0 dB, -10 dB, -20 dB, -30 dB).
3. Выберите −10 дБ → щелчок реле + падение уровня на водопаде.
4. −20 дБ → падает сильнее.
5. −30 дБ → оба реле, минимум.
6. 0 dB → оба отпущены, аттенюатор выключен.

Если реле не щёлкают — проверьте: питание +5 В на J3 (pin 3), сигнал с MIO37/MIO38 приходит на затворы Q2/Q3, обмотки реле целы (мультиметром), диоды D1, D2 не пробиты.

Права доступа. Admin → Config → Allow RF attenuator switching или в файле websdr.json параметр rf_attn_allow: 0 — все пользователи, 1 — только локальные, 2 — только локальные или с паролем (рекомендуется).

Антенный коммутатор

Плата Antminer S9 Control Board имеет 6 выходов ANT0…ANT5, изначально предназначенных для управления чипами майнера. В EradioSDR они используются для управления внешним антенным коммутатором — реле или высокочастотными ключами. Управление идёт через MIO-пины Zynq: ANT0 — MIO32, ANT1 — MIO33, ANT2 — MIO34, ANT3 — MIO35, ANT4 — MIO36, ANT5 — MIO39. Разъёмы на плате подписаны.

Схема подключения

Каждый MIO-пин управляет своим ключом через транзистор — так же, как это сделано для RF-аттенюатора. Обмотка реле питается от +5 В, второй конец идёт на сток транзистора (2N7002 или аналогичного). Затвор — через резистор на MIO-пин (Внимание! лог.1=3,3в). Параллельно обмотке — диод (1N4148) для защиты от обратного выброса.

ВЧ-контакты реле коммутируют центр антенного разъёма между «прямо на AD9226» и «на землю» (для grounding-режима) либо между несколькими антеннами, если реле переключающие.

Возможности расширения ant_switch

Расширение ant_switch (автор Kari Karvonen, OH1KK). В коде поддерживается два режима:

NO MIX (denymixing = 1) — при выборе антенны N все остальные отключаются. Работает как обычный переключатель «одна из N».

MIX (denymixing = 0) — при выборе антенны N она добавляется к уже включённым. Можно включить несколько антенн одновременно — например, для фазированных антенных решёток (два вертикала с переключаемой диаграммой).

Использование в UI

В веб-интерфейсе появится выпадающий список ant_switch с названиями антенн. Пользователь выбирает нужную — реле срабатывает, антенна подключается. Если включён thunderstorm, все антенны заземляются автоматически — полезно при грозе, чтобы не спалить АЦП.

В разделе Admin, веб-интерфейс Extensions - Antenna switch производится настройка комутатора.

Права доступа. Параметр denyswitching ограничивает переключение, как и у RF-аттенюатора: 0 — всем, 1 — только локальным, 2 — только локальным или с паролем.

Запись образа на SD-карту

Ничего собирать не нужно. В разделе Downloads — готовый образ .img (8 ГБ). Записали → вставили → включили → работает.

Внимание Для записи образа потребуется SD-карта объемом не менее 8ГБ.

Как произвести запись образа

Образ диска (файл img) упакован в архив, первым делом необходимо его распаковать.

Windows: Win32DiskImager

1. Скачайте Win32DiskImager (sourceforge.net/projects/win32diskimager).
2. Вставьте SD-карту через картридер.
3. В поле Image File выберите eradiosdr.img.
4. В поле Device — букву вашей SD-карты (не перепутайте с системным диском!).
5. Нажмите Write и подтвердите.

Linux: dd
lsblk
sudo dd if=eradiosdr.img of=/dev/sdX bs=4M status=progress conv=fsync
sync

lsblk определит устройство карты. dd пишет безвозвратно и без подтверждений. Трижды проверьте /dev/sdX.

Поиск приёмника в сети

По умолчанию включен DHCP клиент (ip адрес получает автоматически). В сети должен быть DHCP сервер на: роутере, модеме и тп.

Windows: утилита Advanced IP Scanner (advanced-ip-scanner.com/ru). Ищите устройство с MAC 02:00:00:...

Linux: sudo nmap -sn 192.168.1.0/24 или sudo arp-scan --localnet.

Роутер: раздел DHCP Clients — устройство WebSdr или MAC 02:00:00:...

Первое подключение: откройте браузер: http://<IP>:8073. Пароль администратора по умолчанию — 123456789. Сразу смените (Admin → Security).

Учётные записи по умолчанию

Linux: root — пароль 1234567890.
Linux: ubuntu — пароль temppwd.
Web: admin — пароль 123456789.

Пароли рекомендуется изменить сразу после первого запуска!

Пароль Linux (root и ubuntu):

sudo passwd root
passwd

Пароль веб-админа — через веб-интерфейс, раздел Admin → Security.

Калибровка частоты

Внешний генератор 61.44 МГц не идеален — его реальная частота может отличаться на 10–100 ppm. Без коррекции все частоты на водопаде уедут. Калибровка — обязательный шаг. В EradioSDR она делается прямо в веб-интерфейсе, без правки конфигов вручную.

Как калибровать

1. Найдите эталонную станцию на водопаде. Хорошо подходят сигналы точного времени: RWM (Москва) — 4996, 9996, 14996 кГц; WWV (США) — 5000, 10000, 15000 кГц; WWVH (Гавайи) — 5000, 10000, 15000 кГц; CHU (Канада) — 3330, 7850, 14670 кГц. Список вещательных станций — eibispace.de.
2. Настройтесь на сигнал в режиме AM или CW. Включите узкую полосу — так точнее.
3. Правый клик по водопаду → в контекстном меню выберите cal ADC clock (admin).
4. Появится диалоговое окно.
5. Нажмите Confirm — поправка применится автоматически. Она сохранится в websdr.json в поле clk_adj.
6. Проверьте — сигнал должен встать точно по центру.

Контекстное меню — вызов калибровки:

Диалог калибровки:

Параметры диалога:

-23 Hzна сколько герц нужно сдвинуть частоту приёма
10000 kHzчастота, на которой вы калибруетесь
-22.5 ppmпоправка в ppm (parts per million) для ADC clock

Как это работает. Вы настраиваетесь на точную частоту (например, 10 000 кГц для WWV). Если частота генератора уехала, сигнал окажется не на 10 000, а, скажем, на 10 000.023 кГц. Интерфейс это видит, вычисляет разницу в ppm и предлагает поправку. Знак тоже имеет значение: -22.5 ppm означает, что генератор «быстрее» номинала, и частоту приёма нужно уменьшить.

Важно: прогрейте приёмник 15–20 минут перед калибровкой — дешёвые генераторы уплывают при прогреве. Калибруйтесь по одной станции, но проверьте потом на 2–3 других частотах. Если поправка больше 100 ppm — генератор стоит заменить на TCXO. Готовый образ уже откалиброван (clk_adj: -1242), но под ваш экземпляр значение придётся подстроить.

Если калибровка не помогает: сигнал уплывает в течение дня — температурный дрейф, замените генератор на TCXO. Разные станции калибруются по-разному — калибруетесь по переотражённому сигналу или с доплеровским сдвигом, используйте станцию с устойчивым приёмом. Кнопка cal ADC clock не появляется — вы не админ, войдите в админку.

Структура файлов

Файлы на FAT-разделе SD-карты:

BOOT/
├── BOOT.BIN
├── boot.scr
├── design_1_wrapper.bit    ← прошивка FPGA
├── image.ub                ← ядро Linux
├── mac.txt                 ← MAC (создаётся автоматически)
├── uEnv.txt
└── sdr/
    ├── websdr.bin          ← приложение
    └── config/             ← конфиги и samples

design_1_wrapper.bit — прошивка FPGA. Загружается U-Boot при каждом старте.

image.ub — ядро Linux + device tree + rootfs.

mac.txt — MAC-адрес в формате U-Boot (ethaddr=02:00:00:xx:xx:xx). Создаётся автоматически при первом запуске. Можно задать свой вручную.

uEnv.txt — переменные U-Boot. Последовательность загрузки: MAC → FPGA → ядро → запуск.

websdr.bin — основное приложение.

config/ — конфигурационные файлы (описание в приложении B).

Как обновить design_1_wrapper.bit или websdr.bin

1. Выключите плату, достаньте SD-карту.
2. Вставьте в компьютер через картридер.
3. Замените нужный файл на FAT-разделе.
4. Корректно извлеките карту.
5. Вставьте обратно, включите питание.

Пересобирать ничего не нужно — U-Boot сам загрузит новый bitstream в FPGA, новый бинарник запустится.

Приложение A. Полезные команды по SSH
dmesg | tail -50логи ядра
tail -f /var/log/websdr.logлоги приложения
lsmod | grep sdrdmaзагружен ли драйвер
cat /sys/class/thermal/thermal_zone0/tempтемпература Zynq
free -mпамять
ip addr showсеть
sudo rebootперезагрузка
sudo shutdown -h nowвыключение
Приложение B. Описание конфигов

Все файлы лежат в /mnt/fat_disk/sdr/config/ на приёмнике (на SD-карте — sdr/config/). Правки через админку сохраняются сюда же; можно редактировать вручную и перезагружать приёмник. Формат — JSON. Комментарии не поддерживаются. Перед правкой сохраните резервную копию файла.

websdr.json — рабочие параметры приёмника

Основной конфиг. Здесь всё, что касается приёма, DSP, автозапусков, отображения и расширений.

index_html_params — информация для UI
HTML_HEADstringДополнительный HTML в <head>. Мета-теги, аналитика, кастомные стили.""
PAGE_TITLEstringЗаголовок вкладки браузера."EradioSDR"
RX_PHOTO_FILEstringПуть к фото приёмника. kiwi.config/photo.upload — загруженное через админку."kiwi.config/photo.upload"
RX_PHOTO_HEIGHTintВысота фото в пикселях.600
RX_PHOTO_TITLEstringЗаголовок над фото."EradioSDR"
RX_PHOTO_DESCstringОписание под фото.""
RX_PHOTO_LEFT_MARGINboolСдвиг фото влево для нестандартных пропорций.false
RX_TITLEstringЗаголовок над водопадом. Виден всем."EradioSDR"
RX_LOCstringЛокация (например, «Moscow, Russia»)."Location is not set"
RX_QRAstringQRA-локатор для радиолюбителей.""
RX_ASLstringВысота антенны над уровнем моря."30m"
RX_GMAPstringКоординаты для карты в формате lat,lon."-0.0,0.0"
Верхний уровень
rx_namestringИмя приёмника. Видно в /status и на карте KiwiSDR."0-30 MHz SDR"
rx_devicestringМодель."EradioSDR"
rx_locationstringЛокация (текст)."Not set"
rx_gridstringQRA-квадрат для каталога. Формат: JJ00."JJ00"
rx_aslintВысота над уровнем моря в метрах.0
rx_antennastringОписание антенны."Magnetic Loop"
rx_gpsstringGPS-координаты. В EradioSDR не используется."(0.0, 0.0)"
server_urlstringСвой домен. Пусто = не публиковать.""
admin_emailstringEmail администратора."your@email"
owner_infostringСвободный текст о владельце.""
status_msgstringHTML-сообщение в шапке UI.""
reason_disabledstringПричина отключения, если server_enabled = false.""
passbands — полосы пропускания по режимам
am-4900 / +4900AM вещание, широкая полоса.
amn-2500 / +2500Узкий AM.
sam-4900 / +4900Синхронный AM.
sal / sau / sas-4900 / 0, 0 / +4900SAM нижняя / верхняя / стерео.
qam-4900 / +4900QAM (для DRM в стерео).
drm-5000 / +5000Digital Radio Mondiale.
lsb-2700 / -300LSB SSB.
lsn-2400 / -300Узкий LSB.
usb+300 / +2700USB SSB.
usn+300 / +2400Узкий USB.
cw+300 / +700Телеграф широкий.
cwn+470 / +530Телеграф узкий.
nbfm-6000 / +6000Узкополосная ЧМ.
nnfm-3000 / +3000Очень узкая ЧМ.
iq-5000 / +5000IQ-поток.
init — что включено при старте
modestringНачальный режим: usb, lsb, am, cw, iq, drm и т.д."usb"
freqdoubleНачальная частота в кГц.10000
zoomintУровень зума. 0 — весь диапазон, 14 — максимум.0
min_dB / max_dBintНижняя и верхняя границы шкалы водопада.-110 / -10
ceil_dB / floor_dBintГраницы шкалы S-метра.5 / 0
colormapintНомер цветовой схемы водопада.0
apertureintАвтомасштаб водопада: 0 — выкл, 1 — вкл.1
cw_offsetintТон CW по умолчанию в Гц.500
rf_attnintНачальное значение аттенюатора: 0 / −10 / −20 / −30.0
ITU_regionintРегион ITU для меток вещания: 0 — все, 1/2/3 — конкретные.0
AM_BCB_chanintКанал AM-вещания по умолчанию.0
freq_offsetdoubleСмещение частоты (для трансвертера).0
Калибровка
S_meter_calintПоправка S-метра в дБ. Подбирается по эталону.40
waterfall_calintПоправка яркости водопада.0
clk_adjintПоправка ADC clock в Гц. Ставится через cal ADC clock в UI.0
DSP — обработка сигнала
nb_algointАлгоритм noise blanker: 0 — выкл, 1 — стандартный, 2 — wild.0
nb_wfintПрименять ли NB к водопаду.1
nb_gateintПорог срабатывания NB.130
nb_threshintПорог по амплитуде.50
nb_thresh2floatПорог для wild-алгоритма.0.95
nb_tapsintДлина фильтра NB.10
nb_sampsintКоличество отсчётов для детектора.7
nr_algointАлгоритм noise reduction: 0 — выкл, 1 — WDSP, 2 — ORIG, 3 — SPECTRAL.0
nr_deintВключить denoiser.1
nr_anintВключить autonotch.0
nr_wdsp*intПараметры WDSP: taps, delay, gain, leak.64/16/10/7
nr_orig*floatПараметры ORIG: delay, beta, decay.1/0.05/0.98
nr_spec*floatПараметры SPECTRAL: gain, alpha, SNR.0/0.95/30
Autorun WSPR
callsignstringВаш позывной. Отправляется в спотах.""
gridstringQRA-квадрат для спотов.""
enableboolВкл/выкл модуль.true
autorun0..NintИндекс диапазона: 0 — 160m, 1 — 80m, 2 — 40m, 3 — 30m, 4 — 20m, 5 — 17m, 6 — 15m, 7 — 12m, 8 — 10m, 9 — 6m. 0 — выкл.5
preempt0..Nint1 — можно выгнать при подключении живого пользователя.1
syslogboolПисать споты в syslog.true
spot_logboolПисать споты в отдельный лог-файл.true
GPS_update_gridboolОбновлять QRA-квадрат из GPS. Не используется.false
test_filestringТестовая запись из samples/."WSPR.test.au"
BFOstringТон BFO для приёма CW.""
Autorun FT8/FT4
callsign, grid, enable—То же, что у WSPR.—
autorun0..NintИндекс диапазона FT8/FT4. Включает 8m и 5m.2
preempt0..NintРазрешить выгон.1
SNR_adjintПоправка SNR в дБ. Откалибровано под AD9226.-22
dT_adjintПоправка времени в секундах.-1
syslog, spot_logboolЛоги.false
GPS_update_gridboolОбновлять квадрат из GPS.false
DRM
enableboolГлобальное включение DRM.true
nreg_chansintСколько каналов зарезервировать под DRM.7
test_file1stringТестовая запись из samples/."DRM.BBC.Journaline.au"
test_file2stringВторая тестовая запись."DRM.KTWR.slideshow.au"
RF-аттенюатор
rf_attnintНачальное значение: 0 / −10 / −20 / −30 дБ.0
rf_attn_allowintКто может менять: 0 — все, 1 — локальные, 2 — локальные или с паролем.0
Антенный коммутатор
ant_switch.denyswitchingint0 — все, 1 — локальные, 2 — локальные или с паролем.0
ant_switch.denymixingint1 — только одна антенна, 0 — можно несколько (MIX).1
ant_switch.denymultiuserint1 — запретить переключение при нескольких пользователях.0
ant_switch.thunderstormint1 — грозовой режим, все антенны заземляются.0
ant1desc..ant8descstringОписания антенн (URL-encoded). Видны в UI."Север-Юг"
ant1high_side..ant8high_sideboolИнвертировать спектр для этой антенны.false
ant1offset..ant8offsetintСмещение частоты для трансвертера.0
Прочие параметры
inactivity_timeout_minsintТайм-аут неактивности в минутах. 0 — выключено.0
ip_limit_minsintЛимит на 24 часа для одного IP. 0 — выключено.0
chan_no_pwdintСколько каналов доступно без пароля.0
no_wfboolОтключить waterfall-каналы (только звук).false
n_campintСколько «ждунов» может висеть на одном канале.4
webserver_cachingboolКэширование статики в браузере.true
overload_muteintПорог автоматического мьюта при перегрузке АЦП в дБм.-15
ident_lenintМаксимальная длина имени пользователя.16
show_geoboolПоказывать геолокацию пользователей.true
show_1HzboolПоказывать метки 1 Гц.true
dx_default_dbintБаза меток по умолчанию: 0 — stored, 1 — EiBi, 2 — community.1
spectral_inversionboolИнверсия спектра (если у вас зеркальный сигнал).false
contact_adminboolПоказывать ссылку «связаться с админом».false
S_meter_OV_countsintСколько отсчётов перегрузки АЦП до срабатывания индикатора.12
agc_thresh_smeterboolИспользовать AGC для S-метра.true
snr_meas_interval_hrsintКак часто мерить SNR: 0 — выкл, 1 — каждый час.1
snr_local_timeboolИспользовать локальное время для SNR.true
any_preempt_autorunboolРазрешить выгонять автозапуски.true
ext_api_nchansintСколько каналов доступно через EXT API.8
adc_pgaintPGA АЦП (усиление).0
adc_ditherintDither АЦП.0
led_brightnessintЯркость LED на плате.0
CAT_baudintСкорость CAT-интерфейса.1
Расширения
ale_2gobjectadmin_menu (список частот), enable.—
cw, cwsobjectCW-декодер и скимер. Поле enable.true
digi_modesobjectЦифровые виды. enable.true
faxobjectФакс. enable.true
fftobjectСпектр. enable.true
fskobjecttest_file, enable.true
iframeobjectsrc, url, html, title, width, height, help, enable.true
iq_displayobjectIQ-дисплей. enable.true
loran_cobjectgri0, gri1, enable.true
navtexobjecttest_file, enable.true
sstvobjectSSTV. enable.true
timecodeobjectДекодеры точного времени. enable.true
S_meterobjectrange_i, marker_i, maxdb, mindb, speed_i, averaging, timestamp, show_adc_ovfl, tstamp_tz, enable.—
admin.json — пароли, права, регистрация

Отдельный файл, потому что эти данные конфиденциальны и не показываются пользователям.

Пароли и аутентификация
cfgstringРежим хранения конфига. «pwd» — в файле."pwd"
user_passwordstringПароль пользователей. Пусто = открытый доступ.""
user_auto_loginboolАвтологин с локальной сети без пароля.true
admin_passwordstringПароль администратора. Смените!"123456789"
admin_auto_loginboolАвтологин админа с локалки. Удобно для отладки, но небезопасно.true
user_pwd_seqintСчётчик смены пароля пользователя.2
admin_pwd_seqintСчётчик смены пароля админа.6
Порт и публикация
portintПорт веб-интерфейса.8073
port_extintВнешний порт (для reverse proxy).8073
server_enabledboolВкл/выкл приёмник целиком.true
url_redirectstringКуда перенаправлять, если все каналы заняты.""
kiwisdr_com_registerboolПубликация в каталоге KiwiSDR.false
sdr_hu_registerboolПубликация в sdr.hu.false
sdr_hu_dom_selint0 — свой домен, 2 — публичный.0
api_keystringAPI-ключ для sdr.""
Сеть
ip_address.use_staticboolИспользовать статический IP. false — DHCP.false
ip_address.ipstringСтатический IP."192.168.10.95"
ip_address.netmaskstringМаска подсети."255.255.255.0"
ip_address.gatewaystringШлюз."192.168.10.1"
ip_address.dns1stringПервый DNS."1.1.1.1"
ip_address.dns2stringВторой DNS."8.8.8.8"
ip_address.commit_use_staticboolПрименить статику.false
auto_add_natboolАвтоматически открывать порт (UPnP).false
duc_enableboolDynamic DNS (DuckDNS и др.).false
duc_user, duc_pass, duc_hoststringПараметры DUC.""
duc_updateintИнтервал обновления в минутах.3
proxy_serverstringReverse proxy."proxy.rx-888.com"
use_sslboolHTTPS. Требует сертификат.false
Безопасность
ip_blackliststringСписок заблокированных подсетей через пробел. Поддерживает CIDR и одиночные IP с префиксом +.—
ip_blacklist_auto_downloadboolАвтоскачивание публичного списка ботов.false
ip_blacklist_localstringВаши ручные дополнения.""
ip_blacklist_mtimeintВремя последнего обновления (unix timestamp).0
no_dup_ipboolЗапретить несколько подключений с одного IP.false
onetime_password_checkboolПроверять пароль один раз за сессию.true
tlimit_exempt_pwdstringПароль, снимающий лимиты для друзей.""
console_localboolКонсоль только с локалки.true
admin_keepaliveboolАдминка держит соединение.true
log_local_ipboolПисать локальные подключения в лог.true
GPS, обновления, режимы
enable_gpsboolGPS отключён в EradioSDR.false
GPS_tstampboolИспользовать GPS-таймстамп. Без GPS не влияет.true
update_checkboolПроверка обновлений.false
update_installboolАвтоустановка обновлений.false
airbandboolРежим авиадиапазона 118–137 МГц.false
wf_shareboolРазрешить делить водопад между пользователями.true
narrowbandboolУзкополосный режим.true
rev_user, rev_hoststringРевизия. Оставить пустыми.""
optionsintСлужебные флаги.0

Как менять конфиги. Через веб-интерфейс — большинство параметров доступно в разделе Admin, изменения сохраняются автоматически. Вручную — откройте файл на FAT-разделе в текстовом редакторе, поправьте, сохраните, извлеките карту, вставьте в приёмник, включите. Если приёмник не запускается после правки — скорее всего в JSON опечатка, проверьте через валидатор. Перед правкой сохраните копию.

dx.json — метки на водопаде

Локальная база меток. Каждая метка — объект с полями: f (частота в кГц), m (режим), i (идентификатор), n (заметки), lo/hi (полоса), o (смещение), s (ширина сигнала), fl (флаги), b/e (время начала/конца, 2400 = конец суток), d0 (дни недели, битовая маска, 127 = все дни). Редактируется через Admin → DX.

dx_community.json — метки сообщества

Тот же формат, что dx.json, но приходит из публичной базы. Управляется полем dx_comm_auto_download в admin.json.

dx_config.json и dx_community_config.json

Служебные файлы с настройками отображения DX-списков (порядок сортировки, фильтры, избранное). Редактируются автоматически.

config.js

JavaScript-конфиг для клиентской части. Параметры UI, которые передаются в браузер при загрузке. Генерируется автоматически из websdr.json и admin.json при старте.

mac.txt — MAC-адрес

Формат: ethaddr=02:00:00:e4:74:cb.

Все платы Antminer S9 с завода идут без уникального MAC (или с одинаковым). Если у вас несколько плат в одной сети — они будут конфликтовать. При первом запуске mac.txt отсутствует — система генерирует случайный MAC в диапазоне 02:00:00:xx:xx:xx (локально-администрируемый) и сохраняет в этот файл. При последующих запусках используется сохранённый.

Можно задать свой MAC вручную: откройте mac.txt на FAT-разделе и впишите любое значение в формате ethaddr=02:00:00:xx:xx:xx. Локально-администрируемый диапазон (02:...) гарантированно не конфликтует с заводскими MAC.

photo.upload

Фото приёмника. Загружается через Admin → Config → RX Photo. По умолчанию — placeholder. Формат: JPEG, до 2 МБ.

v.sed

Скрипт для sed-обработки версий при обновлении. Служебный, вручную не трогать.

samples/ — тестовые записи

Аудиофайлы в формате .au (Sun Audio) для тестирования декодеров без эфира.

ALE.test.12k.au, ALE.test.8k.auALE-2G
ALE.zkd.AMD.12k.au, ALE.zkd.AMD.8k.auALE-2G (позывной ZKD)
CW.test.auCW-декодер
digi.test.auцифровые виды
DRM.BBC.Journaline.auDRM с текстом
DRM.KTWR.slideshow.auDRM со слайд-шоу
FT8.test.auFT8
SSTV.test.auSSTV
WSPR.test.auWSPR
HFDL_systable.confтаблица частот HFDL
HFDL_test_12k_cf13270_df13270.wavHFDL

Файлы используются для отладки декодеров и как эталоны при разработке.

Downloads:
eradiosdr_v1.rar — готовый образ SD-карты 8 ГБ.
Что нового:

Версия 1.0
— первая публичная версия;
— форк OpenZynqSDR с доработками: RF-аттенюатор на реле, MAC-генератор, U-Boot-баннеры;
— готовый образ SD-карты с преднастроенными конфигами;
— проверены декодеры: FT8/FT4, WSPR, DRM, SSTV, CW, NAVTEX, FAX, FSK, ALE-2G, Loran-C, timecode, IBP scan;
— аттенюатор 0 / −10 / −20 / −30 дБ через веб-интерфейс.

Бубнов Евгений espradio.ru e-mail: rv9c@yandex.ru