← На главную

Строим графики КСВ с помощью Mini60S и Python

Один из недостатков антенного анализатора Mini60S заключается в том, что им неудобно смотреть изменение параметров антенны на широком интервале частот (например, от 1 до 30 МГц). Приложение Open60 позволяет строить такие графики, но делает это с большим шагом (около 1 МГц), из-за чего картина получается смазанной. Другой недостаток заключается в том, что иногда приложение подключается к устройству по Bluetooth не с первого раза. Было решено попробовать исправить оба недостатка при помощи небольшого набора скриптов.

Mini60S является клоном открытого антенного анализатора SARK-100, созданного испанским радиолюбителем Melchor Varela, EA4FRB. Оригинально SARK-100 можно было приобрести в виде набора для сборки. К сожалению, с октября 2011 наборы больше не выпускаются, а сам проект был объявлен устаревшим в пользу более продвинутого (и дорогого) анализатора SARK-110. Однако архив сайта SARK-100 до сих пор доступен онлайн вместе с прошивкой, схемой и пользовательским мануалом. Сейчас нас особенно интересует последний.

На странице 35 мы можем узнать, что устройство имеет USB-UART интерфейс, и что его скорость – 57600 бод. В свою очередь «Appendix I: PC Command Interface» на странице 77 содержит список поддерживаемых команд. Давайте проверим. Подключаем Mini60S к компьютеру через USB, нажимаем SET → PC Link. На компьютере говорим:

sudo cu -l /dev/tty.usbserial-00000000 -s 57600 -h

Попробуем ввести какую-нибудь команду:

>>scan 7000000 7200000 25000 Start 1.27,57,0,58 1.28,58,0,59 1.29,59,0,60 1.30,60,0,61 1.32,62,0,63 1.35,63,0,64 1.38,63,16,65 1.43,65,16,67 End

Хм… выглядит чем-то рабочим. Теперь дело за малым – автоматизировать сбор данных и их визуализацию.

За сбор будет отвечать скрипт mini60scan.py:

#!/usr/bin/env python3 -u # vim: set ai et ts=4 sw=4: import serial import argparse parser = argparse.ArgumentParser( description='Scan antenna parameters using SARK100/Mini60' ) parser.add_argument( '-b', '--begin', metavar='N', type=int, required=True, help='Frequency to start from, Hz') parser.add_argument( '-e', '--end', metavar='N', type=int, required=True, help='The end frequency, Hz') parser.add_argument( '-s', '--step', metavar='N', type=int, required=True, help='Step size, Hz') parser.add_argument( '-d', '--device', metavar='D', type=str, required=True, help='Serial port device name (e.g. /dev/tty.usbserial-00000000)') parser.add_argument( '-r', '--baudrate', metavar='N', type=int, default=57600, help='Baud rate (default 57600)') args = parser.parse_args() with serial.Serial(args.device, args.baudrate) as conn: cmd = "scan {} {} {}".format(args.begin, args.end, args.step) conn.write((cmd+"\r\n").encode('ascii')) freq = args.begin print("Freq,SWR,R,X,Z") while True: line = conn.readline().decode('ascii').strip() if line == '': continue elif line == 'Start': continue elif line == 'End': break swr, r, x, z = line.split(',') print("{},{},{},{},{}".format(freq,swr,r,x,z)) freq += args.step

Пример использования:

sudo ./mini60scan.py -b 1500000 -e 30000000 -s 25000 \ -d /dev/tty.usbserial-00000000 | tee double-vertical.csv

Скан от 1.5 МГц до 30 МГц с шагом 0.25 МГц дает достаточно точную картину и занимает 2 минуты 30 секунд. Если вы желаете просканировать тот же диапазон с шагом 0.1 МГц, это займет у вас 6 минут 10 секунд.

Для рисования графиков входного сопротивления и КСВ антенны воспользуемся библиотекой Matplotlib. Код скрипта mini60plot.py:

#!/usr/bin/env python3 -u # vim: set ai et ts=4 sw=4: import matplotlib as mpl # for MacOS, see https://stackoverflow.com/a/21789908/1565238 mpl.use('TkAgg') import matplotlib.pyplot as plt import matplotlib.dates as mdates import sys if len(sys.argv) < 3: print("Usage: " + sys.argv[0] + " input.csv output.png") sys.exit(1) infile = sys.argv[1] outfile = sys.argv[2] swr_color = 'green' z_color = 'red' freqs = [] values = { 'swr' : [], 'z': [] } nline = 0 min_freq, max_freq = 9999, 0 max_swr, max_z = 0, 0 with open(infile, newline = '') as f: for line in f: nline += 1 if nline == 1: # skip title continue f, swr, r, x, z = [ float(x) for x in line.strip().split(",") ] f = f / 1000000 print("f = {}, swr = {}".format(f, swr)) freqs += [f] values['swr'] += [ swr ] values['z'] += [ z ] max_swr = max(swr, max_swr) min_freq = min(f, min_freq) max_freq = max(f, max_freq) max_z = max(z, max_z) dpi = 80 fig = plt.figure(dpi = dpi, figsize = (512 / dpi, 384 / dpi) ) mpl.rcParams.update({'font.size': 10}) ax1 = fig.add_subplot(111) lns1 = ax1.plot(freqs, values['swr'], color=swr_color, linestyle = 'solid', label = 'SWR') ax1.set_xlabel("Freq (MHz)") ax1.set_xlim(min_freq, max_freq) # ax1.set_ylabel("SWR", color = swr_color) ax1.yaxis.label.set_color(swr_color) ax1.tick_params(axis='y', colors=swr_color) ax1.spines['left'].set_color(swr_color) ax1.spines['right'].set_color(z_color) ax1.set_ylim(1, max_swr) # highlight amateur radio bands for band in [ [1.8, 2.0], [3.5, 3.8], [7.0, 7.2], [10.1, 10.15], [14.0, 14.35], [18.068, 18.168], [21.0, 21.45], [24.89,24.99], [28.0,29.7] ]: ax1.axvspan(band[0], band[1], color='grey', alpha=0.3) ax2 = ax1.twinx() lns2 = ax2.plot(freqs, values['z'], color=z_color, linestyle = 'solid', label = 'Z (Ω)') # ax2.set_ylabel("Z", color = z_color) ax2.yaxis.label.set_color(z_color) ax2.tick_params(axis='y', colors=z_color) ax2.spines['left'].set_color(swr_color) ax2.spines['right'].set_color(z_color) ax2.set_ylim(0, max_z) lns = lns1 + lns2 labs = [ x.get_label() for x in lns ] ax2.legend(lns, labs, framealpha = 1, loc = 'upper right') fig.savefig(outfile)

Пример использования:

./mini60plot.py ./double-vertical.csv ./double-vertical.png

А так выглядит результат:

График КСВ и входного сопротивления антенны

Можно догадаться, что здесь мы смотрим на вертикал, описанный в недавнем посте Походная антенна-вертикал на диапазоны 15, 20 и 40 метров.

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

Тому есть ряд причин. В частности, ни один запорный дроссель не избавляет от синфазного тока на 100%. Следовательно, кабель всегда немножечко, но все-таки излучает. Кроме того, линия никогда не бывает идеальной, а значит в ней всегда есть какие-то потери. В случае с КСВ это особенно критично, потому что сначала сигнал ослабевает по пути в одну сторону, какая-то часть ослабленного сигнала отражается, и идет до КСВ-метра, ослабевая на обратном пути. В итоге КСВ-метр видит стоячую волну, образованную исходным сигналом и ослабленным отражением ослабленного сигнала. Добавьте сюда прочие факторы – волновое сопротивление кабеля, немного отличное от 50 Ом, не совсем точную калибровку устройства, и так далее, и можно легко увидеть КСВ 3-4 вместо КСВ 5-10 при использовании всего лишь нескольких метров RG58.

Fun fact! Двухпроводные линии с высоким волновым сопротивлением (от 300 до 600 Ом) имеют очень небольшие потери на КВ, поэтому написанное относится к ним в меньше степени. Однако при использовании такого фидера возникают другие нюансы – согласование импеданса, необходимость в отсутствии металлических предметов или земли на расстоянии от линии, равном десяти расстояниям между ее проводами, и так далее.

Такие дела. Теперь, когда 1) соединение с устройством действительно надежно, без этих ваших модных беспроводных протоколов, 2) сканирование диапазона можно производить с любым желаемым шагом и 3) мы выяснили, как правильно производить измерения, КСВ-метром прям стало можно пользоваться.

Дополнение: См также обзоры антенного анализатора EU1KY и NanoVNA.