Панорама-FM или как увидеть все радиостанции сразу с помощью SDR

  • Tutorial
Привет, Хабр.

Наверное все, хоть немного интересующиеся радиосвязью, знают что с помощью SDR-приемника возможно принимать и обрабатывать широкую полосу спектра радиодиапазона. Собственно, отображением спектра в таких программах как HDSDR или SDR# никого не удивить. Я покажу как построить псевдо-3D спектр принимаемых станций с помощью RTL-SDR, GNU Radio и примерно 100 строк кода на языке Python.



Также мы возьмем приемник посерьезнее, и посмотрим на весь FM спектр 88-108МГц.
Продолжение под катом.

Технически, задача довольно проста. SDR-приемник оцифровывает входящий радиосигнал с помощью довольно быстрого АЦП. На выходе мы получаем широкополосный IQ-сигнал в виде массива чисел, приходящих с АЦП с частотой, соответствующей частоте дискретизации. Эта же частота определяет максимальную ширину полосы, принимаемую приемником. Все тоже самое, что и в звуковой карте, только в секунду мы имеем не 22050, а 2000000 или даже 10000000 значений. Для того, чтобы вывести спектр на экран, мы должны выполнить над массивом данных преобразование Фурье. Дальше остается вывести все это на экран, и задача решена. Остается лишь вопрос, как обойтись минимумом кода, для чего нам поможет GNU Radio.

Для тестов нам также понадобится RTL-SDR приемник, цена которого составляет порядка 30$. Он позволяет принимать сигналы в диапазоне частот примерно от 70 до 1700МГц и шириной полосы до 2МГц:



Если кто захочет повторить тесты с RTL-SDR самостоятельно, приемник нужен именно такой как на фото. Есть более дешевые клоны, но они хуже качеством.

Ну а мы приступим.

GNU Radio


Граф связей в GNU Radio показан на рисунке:



Как можно видеть, мы получаем данные с приемника, затем преобразуем непрерывный поток в набор «векторов» размером 1024, над этими блоками выполняем FFT, преобразуем значения из комплексных в вещественные, и отправляем данные по UDP. Разумеется, все это можно было бы сделать и непосредственно в Python с помощью SoapySDR и numpy, но объем кода был бы несколько больше.

Блок QT GUI Frequency Sink нужен для «отладки», с ним можно убедиться что сигналы радиостанций действительно принимаются и при необходимости настроить усиление приемника. Во время работы программы картинка должна быть примерно такой:



Если все работает, GUI Frequency Sink можно отключить, а в настройках проекта указать «No GUI», чтобы не тратить зря ресурсы. В принципе, эту программу дальше можно запускать как сервис, без какого-либо UI.

Отрисовка


Поскольку мы передаем данные по UDP, то принимать их мы можем любым клиентом, и даже на другом ПК. Будем использовать Python, для прототипа этого вполне достаточно.

Сначала мы получаем данные по UDP:

fft_size = 1024
udp_data = None
UDP_IP = "127.0.0.1"
UDP_PORT = 40868

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((UDP_IP, UDP_PORT))
sock.settimeout(0.5)

try:
    data, addr = sock.recvfrom(fft_size * 4)
    if len(data) == 4096:
        udp_data = np.frombuffer(data, dtype=np.float32)
        return True
except socket.timeout:
    pass

Т.к. мы будем работать с графикой, удобно воспользоваться библиотекой pygame. Рисование 3D-спектра делается просто, мы храним данные в массиве, и выводим линии сверху вниз, от более старых к более новым.

fft_size = 1024
depth = 255
fft_data = np.zeros([depth, fft_size])

def draw_image(screen, font):
    x_left, x_right, y_bottom = 0, img_size[0],  img_size[1] - 5
    # Draw spectrum in pseudo-3d
    for d in reversed(range(depth)):
        for x in range(fft_size - 1):
            d_x1, d_x2, d_y1, d_y2 = x + d, x + d + 1, y_bottom - int(y_ampl*fft_data[d][x]) - y_shift - d, y_bottom - int(y_ampl*fft_data[d][x+1]) - y_shift - d
            if d_y1 > y_bottom - 34: d_y1 = y_bottom - 34
            if d_y2 > y_bottom - 34: d_y2 = y_bottom - 34
            dim = 1 - 0.8*(d/depth)
            color = int(dim*data_2_color(fft_data[d][x]))
            pygame.draw.line(screen, (color//2,color,0) if d > 0 else (0, 250, 0), (d_x1, d_y1), (d_x2, d_y2), (2 if d == 0 else 1))

Последнее, это вывод частот и названий станций на экран. Преобразование Фурье дает на выходе 1024 точки, соответствующие ширине полосы пропускания приемника. Мы также знаем центральную частоту, так что вычисление позиции делается элементарной школьной пропорцией.

stations = [("101.8", 101.8), ("102.1", 102.1), ("102.4", 102.4), ... ]
for st_name, freq in stations:
    x_pos = fft_size*(freq - center_freq)*1000000//sample_rate
    textsurface = font.render(st_name, False, (255, 255, 0))
    screen.blit(textsurface, (img_size[0]//2 + x_pos - textsurface.get_width()//2, y_bottom - 22))

Собственно и все, объединяем все это вместе, запускаем обе программы одновременно, и получаем на экране real-time панораму, показывающую работающие в данный момент FM-станции:



Легко можно видеть, что разные станции вещают с разным уровнем, или по ширине полосы отличить моно-вещание от стерео.

Ну а теперь обещанная панорама всего FM-диапазона. Для этого нам придется отложить RTL-SDR и взять приемник посерьезнее, например такой:



Я использую профессиональную модель от Ettus Research, но с точки зрения кода все тоже самое, достаточно поменять в GNU Radio один блок на другой. А вот так это выглядит на спектре при ширине полосы приема 24МГц:



Любопытно, насколько разные уровни сигналов имеют разные радиостанции.

Разумеется, принимать можно не только станции FM-диапазона, но и любые другие, в пределах рабочих частот SDR-приемника. Для примера, вот так выглядит авиадиапазон:



Можно видеть постоянно активные частоты (вероятно метеослужба ATIS) и периодически возникающий радиообмен. А вот так выглядит фрагмент спектра GSM, однако, его сигнал шире чем 24МГц, и целиком не помещается.



Заключение


Как можно видеть, изучение радиоэфира процесс довольно занимательный, даже в 3D. Разумеется, здесь не было цели сделать «еще один спектроанализатор», это лишь прототип, сделанный для фана. Увы, отрисовка работает медленно, для вывода нескольких тысяч примитивов Python это не лучший выбор. Также алгоритм раскрашивания линий оставляет желать лучшего, в идеале, он может быть более гибким.

Для желающих поэкспериментировать самостоятельно, исходный код:

sdr_render.py
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image, ImageDraw
import sys
import pygame
from pygame.locals import *
from threading import Thread
import io
import cv2
import time
import socket


# FFT
receiver_name = "RTL-SDR"
center_freq = 102.5
sample_rate = 1800000
stations = [("101.8", 101.8), ("102.1", 102.1), ("102.4", 102.4), ("102.7", 102.7), ("103.0", 103.0), ("103.2", 103.2)]

# Load data from UDP
UDP_IP = "127.0.0.1"
UDP_PORT = 40868
udp_data = None
sock = None

# Panorama history
fft_size = 1024
depth = 255
fft_data = np.zeros([depth, fft_size])

# Canvas and draw
img_size = (fft_size, fft_size*9//16)
y_ampl = 90
color_ampl = 70
y_shift = 250


def udp_prepare():
    global sock
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # UDP
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind((UDP_IP, UDP_PORT))
    sock.settimeout(0.5)


def udp_getdata():
    global sock, udp_data
    try:
        data, addr = sock.recvfrom(fft_size * 4)
        if len(data) == 4096:
            udp_data = np.frombuffer(data, dtype=np.float32)
            return True
    except socket.timeout:
        pass
    return False


def clear_data():
    for y in range(depth):
        fft_data[y, :] = np.full((fft_size,), -1024)


def add_new_line():
    global udp_data, fft_data
    # Shift old data up
    for y in reversed(range(depth - 1)):
        fft_data[y + 1, :] = fft_data[y, :]
    # Put new data at the bottom line
    if udp_data is not None:
        fft_data[0, :] = udp_data


def data_2_color(data):
    c = -data + 2  # TODO: detect noise floor of the spectrum
    color = 150 - int(color_ampl * c)
    if color < 20:
        color = 20
    if color > 150:
        color = 150
    return color


def draw_image(screen, font):
    x_left, x_right, y_bottom = 0, img_size[0],  img_size[1] - 5
    # Draw spectrum in pseudo-3d
    for d in reversed(range(depth)):
        for x in range(fft_size - 1):
            d_x1, d_x2, d_y1, d_y2 = x + d, x + d + 1, y_bottom - int(y_ampl*fft_data[d][x]) - y_shift - d, y_bottom - int(y_ampl*fft_data[d][x+1]) - y_shift - d
            if d_y1 > y_bottom - 34: d_y1 = y_bottom - 34
            if d_y2 > y_bottom - 34: d_y2 = y_bottom - 34
            dim = 1 - 0.8*(d/depth)
            color = int(dim*data_2_color(fft_data[d][x]))
            pygame.draw.line(screen, (color//2,color,0) if d > 0 else (0, 250, 0), (d_x1, d_y1), (d_x2, d_y2), (2 if d == 0 else 1))
            
    # Bottom line
    pygame.draw.line(screen, (0,100,0), (x_left, y_bottom - 30), (x_right, y_bottom - 30), 2)
    # Station names
    for st_name, freq in stations:
        x_pos = fft_size*(freq - center_freq)*1000000//sample_rate
        textsurface = font.render(st_name, False, (255, 255, 0))
        screen.blit(textsurface, (img_size[0]//2 + x_pos - textsurface.get_width()//2, y_bottom - 22))
    text_mhz = font.render("MHz", False, (255, 255, 0))
    screen.blit(text_mhz, (img_size[0] - 5 - text_mhz.get_width(), y_bottom - 22))


if __name__ == "__main__":
    # UI init
    screen = pygame.display.set_mode(img_size)
    pygame.display.set_caption(receiver_name)
    pygame.font.init()
    font = pygame.font.SysFont('Arial Bold', 30)

    # Subscribe to UDP
    clear_data()
    udp_prepare()

    # Main loop
    is_active = True
    while is_active:
        # Get new data
        if udp_getdata():
            add_new_line()

            # Update screen
            screen.fill((0, 0, 0))
            draw_image(screen, font)
            pygame.display.flip()

        # Check sys events
        for events in pygame.event.get():
            if events.type == QUIT:
                is_active = False

sdr_receiver.grc
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.13'?>
<flow_graph>
  <timestamp>Sun Jun  7 13:17:58 2020</timestamp>
  <block>
    <key>options</key>
    <param>
      <key>author</key>
      <value></value>
    </param>
    <param>
      <key>window_size</key>
      <value></value>
    </param>
    <param>
      <key>category</key>
      <value>[GRC Hier Blocks]</value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>description</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(8, 8)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>generate_options</key>
      <value>no_gui</value>
    </param>
    <param>
      <key>hier_block_src_path</key>
      <value>.:</value>
    </param>
    <param>
      <key>id</key>
      <value>top_block</value>
    </param>
    <param>
      <key>max_nouts</key>
      <value>0</value>
    </param>
    <param>
      <key>qt_qss_theme</key>
      <value></value>
    </param>
    <param>
      <key>realtime_scheduling</key>
      <value></value>
    </param>
    <param>
      <key>run_command</key>
      <value>{python} -u {filename}</value>
    </param>
    <param>
      <key>run_options</key>
      <value>prompt</value>
    </param>
    <param>
      <key>run</key>
      <value>True</value>
    </param>
    <param>
      <key>sizing_mode</key>
      <value>fixed</value>
    </param>
    <param>
      <key>thread_safe_setters</key>
      <value></value>
    </param>
    <param>
      <key>title</key>
      <value></value>
    </param>
    <param>
      <key>placement</key>
      <value>(0,0)</value>
    </param>
  </block>
  <block>
    <key>variable</key>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(168, 12)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>fft_size</value>
    </param>
    <param>
      <key>value</key>
      <value>1024</value>
    </param>
  </block>
  <block>
    <key>variable</key>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(256, 12)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>samp_rate</value>
    </param>
    <param>
      <key>value</key>
      <value>1800000</value>
    </param>
  </block>
  <block>
    <key>blocks_complex_to_mag_squared</key>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(648, 108)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>blocks_complex_to_mag_squared_0</value>
    </param>
    <param>
      <key>maxoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>minoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>vlen</key>
      <value>fft_size</value>
    </param>
  </block>
  <block>
    <key>blocks_nlog10_ff</key>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(832, 100)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>blocks_nlog10_ff_0</value>
    </param>
    <param>
      <key>maxoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>minoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>vlen</key>
      <value>fft_size</value>
    </param>
    <param>
      <key>k</key>
      <value>0</value>
    </param>
    <param>
      <key>n</key>
      <value>1</value>
    </param>
  </block>
  <block>
    <key>blocks_stream_to_vector</key>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(256, 108)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>blocks_stream_to_vector_0</value>
    </param>
    <param>
      <key>type</key>
      <value>complex</value>
    </param>
    <param>
      <key>maxoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>minoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>num_items</key>
      <value>fft_size</value>
    </param>
    <param>
      <key>vlen</key>
      <value>1</value>
    </param>
  </block>
  <block>
    <key>blocks_udp_sink</key>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>ipaddr</key>
      <value>127.0.0.1</value>
    </param>
    <param>
      <key>port</key>
      <value>40868</value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(1000, 76)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>blocks_udp_sink_0</value>
    </param>
    <param>
      <key>type</key>
      <value>float</value>
    </param>
    <param>
      <key>psize</key>
      <value>fft_size*4</value>
    </param>
    <param>
      <key>eof</key>
      <value>True</value>
    </param>
    <param>
      <key>vlen</key>
      <value>fft_size</value>
    </param>
  </block>
  <block>
    <key>fft_vxx</key>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>True</value>
    </param>
    <param>
      <key>fft_size</key>
      <value>fft_size</value>
    </param>
    <param>
      <key>forward</key>
      <value>True</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(424, 76)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>fft_vxx_0</value>
    </param>
    <param>
      <key>type</key>
      <value>complex</value>
    </param>
    <param>
      <key>maxoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>minoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>nthreads</key>
      <value>1</value>
    </param>
    <param>
      <key>shift</key>
      <value>True</value>
    </param>
    <param>
      <key>window</key>
      <value>window.blackmanharris(fft_size)</value>
    </param>
  </block>
  <block>
    <key>qtgui_freq_sink_x</key>
    <param>
      <key>autoscale</key>
      <value>False</value>
    </param>
    <param>
      <key>average</key>
      <value>1.0</value>
    </param>
    <param>
      <key>axislabels</key>
      <value>True</value>
    </param>
    <param>
      <key>bw</key>
      <value>samp_rate</value>
    </param>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>fc</key>
      <value>102.5e6</value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>ctrlpanel</key>
      <value>False</value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>0</value>
    </param>
    <param>
      <key>fftsize</key>
      <value>1024</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(256, 188)</value>
    </param>
    <param>
      <key>gui_hint</key>
      <value></value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>grid</key>
      <value>False</value>
    </param>
    <param>
      <key>id</key>
      <value>qtgui_freq_sink_x_0</value>
    </param>
    <param>
      <key>legend</key>
      <value>True</value>
    </param>
    <param>
      <key>alpha1</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color1</key>
      <value>"blue"</value>
    </param>
    <param>
      <key>label1</key>
      <value></value>
    </param>
    <param>
      <key>width1</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha10</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color10</key>
      <value>"dark blue"</value>
    </param>
    <param>
      <key>label10</key>
      <value></value>
    </param>
    <param>
      <key>width10</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha2</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color2</key>
      <value>"red"</value>
    </param>
    <param>
      <key>label2</key>
      <value></value>
    </param>
    <param>
      <key>width2</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha3</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color3</key>
      <value>"green"</value>
    </param>
    <param>
      <key>label3</key>
      <value></value>
    </param>
    <param>
      <key>width3</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha4</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color4</key>
      <value>"black"</value>
    </param>
    <param>
      <key>label4</key>
      <value></value>
    </param>
    <param>
      <key>width4</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha5</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color5</key>
      <value>"cyan"</value>
    </param>
    <param>
      <key>label5</key>
      <value></value>
    </param>
    <param>
      <key>width5</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha6</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color6</key>
      <value>"magenta"</value>
    </param>
    <param>
      <key>label6</key>
      <value></value>
    </param>
    <param>
      <key>width6</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha7</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color7</key>
      <value>"yellow"</value>
    </param>
    <param>
      <key>label7</key>
      <value></value>
    </param>
    <param>
      <key>width7</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha8</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color8</key>
      <value>"dark red"</value>
    </param>
    <param>
      <key>label8</key>
      <value></value>
    </param>
    <param>
      <key>width8</key>
      <value>1</value>
    </param>
    <param>
      <key>alpha9</key>
      <value>1.0</value>
    </param>
    <param>
      <key>color9</key>
      <value>"dark green"</value>
    </param>
    <param>
      <key>label9</key>
      <value></value>
    </param>
    <param>
      <key>width9</key>
      <value>1</value>
    </param>
    <param>
      <key>maxoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>minoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>name</key>
      <value>""</value>
    </param>
    <param>
      <key>nconnections</key>
      <value>1</value>
    </param>
    <param>
      <key>showports</key>
      <value>True</value>
    </param>
    <param>
      <key>freqhalf</key>
      <value>True</value>
    </param>
    <param>
      <key>tr_chan</key>
      <value>0</value>
    </param>
    <param>
      <key>tr_level</key>
      <value>0.0</value>
    </param>
    <param>
      <key>tr_mode</key>
      <value>qtgui.TRIG_MODE_FREE</value>
    </param>
    <param>
      <key>tr_tag</key>
      <value>""</value>
    </param>
    <param>
      <key>type</key>
      <value>complex</value>
    </param>
    <param>
      <key>update_time</key>
      <value>0.10</value>
    </param>
    <param>
      <key>wintype</key>
      <value>firdes.WIN_BLACKMAN_hARRIS</value>
    </param>
    <param>
      <key>label</key>
      <value>Relative Gain</value>
    </param>
    <param>
      <key>ymax</key>
      <value>10</value>
    </param>
    <param>
      <key>ymin</key>
      <value>-140</value>
    </param>
    <param>
      <key>units</key>
      <value>dB</value>
    </param>
  </block>
  <block>
    <key>rtlsdr_source</key>
    <param>
      <key>alias</key>
      <value></value>
    </param>
    <param>
      <key>ant0</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain0</key>
      <value>20</value>
    </param>
    <param>
      <key>bw0</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode0</key>
      <value>0</value>
    </param>
    <param>
      <key>corr0</key>
      <value>0</value>
    </param>
    <param>
      <key>freq0</key>
      <value>102.5e6</value>
    </param>
    <param>
      <key>gain_mode0</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain0</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode0</key>
      <value>0</value>
    </param>
    <param>
      <key>gain0</key>
      <value>20</value>
    </param>
    <param>
      <key>ant10</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain10</key>
      <value>20</value>
    </param>
    <param>
      <key>bw10</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode10</key>
      <value>0</value>
    </param>
    <param>
      <key>corr10</key>
      <value>0</value>
    </param>
    <param>
      <key>freq10</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode10</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain10</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode10</key>
      <value>0</value>
    </param>
    <param>
      <key>gain10</key>
      <value>10</value>
    </param>
    <param>
      <key>ant11</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain11</key>
      <value>20</value>
    </param>
    <param>
      <key>bw11</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode11</key>
      <value>0</value>
    </param>
    <param>
      <key>corr11</key>
      <value>0</value>
    </param>
    <param>
      <key>freq11</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode11</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain11</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode11</key>
      <value>0</value>
    </param>
    <param>
      <key>gain11</key>
      <value>10</value>
    </param>
    <param>
      <key>ant12</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain12</key>
      <value>20</value>
    </param>
    <param>
      <key>bw12</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode12</key>
      <value>0</value>
    </param>
    <param>
      <key>corr12</key>
      <value>0</value>
    </param>
    <param>
      <key>freq12</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode12</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain12</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode12</key>
      <value>0</value>
    </param>
    <param>
      <key>gain12</key>
      <value>10</value>
    </param>
    <param>
      <key>ant13</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain13</key>
      <value>20</value>
    </param>
    <param>
      <key>bw13</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode13</key>
      <value>0</value>
    </param>
    <param>
      <key>corr13</key>
      <value>0</value>
    </param>
    <param>
      <key>freq13</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode13</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain13</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode13</key>
      <value>0</value>
    </param>
    <param>
      <key>gain13</key>
      <value>10</value>
    </param>
    <param>
      <key>ant14</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain14</key>
      <value>20</value>
    </param>
    <param>
      <key>bw14</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode14</key>
      <value>0</value>
    </param>
    <param>
      <key>corr14</key>
      <value>0</value>
    </param>
    <param>
      <key>freq14</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode14</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain14</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode14</key>
      <value>0</value>
    </param>
    <param>
      <key>gain14</key>
      <value>10</value>
    </param>
    <param>
      <key>ant15</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain15</key>
      <value>20</value>
    </param>
    <param>
      <key>bw15</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode15</key>
      <value>0</value>
    </param>
    <param>
      <key>corr15</key>
      <value>0</value>
    </param>
    <param>
      <key>freq15</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode15</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain15</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode15</key>
      <value>0</value>
    </param>
    <param>
      <key>gain15</key>
      <value>10</value>
    </param>
    <param>
      <key>ant16</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain16</key>
      <value>20</value>
    </param>
    <param>
      <key>bw16</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode16</key>
      <value>0</value>
    </param>
    <param>
      <key>corr16</key>
      <value>0</value>
    </param>
    <param>
      <key>freq16</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode16</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain16</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode16</key>
      <value>0</value>
    </param>
    <param>
      <key>gain16</key>
      <value>10</value>
    </param>
    <param>
      <key>ant17</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain17</key>
      <value>20</value>
    </param>
    <param>
      <key>bw17</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode17</key>
      <value>0</value>
    </param>
    <param>
      <key>corr17</key>
      <value>0</value>
    </param>
    <param>
      <key>freq17</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode17</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain17</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode17</key>
      <value>0</value>
    </param>
    <param>
      <key>gain17</key>
      <value>10</value>
    </param>
    <param>
      <key>ant18</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain18</key>
      <value>20</value>
    </param>
    <param>
      <key>bw18</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode18</key>
      <value>0</value>
    </param>
    <param>
      <key>corr18</key>
      <value>0</value>
    </param>
    <param>
      <key>freq18</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode18</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain18</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode18</key>
      <value>0</value>
    </param>
    <param>
      <key>gain18</key>
      <value>10</value>
    </param>
    <param>
      <key>ant19</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain19</key>
      <value>20</value>
    </param>
    <param>
      <key>bw19</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode19</key>
      <value>0</value>
    </param>
    <param>
      <key>corr19</key>
      <value>0</value>
    </param>
    <param>
      <key>freq19</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode19</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain19</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode19</key>
      <value>0</value>
    </param>
    <param>
      <key>gain19</key>
      <value>10</value>
    </param>
    <param>
      <key>ant1</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain1</key>
      <value>20</value>
    </param>
    <param>
      <key>bw1</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode1</key>
      <value>0</value>
    </param>
    <param>
      <key>corr1</key>
      <value>0</value>
    </param>
    <param>
      <key>freq1</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode1</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain1</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode1</key>
      <value>0</value>
    </param>
    <param>
      <key>gain1</key>
      <value>10</value>
    </param>
    <param>
      <key>ant20</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain20</key>
      <value>20</value>
    </param>
    <param>
      <key>bw20</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode20</key>
      <value>0</value>
    </param>
    <param>
      <key>corr20</key>
      <value>0</value>
    </param>
    <param>
      <key>freq20</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode20</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain20</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode20</key>
      <value>0</value>
    </param>
    <param>
      <key>gain20</key>
      <value>10</value>
    </param>
    <param>
      <key>ant21</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain21</key>
      <value>20</value>
    </param>
    <param>
      <key>bw21</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode21</key>
      <value>0</value>
    </param>
    <param>
      <key>corr21</key>
      <value>0</value>
    </param>
    <param>
      <key>freq21</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode21</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain21</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode21</key>
      <value>0</value>
    </param>
    <param>
      <key>gain21</key>
      <value>10</value>
    </param>
    <param>
      <key>ant22</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain22</key>
      <value>20</value>
    </param>
    <param>
      <key>bw22</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode22</key>
      <value>0</value>
    </param>
    <param>
      <key>corr22</key>
      <value>0</value>
    </param>
    <param>
      <key>freq22</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode22</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain22</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode22</key>
      <value>0</value>
    </param>
    <param>
      <key>gain22</key>
      <value>10</value>
    </param>
    <param>
      <key>ant23</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain23</key>
      <value>20</value>
    </param>
    <param>
      <key>bw23</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode23</key>
      <value>0</value>
    </param>
    <param>
      <key>corr23</key>
      <value>0</value>
    </param>
    <param>
      <key>freq23</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode23</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain23</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode23</key>
      <value>0</value>
    </param>
    <param>
      <key>gain23</key>
      <value>10</value>
    </param>
    <param>
      <key>ant24</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain24</key>
      <value>20</value>
    </param>
    <param>
      <key>bw24</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode24</key>
      <value>0</value>
    </param>
    <param>
      <key>corr24</key>
      <value>0</value>
    </param>
    <param>
      <key>freq24</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode24</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain24</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode24</key>
      <value>0</value>
    </param>
    <param>
      <key>gain24</key>
      <value>10</value>
    </param>
    <param>
      <key>ant25</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain25</key>
      <value>20</value>
    </param>
    <param>
      <key>bw25</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode25</key>
      <value>0</value>
    </param>
    <param>
      <key>corr25</key>
      <value>0</value>
    </param>
    <param>
      <key>freq25</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode25</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain25</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode25</key>
      <value>0</value>
    </param>
    <param>
      <key>gain25</key>
      <value>10</value>
    </param>
    <param>
      <key>ant26</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain26</key>
      <value>20</value>
    </param>
    <param>
      <key>bw26</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode26</key>
      <value>0</value>
    </param>
    <param>
      <key>corr26</key>
      <value>0</value>
    </param>
    <param>
      <key>freq26</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode26</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain26</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode26</key>
      <value>0</value>
    </param>
    <param>
      <key>gain26</key>
      <value>10</value>
    </param>
    <param>
      <key>ant27</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain27</key>
      <value>20</value>
    </param>
    <param>
      <key>bw27</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode27</key>
      <value>0</value>
    </param>
    <param>
      <key>corr27</key>
      <value>0</value>
    </param>
    <param>
      <key>freq27</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode27</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain27</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode27</key>
      <value>0</value>
    </param>
    <param>
      <key>gain27</key>
      <value>10</value>
    </param>
    <param>
      <key>ant28</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain28</key>
      <value>20</value>
    </param>
    <param>
      <key>bw28</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode28</key>
      <value>0</value>
    </param>
    <param>
      <key>corr28</key>
      <value>0</value>
    </param>
    <param>
      <key>freq28</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode28</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain28</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode28</key>
      <value>0</value>
    </param>
    <param>
      <key>gain28</key>
      <value>10</value>
    </param>
    <param>
      <key>ant29</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain29</key>
      <value>20</value>
    </param>
    <param>
      <key>bw29</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode29</key>
      <value>0</value>
    </param>
    <param>
      <key>corr29</key>
      <value>0</value>
    </param>
    <param>
      <key>freq29</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode29</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain29</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode29</key>
      <value>0</value>
    </param>
    <param>
      <key>gain29</key>
      <value>10</value>
    </param>
    <param>
      <key>ant2</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain2</key>
      <value>20</value>
    </param>
    <param>
      <key>bw2</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode2</key>
      <value>0</value>
    </param>
    <param>
      <key>corr2</key>
      <value>0</value>
    </param>
    <param>
      <key>freq2</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode2</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain2</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode2</key>
      <value>0</value>
    </param>
    <param>
      <key>gain2</key>
      <value>10</value>
    </param>
    <param>
      <key>ant30</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain30</key>
      <value>20</value>
    </param>
    <param>
      <key>bw30</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode30</key>
      <value>0</value>
    </param>
    <param>
      <key>corr30</key>
      <value>0</value>
    </param>
    <param>
      <key>freq30</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode30</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain30</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode30</key>
      <value>0</value>
    </param>
    <param>
      <key>gain30</key>
      <value>10</value>
    </param>
    <param>
      <key>ant31</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain31</key>
      <value>20</value>
    </param>
    <param>
      <key>bw31</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode31</key>
      <value>0</value>
    </param>
    <param>
      <key>corr31</key>
      <value>0</value>
    </param>
    <param>
      <key>freq31</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode31</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain31</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode31</key>
      <value>0</value>
    </param>
    <param>
      <key>gain31</key>
      <value>10</value>
    </param>
    <param>
      <key>ant3</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain3</key>
      <value>20</value>
    </param>
    <param>
      <key>bw3</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode3</key>
      <value>0</value>
    </param>
    <param>
      <key>corr3</key>
      <value>0</value>
    </param>
    <param>
      <key>freq3</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode3</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain3</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode3</key>
      <value>0</value>
    </param>
    <param>
      <key>gain3</key>
      <value>10</value>
    </param>
    <param>
      <key>ant4</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain4</key>
      <value>20</value>
    </param>
    <param>
      <key>bw4</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode4</key>
      <value>0</value>
    </param>
    <param>
      <key>corr4</key>
      <value>0</value>
    </param>
    <param>
      <key>freq4</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode4</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain4</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode4</key>
      <value>0</value>
    </param>
    <param>
      <key>gain4</key>
      <value>10</value>
    </param>
    <param>
      <key>ant5</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain5</key>
      <value>20</value>
    </param>
    <param>
      <key>bw5</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode5</key>
      <value>0</value>
    </param>
    <param>
      <key>corr5</key>
      <value>0</value>
    </param>
    <param>
      <key>freq5</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode5</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain5</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode5</key>
      <value>0</value>
    </param>
    <param>
      <key>gain5</key>
      <value>10</value>
    </param>
    <param>
      <key>ant6</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain6</key>
      <value>20</value>
    </param>
    <param>
      <key>bw6</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode6</key>
      <value>0</value>
    </param>
    <param>
      <key>corr6</key>
      <value>0</value>
    </param>
    <param>
      <key>freq6</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode6</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain6</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode6</key>
      <value>0</value>
    </param>
    <param>
      <key>gain6</key>
      <value>10</value>
    </param>
    <param>
      <key>ant7</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain7</key>
      <value>20</value>
    </param>
    <param>
      <key>bw7</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode7</key>
      <value>0</value>
    </param>
    <param>
      <key>corr7</key>
      <value>0</value>
    </param>
    <param>
      <key>freq7</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode7</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain7</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode7</key>
      <value>0</value>
    </param>
    <param>
      <key>gain7</key>
      <value>10</value>
    </param>
    <param>
      <key>ant8</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain8</key>
      <value>20</value>
    </param>
    <param>
      <key>bw8</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode8</key>
      <value>0</value>
    </param>
    <param>
      <key>corr8</key>
      <value>0</value>
    </param>
    <param>
      <key>freq8</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode8</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain8</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode8</key>
      <value>0</value>
    </param>
    <param>
      <key>gain8</key>
      <value>10</value>
    </param>
    <param>
      <key>ant9</key>
      <value></value>
    </param>
    <param>
      <key>bb_gain9</key>
      <value>20</value>
    </param>
    <param>
      <key>bw9</key>
      <value>0</value>
    </param>
    <param>
      <key>dc_offset_mode9</key>
      <value>0</value>
    </param>
    <param>
      <key>corr9</key>
      <value>0</value>
    </param>
    <param>
      <key>freq9</key>
      <value>100e6</value>
    </param>
    <param>
      <key>gain_mode9</key>
      <value>False</value>
    </param>
    <param>
      <key>if_gain9</key>
      <value>20</value>
    </param>
    <param>
      <key>iq_balance_mode9</key>
      <value>0</value>
    </param>
    <param>
      <key>gain9</key>
      <value>10</value>
    </param>
    <param>
      <key>comment</key>
      <value></value>
    </param>
    <param>
      <key>affinity</key>
      <value></value>
    </param>
    <param>
      <key>args</key>
      <value></value>
    </param>
    <param>
      <key>_enabled</key>
      <value>1</value>
    </param>
    <param>
      <key>_coordinate</key>
      <value>(16, 96)</value>
    </param>
    <param>
      <key>_rotation</key>
      <value>0</value>
    </param>
    <param>
      <key>id</key>
      <value>rtlsdr_source_0</value>
    </param>
    <param>
      <key>maxoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>clock_source0</key>
      <value></value>
    </param>
    <param>
      <key>time_source0</key>
      <value></value>
    </param>
    <param>
      <key>clock_source1</key>
      <value></value>
    </param>
    <param>
      <key>time_source1</key>
      <value></value>
    </param>
    <param>
      <key>clock_source2</key>
      <value></value>
    </param>
    <param>
      <key>time_source2</key>
      <value></value>
    </param>
    <param>
      <key>clock_source3</key>
      <value></value>
    </param>
    <param>
      <key>time_source3</key>
      <value></value>
    </param>
    <param>
      <key>clock_source4</key>
      <value></value>
    </param>
    <param>
      <key>time_source4</key>
      <value></value>
    </param>
    <param>
      <key>clock_source5</key>
      <value></value>
    </param>
    <param>
      <key>time_source5</key>
      <value></value>
    </param>
    <param>
      <key>clock_source6</key>
      <value></value>
    </param>
    <param>
      <key>time_source6</key>
      <value></value>
    </param>
    <param>
      <key>clock_source7</key>
      <value></value>
    </param>
    <param>
      <key>time_source7</key>
      <value></value>
    </param>
    <param>
      <key>minoutbuf</key>
      <value>0</value>
    </param>
    <param>
      <key>nchan</key>
      <value>1</value>
    </param>
    <param>
      <key>num_mboards</key>
      <value>1</value>
    </param>
    <param>
      <key>type</key>
      <value>fc32</value>
    </param>
    <param>
      <key>sample_rate</key>
      <value>samp_rate</value>
    </param>
    <param>
      <key>sync</key>
      <value></value>
    </param>
  </block>
  <connection>
    <source_block_id>blocks_complex_to_mag_squared_0</source_block_id>
    <sink_block_id>blocks_nlog10_ff_0</sink_block_id>
    <source_key>0</source_key>
    <sink_key>0</sink_key>
  </connection>
  <connection>
    <source_block_id>blocks_nlog10_ff_0</source_block_id>
    <sink_block_id>blocks_udp_sink_0</sink_block_id>
    <source_key>0</source_key>
    <sink_key>0</sink_key>
  </connection>
  <connection>
    <source_block_id>blocks_stream_to_vector_0</source_block_id>
    <sink_block_id>fft_vxx_0</sink_block_id>
    <source_key>0</source_key>
    <sink_key>0</sink_key>
  </connection>
  <connection>
    <source_block_id>fft_vxx_0</source_block_id>
    <sink_block_id>blocks_complex_to_mag_squared_0</sink_block_id>
    <source_key>0</source_key>
    <sink_key>0</sink_key>
  </connection>
  <connection>
    <source_block_id>rtlsdr_source_0</source_block_id>
    <sink_block_id>blocks_stream_to_vector_0</sink_block_id>
    <source_key>0</source_key>
    <sink_key>0</sink_key>
  </connection>
  <connection>
    <source_block_id>rtlsdr_source_0</source_block_id>
    <sink_block_id>qtgui_freq_sink_x_0</sink_block_id>
    <source_key>0</source_key>
    <sink_key>0</sink_key>
  </connection>
</flow_graph>


Как обычно, всем удачных экспериментов.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 26

    –8
    30 баксов потратить на приемник ради статьи по фану, так себе занятие во время самоизоляции. Однако статья клевая!
      +3
      Да, к сожалению Хабр никак не оптимизирован под обзоры железа, а спонсоров кто бы его оплачивал, нет. Но приемник уже был, так что ничего покупать не пришлось :)
      +1
      Подскажите, а подобного рода приёмниками можно определять расстояния до вышек? Если можно можно ли вычислить своё местоположение, зная координаты вышек радиовещания?
        +2
        Имхо вряд ли, ведь нужна точная привязка сигнала по времени. Да и задержки в USB непредсказуемы.

        Есть специальные устройства из 4х когерентных приемников, с ними можно определять направление на источник:
        www.rtl-sdr.com/kerberossdr-4-channel-rtl-sdr-passive-radar-with-peak-hold-display
        Есть другая фича, passive radar, но там как я понимаю, нужен опорный источник сигнала, от которого измеряются отражения.

        Еще есть сеть приемников kiwi-sdr, каждый их которых синхронизирован по GPS, там есть возможность пеленгации источника, но точность довольно низка:
        www.rtl-sdr.com/kiwisdr-tdoa-direction-finding-now-freely-available-for-public-use
        +2
        Можно программой rtlplan.exe посканировать эфир минут 30
        sourceforge.net/projects/guiforrtlpower
        image
          0
          Да, такого софта много, интерес был именно посмотреть как оно выглядит в 3D.
        0
        А сколько времени длится сканирование диапазона 2 мГц? Я к тому что можно ли после каждого сканирования диапазона сдвигать частоту на 2 мГц и получить более широкий диапазон?
          0
          Можно конечно, 5ю сообщениями выше приведен скриншот такого софта.

          При sample rate 2мегасемпла/с, 2 мегагерца приходит как раз за секунду, ну еще небольшая пауза нужна на перестройку частоты, плюс нужно частоты немного «внахлест» брать. А так, реально конечно, такой софт есть.
          0
          Всегда интересно было, что если подключить через хаб 4 дешевых rtl2832, по 2.5-3мгц, и каким-то софтом синхронно их перестраивать и склеивать картинку…
            +2
            Поздравляю, вы изобрели KerberosSDR: othernet.is/products/kerberossdr-4x-coherent-rtl-sdr :)

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

              Есть Airspy R2, он дороже, но умеет в 10 МГц.

                0
                А кстати, у Airspy есть поддержка GNU Radio?
                  +1
                  Судя по описанию — без проблем, через библиотеку libairspy (https://github.com/airspy/airspyone_host). В Gqrx точно работает, а он, как я понимаю, тот же GNURadio в обертке.
                +1
                Все возможно: www.rtl-sdr.com/combining-the-bandwidth-of-two-rtl-sdr-dongles-in-gnu-radio
                Основная проблема с множеством донглов — рассинхрон их клоков, поэтому ровной склейки не получится. Нужно либо модифицировать сами устройства, тактиря от одного генератора. Либо использовать готовое устройство, вроде указанного KerberosSDR.
                0
                А можно в форме готовой приложушки? Ну для тех кто не умеет в питон и прочую магию, но у кого есть sdr с диапазоном от 1мГц до 6ГГц.
                  0
                  А как работают webSDR показывая радиостанции чуть ли не всех диапазонов сразу в виде «водопада»?
                  Судя по фоткам у них там такие же «свистки» стоят.
                    0
                    Я может ошибаюсь, но в WebSDR отдельно выводится панорама в виде графического потока, плюс отдельный узкий канал звука на каждого подключенного юзера. Весь IQ поток каждому не передается.
                      0
                      Кстати, есть неплохое описание архитектуры openwebrx: sdr.hu/static/bsc-thesis.pdf
                        0
                        Я скорей про то, что там уже это всё сделано и на все диапазоны разом.
                          0
                          Сделано, да, только там не свисток, а достаточно дорогой 16-битный АЦП LTC2216 с DDC оцифровкой всего диапазона.

                          Здесь неплохое описание истории проекта: www.pa3fwm.nl/projects/sdr
                      –1

                      2 МГц спектр позволяет смотреть практически любой донгл. После слов "возьмём приемник посерьёзнее" ждал чего то поинтереснее, с полосой хотя бы 10 МГц. И захватом КВ.

                        +1
                        Мда, я понимаю что большинство читает по диагонали, но вы хоть до середины текста долистайте ;)
                          0
                          Приношу извинения, был не прав. Если подскажете в личку где такой покупали буду очень благодарен. Темой интересуюсь не из праздного интереса а в силу хобби. 73! de R0JAB
                            0
                            Модели, умеющие принимать полосу 30МГц:
                            — LimeSDR
                            — Adalm Pluto
                            — USRP
                            — BladeRF

                            Я покупал не в России, так что где лучше брать, не подскажу.

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

                      Самое читаемое