Используем HackRF в качестве анализатора спектра

2 октября 2025

Давние читатели этого блога могут помнить, как когда-то я использовал RTL-SDR с генератором шума в качестве дешевого анализатора спектра. Метод оказался рабочим, хотя пользоваться им и не слишком удобно. Есть теория, что HackRF лучше справится с задачей за счет одновременного приема полосы в 20 МГц. Проверим, так ли это на самом деле.

В прошлый раз была использована утилита rtl_power. Аналогом для HackRF является hackrf_sweep. Но данные он выводит в формате, который нуждается в некоторой постобработке. Дабы не переизобретать велосипед, было решено воспользоваться открытой программой QSpectrumAnalyzer. Это GUI-фронтенд к hackrf_sweep, а также утилитам для прочих SDR.

QSpectrumAnalyzer работает везде, где работает Python:

pip3 install pyqt5 qspectrumanalyzer

На момент написания этих строк QSpectrumAnalyzer имел небольшую проблему совместимости с NumPy версии 2.3.3 и старше. Решается исправлением одной строчки в файле qspectrumanalyzer/backends/hackrf_sweep.py. Когда вы будете читать этот пост, проблема может уже утратить актуальность.

Интерфейс программы интуитивно понятен, поэтому не будем долго на нем задерживаться. В настройках в качестве бэкенда нужно выбрать hackrf_sweep. Там же можно указать дополнительные аргументы. Забегая немного вперед, я указал -a 0 -l 8 -g 0. Из вывода hackrf_sweep --help:

[-a amp_enable]        # RX RF amplifier 1=Enable, 0=Disable
[-l gain_db]           # RX LNA (IF) gain, 0-40dB, 8dB steps
[-g gain_db]           # RX VGA (baseband) gain, 0-62dB, 2dB steps

В качестве первого эксперимента изучим выход миниатюрного генератора сигналов на базе MAX2870:

Генератор сигналов на базе MAX2870

Генератор имеет довольно чистый сигнал. Работает на частотах от 23.5 МГц до 6 ГГц. Реализован sweep mode. Цены в интернет-магазинах колеблются около 4000-5000 руб.

Максимальный уровень входного сигнала для HackRF составляет -5 dBm. Согласно даташиту, MAX2870 может выдавать до +5 dBm. Однако здесь речь о дифференциальном выходе на двух портах. Если снимать сигнал с одного порта, то его уровень не превышает +3 dBm, проверено. Таким образом, если подключить к генератору аттенюатор на 10 dB, то HackRF мы точно не спалим. Именно такой аттенюатор и показан на приведенном фото.

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

Подключаем MAX2870 к HackRF. В QSpectrumAnalyzer видим следующее:

Сигнал MAX2870 в программе QSpectrumAnalyzer

На пики слева и справа не обращаем внимания. Это артефакты работы FFT.

Указанные ранее аргументы hackrf_sweep подобраны так, чтобы обеспечить хорошее усиление сигнала, но при этом не перегружать приемник. Как проверить, что приемник не перегружен?

HackRF использует АЦП/ЦАП MAX5864. В даташите на последний заявлен SINAD равный 48.5 dB. Также приводится формула для перевода SINAD в эффективное количество бит:

>>> SINAD = 48.5
>>> ENOB = (SINAD - 1.76)/6.02
>>> ENOB
7.764119601328905

Если мы знаем последний, то знаем и динамический диапазон приемника:

>>> from math import log10
>>> 20 * log10(pow(2,ENOB) - 1)
46.704609669047144

Таким образом, для MAX5864 заявлен динамический диапазон в 46.7 dB. Если теперь посмотреть в QSpectrumAnalyzer, то от пикового значения сигнала (-27 dB) до уровня шума (-70 dB) на глаз мы видим около 43 dB. Значит, все в порядке.

Если использовать недостаточное усиление, то между пиком сигнала и уровнем шума будет меньше 40 dB. Это означает, что часть информации теряется в шуме, чего мы не хотим. Если же усиление слишком велико, то в QSpectrumAnalyzer мы увидим характерную картину с кучей более слабых сигналов в окрестностях того, что передается на самом деле.

В качестве еще одного эксперимента попробуем измерить АЧХ фильтра на спиральных резонаторах. Для начала запустим генератор в sweep mode на интервале от 25 МГц до 500 МГц. При помощи QSpectrumAnalyzer будем принимать сигнал на соответствующих частотах в режиме max hold:

Режим max hold в QSpectrumAnalyzer

Тут нужно подобрать правильный размер корзины FFT, а также шаг частоты и время перестройки на следующую частоту в генераторе. Задача состоит в том, чтобы красный график был без провалов. Уровень сигнала от MAX2870 довольно равномерен. На глаз назовем это постоянным уровнем -29.2 dB во всей полосе.

Теперь делаем все то же самое, но между генератором и HackRF подключаем измеряемый фильтр:

Измерение АЧХ фильтра при помощи HackRF и QSpectrumAnalyzer

Выглядит похоже на правду. Чтобы измерить фильтр поточнее, я повторил эксперимент на интервале частот 100-200 МГц. Потери в полосе пропускания получились 0.4 dB, а полоса по уровню -3 dB составила 10.6 МГц. Ранее на контрольном приборе были получены значения 0.6 dB и 11.5 МГц соответственно. Принимая во внимание разницу в стоимости между нашим текущим сетапом и контрольным прибором, я бы назвал это неплохой точностью.

Тут следует заострить внимание на важной особенности HackRF. В описанных опытах измерения проводились на удачном интервале частот. В более же общем случаем HackRF имеет неравномерности в уровне принимаемого сигнала. Связано это с тем, что устройство основано на трансивере MAX2837, который на самом деле принимает частоты лишь в интервале 2170-2740 МГц. Прием всех остальных частот осуществляется благодаря встроенному up/down-конвертеру. Подробности можно почерпнуть из структурной схемы устройства.

Удобство QSpectrumAnalyzer примерно соответствует удобству анализатора спектра без следящего генератора. То есть, не очень удобно, но пользоваться можно. Это был куда более приятный опыт по сравнению с моим прошлым опытом с RTL-SDR. Досадно, что в программе не реализованы курсоры, а также операции с трейсами. С другой стороны, принимая во внимание, что измерения не претендуют на большую точность, может оно и к лучшему. Зато интерфейс получился простым.

В целом, QSpectrumAnalyzer является отличным инструментом для начинающих радиолюбителей. Из других интересных опытов, которые можно с ним провести, могу рекомендовать измерение КСВ и диаграммы направленности антенн. Для частот ниже 23.5 МГц можно спаять генератор шума или генератор сигналов на основе Si5351. Если же вас больше интересует программирование, то можете законтрибьютить в QSpectrumAnalyzer те же курсоры и операции с трейсами.

Метки: , , .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.