В далекие 70-е годы с подачи инженеров HP (Hewlett-Packard) появилась первая унифицированная шина автоматического управления измерительными приборами GPIB (General Purpose Interface Bus), международная электротехническая комиссия (IEC) зарегистрировала эту шину как стандартный интерфейс IEEE 488. Далее в 1990 году была зарегистрирована система команд SCPI (Standard Commands for Programmable Instruments) как надстройка над GPIB, которая определяет синтаксис, структуру команд, форматы данных управления измерительным и тестовым оборудование�� (генераторами, мультиметрами, осциллографами и др.)
Согласно спецификациям современных измерительных приборов можно управлять любой кнопкой на панели прибора при помощи SCPI (часто произносится как «скиппи», не путать со SciPy) команд. Команды имеют иерархическую структуру и строятся как дерево подкоманд, разделённых двоеточием. Обычно описание используемых команд приводится в инструкции по эксплуатации конкретного прибора и может отличаться у разных вендоров, пример тут или тут.
В настоящее время в результате бурного развития сетевых технологий наиболее перспективными считаются системы управления приборами на основе LAN(Ethernet) протокола, например LXI, VXI, PXI, VISA. Подробное описание этих протоколов доступно в поисковых системах Интернета.
Рассмотрим использование LXI (LAN extensions for instrumentation), так как эта платформа сочетает самые лучшие стороны GPIB, VXI и PXI, но в отличие от них не требуют специальных кабелей и дорогостоящих встроенных в прибор интерфейсных контроллеров. Тестовые системы на основе LXI могут масштабироваться от небольшой локальной сети до распределённой глобальной системы, подключённой к Интернету. Обычно приборы LXI обмениваются данными по локальной сети с помощью одного из двух протоколов: VXI-11 или HiSLIP. Оба протокола предоставляют механизмы для отправки стандартных команд SCPI в формате ASCII согласно спецификации шины GPIB.
VXI‑11 (VXIbus Instrument 1) основан на удаленном вызове процедуры open network computing (ONC RPC), который, в свою очередь, использует TCP/IP в качестве сетевого/транспортного уровня и обеспечивает связь с гарантией доставки сообщений, при этом несколько падает общая скорость обмена данными.
HiSLIP (High-speed LAN instrument protocol) является преемником протокола VXI-11 для инструментов на основе TCP, использует два сокета для одного соединения - один для передачи данных, другой для команд управления. Таким образом обеспечивается более высокая скорость обмена чем у VXI‑11. Протокол может использоваться в сетях IPv6 или IPv4.
Рассмотрим простой пример кода для создания системы автоматического тестирования (ATS- automatic testing system) - определение компрессии усилителя мощности.
Реальные усилители, в отличие от идеальных, имеют ограничение на допустимый уровень входного сигнала. Если постепенно увеличивать входной сигнал, мы заметим, что с определенного уровня усиление перестанет линейно увеличиваться и станет меньше на 1 dB это и есть точка компрессии (1 dB compression point, P1db). Иногда различают точки компрессии по входу и по выходу. В общем случае точка компрессии является функцией от частоты. Она также может зависеть от напряжения питания и других параметров.
Автоматизированный комплекс состоит из стенда в составе: инструментального компьютера, генератора, анализатора спектра подключенных в одну LAN сеть через свич и тестируемого усилителя (называемого в заграничных статьях как DUT- Device Under Test) и программной среды. На вход DUT подключаем выход из генератора, с выхода тестируемого девайса через аттенюатор подаем на вход анализатора спектра. В качестве программной среды использую оболочку Anaconda/Jupyter Notebook, язык Python 3.8.8, Win 10, фреймворки pandas, numpy - для работы с данными, matplotlib -для построения графиков и самое главное – устанавливаем библиотеку управления приборами -vxi11 (взято тут ).
import pandas as pd import numpy as np import vxi11 import time import matplotlib.pyplot as plt import seaborn as sns Gen = vxi11.Instrument("192.168.30.20") # IP генератора СВЧ Aspectr = vxi11.Instrument("192.168.30.40") # IP анализатора спектра print("Генератор=>", Gen.ask("*IDN?")) # команда SCPI идентификации генератора print("Анализатор=>", Aspectr.ask("*IDN?")) #команда SCPI идентификации анализатора спектра
Ответ:
Генератор=> Rohde&Schwarz,SMF100A,1167.0000k02/101422,3.1.19.15-3.20.390.24
Анализатор=> Rohde&Schwarz,FPH,1321.1711K36/101053,V2.50
Если приборы не определились в сети, сделать ping или выкл/вкл приборов.
Чтобы каждый раз вручную не устанавливать одинаковые режимы приборов можно создать и запускать следующую последовательность команд.
Aspectr.write("*RST") # общий сброс всех настроек анализатора спектра Aspectr.write("SENS:DET RMS") #установка среднеквадратичного измерителя Aspectr.write("FREQ:CENT 1100 MHz") # центральная частота анализатора спектра Aspectr.write("FREQ:SPAN 500KHz") # полоса обзора анализатора спектра Aspectr.write("DISP:TRAC:Y:RLEV -10dBm") # трэйс уровень (масштаб обзора) Gen.write('FREQ 1100 MHz') # устанавливаем частоту генератора
Вариант скрипта для измерения точки компрессии и сохранения результата в файл csv с колонками "Входн мощн dBm", "Выходн мощн dBm" и "К пер".
( "К пер"= "Входн мощн dBm" - "Выходн мощн dBm")
rs = [] columns = ["Входн мощн dBm", "Выходн мощн dBm", "К пер"] nn = str(input("Ввести номер DUT:" )) Pn = int(input("Ввести начальную мощность в dBm: ")) Pk = int(input("Ввести конечную мощность в dBm: ")) st = int(input("Ввести шаг в dBm:" )) Gen.write("OUTP ON") # включение ON вых мощности генератора for n in range(Pn,Pk,st): st = str(n) fg = "POW ss" # создаем форму команды установки мощности генератора s1 = fg.replace("ss", st) # меняем в форме ss на st Gen.write(s1) # записать команду s1 в Gen time.sleep(0.5) # задержка на 0.5 секунд inp = float(Gen.ask("POW?")) # считываем уровень мощности генератора oup = float(Aspectr.ask("CALC:MARK1:Y?")) # измер уровень мощности анализатором спектра print("Входная мощность ", inp, "dBm") print("Выходная мощность ", oup, "dBm") ku = inp - oup # коэф. усиления time.sleep(0.2) # задержка на 0.2 секунды row = [inp, oup, ku ] rs.append(row) dtf.to_csv("DUT"+ nn + ".csv") # сохранить датафрейм в csv Gen.write("OUTP OFF") # выключение OFF вых мощности
Посмотрим первые пять строк полученного файла DUT072.csv
data = pd.read_csv("DUT072.csv", index_col = 0) data.head()

Теперь сделаем визуализацию полученной таблицы, вычислим и отобразим точку компрессии на графике.
# вычислим точку data = pd.read_csv('DUT072.csv', index_col = 0) # считаем файл из архива str = data['К пер'].tolist() # возьмем столбец 'К пер'- коэффиц. передачи data_2 = np.array(str) # сформируем нампи массив i=1 while i < (data_2.size)-3: # пробежим в цикле по измеренным точкам до последней-3 a=data_2[i] b=data_2[i+3] m = round(abs(a-b), 4) # вычислим разницу if m > 1: komp=i+2 # если условие выполнено, получим номер строки точки компрессии break i += 1 v=data["Входн мощн dBm"] aa=v[komp] # по номеру получим входной уровень vh=data["Выходн мощн dBm"] bb=vh[komp] # по номеру получим выходной уровень # отобразим все на графике plt.figure(figsize=(8,4)) sns.scatterplot(x=data['Входн мощн dBm'], y=data['Выходн мощн dBm']) titl = 'Характеристика ВХОД\ВЫХОД ' plt.plot(aa, bb, 'r*', label = 'Точка компрессии P1db') # plt.legend() plt.title(titl) #Добавляем название графику plt.grid() #Включаем сетку plt.show() print("Точка компрессии по входн мощн dBm", aa)

Используя аналогичный подход, можно автоматизировать измерения АЧХ, коэффициента шума, нелинейных и интермодуляционных искажений различных усилителей и радио трактов, при этом минимизировать ошибки человеческого фактора.
