SDR-приемник своими руками

FM-радиоприемник на лампах

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

SDR-приемник своими руками

Один из самых популярных SDR сегодня — это китайский RTL-SDR. Он обладает огромными возможностями для своей небольшой цены.

Схема RTL2832 + RT820 выглядит вот так.

Сигнал поступает на вход радиотракта, реализованного на RT820, где выполняется первое преобразование частоты в промежуточную, здесь 3,57 МГц. Зеркальный канал при этом подавляется фильтрами, насколько это возможно.

Такое решение позволяет покрыть огромный диапазон частот от нескольких десятков мегагерц до пары гигагерц. Не весь сразу, конечно, а только кусочками по несколько мегагерц (судя по документации, RTL2832 способен оцифровать и сигнал частотой в несколько десятков мегагерц, однако упирается в пропускную способность USB). На самом деле зачастую достаточно и этого.

Полученный сигнал ПЧ оцифровывается в RTL2832, после чего подвергается второму программному преобразованию частоты. Здесь уже используется квадратурный гетеродин, реализованный программно как скалярное произведение входящего сигнала на опорный. А в случае квадратурного гетеродина в качестве опорных использованы два сигнала с одной и той же частотой, но сдвинутые по фазе на π/2. На выходе смесителей стоят фильтры низкой частоты, которые фильтруют сигнал с удвоенной опорной частотой. В результате на выходе тоже имеем два сигнала: синфазный (I) и квадратурный (Q). Впрочем, названия до некоторой степени условны.

Сигналы в виде потока данных передаются по USB. Собственно, перед отправкой и происходит ресемплирование, когда скорость передачи понижается до примерно 2 Мвыб/с, в данной схеме это «бутылочное горлышко». Почему именно квадратурный гетеродин? Из теории цифровой обработки сигналов известно, что, имея только сигналы I и Q, можно декодировать сигнал с любым из существующих способов модуляции. Например, АМ-модуляция, на которой мы ниже и сосредоточимся, реализуется наиболее просто.

Если представить, что I — это действительная часть, а Q — мнимая часть комплексного сигнала Z, то |Z| = (I^2 + Q^2)^1/2 и есть искомый демодулированный сигнал. C ЧМ и ФМ уже будет сложнее, но не принципиально. Впрочем, теория цифровой обработки сигналов слишком тяжела, чтобы пересказывать ее в двух словах, — при желании можешь почитать подробнее сам.

Дальше сигнал обрабатывает уже компьютер, где из отдельных семплов I и Q формируется комплексный семпл Z = I + jQ. Однако, как ты понимаешь, это тоже некоторая условность, позволяющая использовать математический аппарат комплексного исчисления к сигналу.

По существу, все это реализуется такими программными пакетами, как SDR# (Windows), Gqrx (Linux) или GNU radio (Linux). Последний нам наиболее интересен, так как позволяет не только пробежаться по диапазону, но и понять, как программная часть реализована внутри. И при этом вовсе не нужно залезать в дебри программирования, а можно при помощи мыши составить структурную схему (граф) из отдельных блоков. Блоки обычно реализуют одну операцию (в лучших традициях Unix). Вот так в GNU Radio выглядит простейший FM-приемник на RTL-SDR, созданный за пару минут.

Простейший пример

Простейший пример

RTL-SDR выступает в роли источника, выдающего поток комплексных Z-значений, что равносильно обоим потокам I и Q. Далее сигнал попадает в цифровой фильтр низких частот ФНЧ, который вырезает интересующую нас полосу. Так как в данном случае ожидается частотная модуляция, то нам потребуется полоса в ~200 кГц, с центром в нуле, которому соответствует выставленная на RTL-SDR частота. Далее сигнал попадает на частотный детектор, на выходе которого получается реальный звуковой сигнал, подходящий для звуковой карты. Ресемплер нужен, чтобы согласовать битрейт сигнала. Итого — половина приемника всего в несколько кликов мышки!

РЕКОМЕНДУЕМ:
Как собрать FM-радиоприемник на лампах

Простой SDR-применик

Раньше относительной популярностью пользовались SDR-приемники, которые использовали звуковую карту компьютера в качестве АЦП. Большинство имели схожую конструкцию и состояли из опорного генератора, фазовращателя, смесителя и усилителя низкой частоты. Выход усилителя подключался к линейному входу звуковой карты. Чувствуешь аналогию с рассмотренным выше RTL2832? Суть та же, только промежуточная частота тут ниже и оцифровывается уже квадратурный сигнал.

Рассмотрим схему популярного приемника ZetaSDR.

Схема ZetaSDR

Схема ZetaSDR

Сигнал с тактового генератора частотой F идет к фазовращателю, выполненному на двух D-триггерах, соединенных в счетчик Дженсона. Тот представляет собой сдвиговый регистр, последний инвертированный выход которого подан на вход. При подаче тактового сигнала по выходам сдвигового регистра будет распространяться попеременно волна нулей и единиц. В нашем случае на выходах Q0 и Q1 будут последовательно устанавливаться состояния 00, 01, 11, 10, что в десятичной системе соответствует 0, 1, 3, 2. С точки зрения сигналов это два меандра частотой F/4, сдвинутые по фазе на 90 градусов.

Диаграмма сигналов на счетчике Дженсона

Диаграмма сигналов на счетчике Дженсона

Далее полученные опорные сигналы поступают на ключевой смеситель Дэна Тейло (Dan Tayloe), выполненный на мультиплексоре 74HC4052. Смеситель умножает один сигнал на другой, поэтому если один из сигналов — меандр, то умножение сводится к простому переключению.

Принцип работы смесителя Тейло

Принцип работы смесителя Тейло

На приведенной ниже картинке показана диаграмма работы мультиплексора, где включенному каналу условно соответствует высокий уровень на нем.

Работа мультиплексора

Работа мультиплексора

Принимая канал X0 за 0°, видим, что 90° — это X1, 180° — X3, а 270° — X4. Соответствующим образом подключены и операционные усилители. В результате на выходе получаем сигналы I и Q, смещенные на 90°. Подробнее о смесителе Тейло можно прочитать в оригинальной статье. Далее сигналы отправляются на линейный вход аудиокарты.

Синтезатор

В ZetaSDR применен неперестраиваемый генератор, что дает полосу приема, равную полосе пропускания аудиокарты вокруг F/4. Думаю, ты согласишься, что это не очень много, так как любая аудиокарта редко имеет полосу пропускания больше 200 кГц. С другой стороны, ZetaSDR разрабатывался как приемник наблюдателя, и там полоса в 200 кГц перекрывает весь любительский диапазон на 40 м. Но мы-то хотим охватить несколько КВ-диапазонов! Кроме того, за последние десять лет стало гораздо проще с синтезаторами.

Поэтому воспользуемся микросхемой SI5351, которая представляет собой синтезатор частоты с цифровым интерфейсом, способный выхватывать несколько сигналов с частотой от 8 кГц до 160 мГц. При этом из обвязки требует лишь кварц и два подтягивающих резистора для I2C — все, как ты любишь. Для совсем уж ленивых людей в китайских онлайновых магазинах продавцы предлагают и вовсе собранные модули на этой микросхеме, что очень удобно для макетирования.

В качестве микроконтроллера я взял STM32F103C8T6, весьма популярный сегодня среди радиолюбителей благодаря плате Bluepill. Собираем макет на Bluepill и модуле SI5351, а в качестве интерфейсов используем I2C OLED-дисплей и энкодер. В итоге получается такая схема.

Для управления SI5351 я использовал библиотеку STM32-SI5351, которая представляет собой порт на С аналогичной библиотеки для Arduino на Wiring. Так как она использует код на HAL, а я уже сильно привык к функциям LibopenCM3, ее исходники пришлось чуть поправить. В основном изменения коснулись функций отправки и чтения данных. Кроме того, в заголовочном файле перед приватными переменными пришлось добавить модификатор static, иначе оно не хотело собираться.

В итоге адаптированные функции приняли следующий вид:

Из-за расхождений в обработке данных при передаче по I2C между HAL и LibopenCM3 функция si5351_write_bulk() получилась несколько сложной. Но, учитывая небольшой объем данных, передаваемых в SI5351, я решил, что спускаться на уровень ниже и писать свой аналог для ‘i2c_transfer7()’ ради всего этого не стоит. А вот с заголовочным файлом пришлось поковыряться дольше. Для запуска синтезатора необходимо инициализировать SI5351, включить соответствующий порт и задать частоту.

Частота задается в si5351_set_freq() в сотых долях герца, поэтому значение в килогерцах умножается на константу. Также крайне желательно указать тип константы — ULL (uint64). Микросхема может не только просто синтезировать произвольную частоту, но и генерировать несколько сигналов с заданным сдвигом фаз. Была реализована функция, генерирующая два опорных сигнала со сдвигом фаз в 90°.

Сначала я использовал именно эту функцию, и первый макет приемника не имел фазовращателя. Однако применение локального фазовращателя на 74AC74 дало лучший результат, поэтому от генерации двух сигналов я отказался (хотя этот вариант тоже оказался рабочим).

В качестве дисплея здесь применен OLED-экран на SSD1306, для него была написана библиотека, которая осуществляет форматный текстовый вывод и ограниченно поддерживает юникод. Настоящей засадой стал энкодер. С виду это очень удобная вещь для перестройки. Однако дешевый контактный энкодер стал быстро сбоить, и пользоваться им стало невозможно. А хотелось, чтобы ему сносу не было, как в Bruker AC200. И решение нашлось!

По сути, энкодер легко можно сделать из шагового двигателя, а у меня как раз завалялся один такой от принтера. Поэтому, вдохновившись одной публикацией и слегка адаптировав схему под имевшиеся у меня в наличии HEF4011 (К561ЛА7), я собрал вот такую конструкцию. Здесь собранные на инверторах триггеры Шмитта формируют цифровой выход.

Алгоритм дешифровки сигнала энкодера великолепно прост. По восходящему фронту одного из выходов энкодера случается прерывание, в котором определяется уровень на втором выходе. Если там ноль, то считаем, что энкодер вращается вперед, а если единица, то назад. Это отражено на графике.

Видим, что и здесь у нас квадратурные сигналы: в одном случае фаза отстает на 90°, а в другом опережает.

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

Любопытная особенность: прерывание срабатывает, лишь когда вывод сконфигурирован как float input, а когда его задаешь как input pullup/pulldown, оно не работает (хотя вроде как должно). Кнопками переключается шаг перестройки частоты и устанавливаются значения частот, соответствующих КВ-диапазонам. Исходники синтезатора, как всегда, доступны на GitHub.

Сборка SDR-приемника

Схема, которую я использовал, отличается от референсной лишь незначительно.

Сначала приемник и синтезатор были собраны на макетах, причем в первой версии не было фазовращателя, а оба опорных сигнала генерировались в SI5351.

Потом туда добавился фазовращатель (также на соплях), и, что самое интересное, все это работало! Вместо 74AC74 (K1554ТМ2) также можно взять 74HC74 (K555ТМ2), но тогда выше 10 МГц вряд ли удастся забраться, так как 74HC74 работает где-то до 40 МГц. А вот AC-серия уверенно держит до 120 МГц.

Убедившись в работоспособности конструкции, я перенес устройство на печатные платы, что несколько повысило качество сигнала, особенно после помещения плат в экран. Хотя разница была непринципиальная.

ВЧ-сигналы стоит передавать по коаксиальному кабелю и использовать при этом соответствующие разъемы, например SMA. На худой конец кабель можно и запаять. Провод, идущий к аудиокарте, тоже нужен экранированный. Необязательно высокочастотный, но непременно экранированный, иначе все утонет в помехах.

Печатные платы выполнены из двухстороннего фольгированного стеклотекстолита, на тыльной стороне сохранен слой меди и соединен с землей, перемычки сделаны из изолированного провода, а в месте входа в плату отверстия раззенкованы.

Сами платы помещены в жестяные корпуса, выполняющие роль экрана.

Энкодер синтезатора вместе с кнопками переключения диапазонов и изменения шага настройки выведен отдельно.

Вместо NE5532 можно взять LM358, но первая микросхема все же предпочтительнее, так как меньше шумит. И самый важный момент во всем деле — антенна. Хорошо бы, конечно, использовать достаточно длинную наружную антенну и желательно за городом, но за неимением лучшего сойдет и кусок провода, растянутый по комнате. Особенно если к нему подключить П-образный контур и подстраивать по максимуму сигнала.

Неплохих результатов можно добиться с магнитной антенной. Главное — при ее использовании будет куда лучше соотношение сигнал/шум, что особенно важно в городе.

Сама петля изготовлена из коаксиального кабеля и имеет диаметр 400 мм, транзистор J309 можно заменить на BF245 или КП303Е. Антенну и предусилитель также можно смонтировать на макетной плате.

Все это собрано буквально на коленке, из имевшихся дома запасов (чертов коронавирус!). Места занимает немного, но работает достаточно бодро, перекрывая диапазон от 5,8 МГц до 19 000 МГц. А если параллельно переменному конденсатору добавить емкость, то можно уйти и ниже.

Включение SDR-приемника

Для проверки работоспособности приемник сначала подключаем к осциллографу. На синтезаторе выставляем частоту 12 МГц (3 МГц после фазовращателя), а вместо антенны подключаем генератор сигнала (синусоида 3 МГц размахом 300 мкВ). Если синтезатор настроен правильно, то частота биений на выходе должна быть несколько герц. Собственно, по генератору я его и откалибровал, поправив частоту кварцевого резонатора в прошивке. Кстати, вместо правки частоты можно было в той же функции задать отклонение в ppm.

Также видим, что при переходе частоты биений через 0 скачкообразно изменяется сдвиг фаз между I и Q c 90° на –90°. Это значит, что все работает правильно. Теперь можно подключать к аудиокарте. Тут подойдет любая со стереофоническим линейным входом. Ширина полосы пропускания нас в данном случае волнует мало, так как мы всегда можем сдвинуть опорный сигнал.

Программы для работы с SDR-приемниками

Есть множество программ для работы с SDR-приемниками, однако сейчас все они ориентированы на работу с RTL-SDR и его более специализированными разновидностями, такими как HACK-RF, airspy и другими. Тем не менее из актуального софта SDR# поддерживает захват с аудиокарты. Это популярная программа, и мануалов по ней в Сети полно, хотя интерфейс и так интуитивен.

Поэтому устанавливаем, запускаем, выставляем желаемый диапазон на синтезаторе, подстраиваем антенну по максимуму сигнала, включаем АМ-демодулятор (большая часть всего интересного на КВ именно в АМ) — и вперед. Работает приемник очень устойчиво, с регенеративными аналогами (которые до сих пор иногда собирают) при схожей сложности тут по качеству просто нет никакого сравнения. Конечно, здесь видны и зеркальный канал, и отражения, особенно отчетливые на мощных станциях, но это расплата за простоту радиотракта. Побороть отражения можно, использовав ФНЧ на выходе операционного усилителя. А зеркальность реально подавить, отбалансировав каналы хотя бы по амплитуде.

Также для Windows есть совсем минималистичная и несколько устаревшая программа SDRadio, которая поддерживает и наш приемник. Впрочем, упомянуть ее стоило скорее ради ретроспективы.

Хорошо, а что в Linux? Тут чуть сложнее: gqrx ориентирована только на работу с чипами RTL и не поддерживает захват с аудиокарты. Так что воспользуемся GNU Radio!

Запускаем gnuradio-companion и строим несложный граф. В качестве источника используем audio source, в свойствах которого выставляем количество выходов ( 2) и sample rate=48000. Такие настройки любая аудиокарта потянет. Когда количество выходов audio source указано как два, автоматически используются левый и правый каналы захвата.

При необходимости можно выбрать одну из нескольких аудиокарт. Дальше ставим блок float to complex, который из двух реальных значений создает одно комплексное, к его входам подключаем наш источник. Также полезно между audio source и float to complex поставить умножение на константу, что позволит отбалансировать каналы по амплитуде. Теперь ставим фильтр низких частот, в котором указываем частоту среза 5 кГц. Фильтр выделит необходимую нам полосу сигнала 5 кГц вокруг нуля.

Очень полезная функция GNU Radio — возможность использовать переменные, значения которых задаются отдельно, или и вовсе изменять интерактивно с помощью элементов интерфейса. К выходу фильтра подключаем АМ-демодулятор, который находит модуль комплексного сигнала, и Audio Sink. А так как в данном случае sample rate источника и приемника равны, то согласовывать их ресемплингом нам не нужно. Простейший AM-приемник готов!

Он принимает станцию на частоте гетеродина, то есть в центре полосы, попадающей на аудиокарту. Хорошо, а как посмотреть спектр сигнала? Для этого добавляем элемент QT GUI: Frequency Sink, который отрисует нам спектр сигнала. Подключать его стоит к выходу блока float to complex. Похожим образом элемент QT GUI: Waterfall Sink отвечает за «водопад».

Как будто все хорошо в нашем приемнике. Вот только нет программной перестройки частоты в окне, а это крайне полезная штука, учитывая, что аудиокарты часто дают артефакты в разных частях окна. Моя вот, например, в нуле (+/–100 Гц): судя по всему, это наводки от электросети мешают приему сигнала.

Сделать программную перестройку достаточно просто, надо добавить еще один блок умножения между float to complex и Low Pass Filter, но в данном случае не на константу, а на функцию, то есть на второй сигнал. В качестве источника второго сигнала возьмем блок Signal Source, форма сигнала — косинус. Его частота должна быть равна той частоте, на которую необходимо сдвинуть сигнал.

Таким образом, мы добавили в приемник еще один преобразователь частоты, на этот раз уже программный. Теперь, перестраивая частоту Signal Source, мы можем выбирать, какую часть окна отправить на детектор. Иными словами, мы просто сдвигаем ноль в нашем окне. Полученный граф приемника выглядит как на схеме.

Если хочется послушать радиолюбителей — никаких проблем, только вместо модуля сигнала нам теперь нужна его действительная часть (или мнимая, или их сумма, тут непринципиально). Был приемник АМ, а стал прямого преобразования! Тут, конечно, стоит поправить полосу пропускания фильтра, так как мы уже на SSB. Лучше выставить где-нибудь 1500 Гц.

На 40 м хорошо слышны радиолюбители. А вот так выглядит уверенный прием в режиме АМ «Международного радио Китая», которое здорово слышно во всех вещательных КВ-диапазонах.

Бонус

Хорошо, но что делать, если в ноутбуке нет аудиокарты, а поползать по КВ-диапазону очень хочется? Можно, конечно, купить внешнюю аудиокарту или конвертер к RTL-SDR, но повышающий конвертер стоит в разы дороже самого RTL-свистка. Также в Китае продают модифицированные RTL-SDR v3, которые поддерживают direct conversion: цена приемлема, но все равно заметно выше, чем у RTL-SDR. Да и зачем покупать, когда девайс можно хакнуть.

Описанные манипуляции могут испортить твой RTL-SDR, а при неблагоприятном стечении обстоятельств выжечь порт USB и даже спалить материнскую плату. Поэтому повторяй эти действия на свой страх и риск и лишь в том случае, если точно знаешь, что делаешь. Я предупредил!

Как ты знаешь, RTL2832U имеет на входе АЦП. Более того, если прочитать импровизированный даташит, написанный энтузиастами, можно увидеть, что этих АЦП два и у обоих дифференциальный вход. При этом чип может оцифровать сигнал вплоть до 30 МГц. По сути, все, что надо, — это подать сигнал на вход, можно даже на один. В простейшем случае так и делают: выпаивают чип преобразователя частоты и припаивают антенну. Причем иногда чип даже оставляют на месте, просто перерезая соответствующие дорожки.

Но мы используем более элегантное решение. Если ты, выбирая свисток, следовал рекомендациям, то наверняка в качестве преобразователя там используется чип RT820 — и действительно, в нашем случае он более удобен. Дело в том, что RT820 использует только один вход I микросхемы RTL2832U (это выводы 1 и 2), а вход Q (выводы 4 и 5) остается незадействованным.

Вот именно к ним мы и подключимся. Более того, дополнительно можно воспользоваться трансформатором, что позволит задействовать дифференциальность входа, защитит от статики и несколько согласует сопротивления. Впрочем, с последним мы заморачиваться не будем. А вот защита от статики гораздо важнее, иначе в один неожиданный и не самый приятный момент девайс может превратиться в кирпич. Трансформатор мотается на ферритовом кольце тремя сложенными вместе проводами и содержит шесть витков, обмотки фазируются, как указано на схеме.

В принципе, даже мотать трансформатор необязательно, можно использовать готовый, например из ADSL-модема. Все в этой модификации хорошо, разве что шаг у RTL2832U 0.5 мм и выводы очень короткие. Так что припаять к самим контактам МГТФ 0.05 у меня не вышло. Вместо этого я подпаял к ним провод 0.1 мм, а уже к нему — выводы трансформатора. Чтобы вся эта конструкция держалась и не шевелилась, я использовал термоскотч.

Эта модификация, конечно, требует определенных навыков, но все вполне реально (у меня ушло на это около получаса). Запускаем gqrx с параметрами устройства rtl=0,direct_samp=2 и видим, что все прекрасно работает (будем оптимистами). Подключаем рамочную антенну, и можно слушать эфир. Параметр direct_samp=2 указывает на то, что надо использовать прямую оцифровку сигнала со входа Q. Кроме того, основная функциональность устройства по-прежнему присутствует и запуск со стандартными параметрами позволяет принимать УКВ.

РЕКОМЕНДУЕМ:
Прием и декодирование сигналов из космоса Inmarsat и Iridium

Конечно, у такого простого решения есть и недостатки в виде наводок от FM-станций, ложных сигналов и прочих прелестей, но работает оно сравнимо с RTL-SDR v3. А если очень хочется, то устройство можно попробовать прокачать и дальше. Но это, на мой взгляд, излишне, разве что входной фильтр с частотой среза около 30 МГц и хороший, экранированный корпус точно еще никому не мешали.

Понравилась статья? Поделиться с друзьями:
Комментарии: 2
  1. Михаил

    Великолепная статья! Профессиональное изложение грамотным русским языком, лаконичное и культурное. Снимаю шляпу, уважаю. Подобный стиль редко встретишь на просторах интернета. Автору всех благ!

  2. Aleksandr

    Отличная статья! Чувствуется профессионализм на высоком уровне! В связи с чем имеется вопрос. Для моего проекта нужна схема двухканального SDR приемника, но не радио, а оптических сигналов, т.е. вместо антенны 2 фотодиода, а передатчиков выступает лазер с модулятором. Можете посоветовать что-либо? Возможно ли такое?
    Буду благодарен за профессиональное обсуждение.

Добавить комментарий