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

от автора

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

Наверное все, хоть немного интересующиеся радиосвязью, знают что с помощью 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> 

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

ссылка на оригинал статьи https://habr.com/ru/post/505944/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *