Python与矢量网络分析仪3671E:通道插损自动化校准(Vscode)

一、背景介绍

DUT集成了多个可调衰减的射频通道,可调衰减由高精度DAC和VVA构成,使用中电思仪的3671E矢量网络分析仪测试DUT的S参数,并自动化调整VVA的控制电压,以自动化获取指定衰减值对应的控制电平。

二、前期准备

Python环境:3.11.5(版本过高需要安装ipykernel)

Vscode版本:version 1.98

R&S visa:Version 5.12.3(最新版本7.2.5)

确保本地上位机与矢网以太网通信正常:
如何使用VISA通过以太网(Ethernet)和罗德施瓦茨设备通信_rohde&schwarz频谱仪如何联网-CSDN博客

三、代码实现

3.1 连接仪表

python 复制代码
import pyvisa 
import time
import numpy as np
# 导入 create_serial_command 函数
from serial_command_XYcal import create_serial_command

# 初始化VISA资源管理器
rm = pyvisa.ResourceManager()

# 连接到仪器
instrument = rm.open_resource('TCPIP0::10.0.0.102::inst0::INSTR')  # 通过LAN连接的例子

ID=instrument.query('*IDN?')  # 查询仪器信息
print("ID: ", ID)

instrument.write("*CLS")  # 复位状态寄存器
instrument.write("*RST")  # 复位仪器
instrument.write("CALC:PAR:DEL:ALL")    # 删除所有测量
time.sleep(1)

此处矢网的IP地址为:10.0.0.102,根据需要进行修改。运行代码,通信正常情况下,输出:ID: Ceyear Technologies,3671E,QZNK000625,2.2.0

3.2 仪表设置

设置内容:起始频率、功率、扫描点数、中频带宽、平均因子、光标等

python 复制代码
# -----------DUT参数设置-------------------
test_kind = 'XY' #表征待测试内容的类别
SET_aver_num=5  #平均次数

match test_kind=='XY':
    case 1: #校准矢网,以测试XY通道
        # # 测量项目和窗口曲线显示:
        delay_IL=6
        IL_indicator=5
        ISO_indicator=40
        # delay_ISO=2
        instrument.write("CALC:PAR:DEF:EXT 'Trace1', 'S21'") # 设置Trace1为S21
        # instrument.write("CALC:PAR:DEF:EXT 'Trace2', 'S11'") # 设置Trace2为S11
        # instrument.write("CALC:PAR:DEF:EXT 'Trace3', 'S22'") # 设置Trace3为S22
        instrument.write("DISPlay:WINDow1:STATE ON")         # 显示第一窗口
        instrument.write("DISP:WIND1:TRACE1:FEED 'Trace1'")  # Trace1显示在第一窗口内
        # instrument.write("DISP:WIND1:TRACE2:FEED 'Trace2'")  # Trace2显示在第一窗口内
        # instrument.write("DISP:WIND1:TRACE3:FEED 'Trace3'")  # Trace3显示在第一窗口内

        #---------------设置起始频率,功率,扫描点数----------
        instrument.write("SENSe1:FREQ:STAR 3e9")      # 设置起始频率
        instrument.write("SENSe1:FREQ:STOP 6e9")      # 设置终止频率
        instrument.write("SOURce1:POWer1 0dBm")       # 设置功率
        instrument.write("SENSe1:SWEep:POINts 1501")  # 设置扫描点数1501
        instrument.write("SENSe1:BANDwidth 10000")    # 设置中频带宽

        instrument.write("SENSe1:AVER:STATe OFF")      # 打开轨迹平均功能
        instrument.write("SENSe1:AVER:Count "+str(SET_aver_num))       # 设置平均因子为5

        instrument.write("CALC:PAR:SEL 'Trace1'")     # 选择测量S21
        instrument.write("CALCulate1:MARKer:AOFF")    # 关闭所有光标 
        time.sleep(0.1)
        instrument.write("CALCulate1:MARKer1:STATe ON")    # 打开光标1     
        instrument.write("CALCulate1:MARKer1:X 6e9")    # 设置光标1的X坐标为6GHz 
        # XYEcal() #XY通道电子校准

        print("XY通道校准完毕")

    case _: #校准矢网,以测试Z通道
        # # 测量项目和窗口曲线显示:
        delay_IL=1.5
        IL_indicator=4
        ISO_indicator=55
        # delay_ISO=1

        instrument.write("CALC:PAR:DEF:EXT 'Trace1', 'S21'") #设置Trace1为S11
        instrument.write("DISPlay:WINDow1:STATE ON")         #显示第一窗口
        instrument.write("DISP:WIND1:TRACE1:FEED 'Trace1'")  #Trace1显示在第一窗口内

        #---------------设置起始频率,功率,扫描点数----------
        instrument.write("SENSe1:FREQ:STAR 2e6")    # 设置起始频率
        instrument.write("SENSe1:FREQ:STOP 1e9")    # 设置终止频率
        instrument.write("SOURce1:POWer1 0dBm")    # 设置功率
        instrument.write("SENSe1:SWEep:POINts 500")    # 设置扫描点数500
        instrument.write("SENSe1:BANDwidth 10000")    # 设置中频带宽

        instrument.write("SENSe1:AVER:STATe OFF")      # 打开轨迹平均功能
        instrument.write("SENSe1:AVER:Count "+str(SET_aver_num))       # 设置平均因子为5

        instrument.write("CALC:PAR:SEL 'Trace1'")     # 选择测量S21
        instrument.write("CALCulate1:MARKer:AOFF")    # 关闭所有光标 
        instrument.write("CALCulate1:MARKer1:STATe ON")    # 打开光标1     
        instrument.write("CALCulate1:MARKer1:X 1e9")    # 设置光标1的X坐标为1GHz  
#         ZEcal() #Z通道电子校准
        print("Z通道校准完毕")

3.3 插损态测试

测得的插损态S21数据作为校准的基准。

python 复制代码
#------------------测试参数设置-----------------------
DUT_num='M_0000'  # 模块编号
chn=5   # 测试通道

temp=25  #温度值
COM_port = 'COM3'  # 根据实际情况设置串口号
baudrate = 115200  # 波特率
ATT_stage=0 #衰减态
InputPower=0 #输入功率电平
# 初始调控电压
Vctrl_origin = np.array([0, 0.629, 0.684, 0.719, 0.778, 0.831, 0.871, 0.894, 0.92, 
                  0.977, 1.044, 1.073, 1.101, 1.149, 1.192, 1.216, 1.248])

if test_kind == 'XY':
    chn_IL=chn-4
    chn_ISO=chn-4
else:
    chn_IL=chn
    chn_ISO=chn

instrument.write("DISP:WIND:TRAC1:Y:RLEVel 0")    # 设置Y轴参考电平0dB
create_serial_command(COM_port, baudrate, chn, Vctrl_origin[ATT_stage]) #串口下发插损态
time.sleep(2)

instrument.write("CALC:PAR:SEL 'S21'")  # 选择S21参数
instrument.write("FORM:DATA ASCii")  # 设置为ASCII格式
readdata_0dB = instrument.query("CALC:DATA? FDATA")  # 获取测量数据
readdata_0dB_list = readdata_0dB.splitlines()  # 按行分割数据
data_0dB = np.array([list(map(float, row.split(','))) for row in readdata_0dB_list]) # 将每行数据转换为浮点数,并转换为numpy数组
print('data_0dB测试完成')

3.4 衰减态校准

python 复制代码
for ATT_stage in range(1,17,1):
    CurretVctrl=Vctrl_origin[ATT_stage]
    print('当前衰减态初始调谐电压值:',CurretVctrl)
    while True:
        create_serial_command(COM_port, baudrate, chn, CurretVctrl) #串口下发衰减态
        time.sleep(1.5)

        instrument.write("CALC:PAR:SEL 'S21'")  # 选择S21参数
        instrument.write("FORM:DATA ASCii")  # 设置为ASCII格式
        data = instrument.query("CALC:DATA? FDATA")  # 获取测量数据
        data_list = data.splitlines()  # 按行分割数据
        data_array = np.array([list(map(float, row.split(','))) for row in data_list])  # 将每行数据转换为浮点数,并转换为numpy数组

        deviation_max=np.max(data_array-data_0dB+ATT_stage)  #取偏离值的最大值和最小值,无偏离时,理论为0
        deviation_min=np.min(data_array-data_0dB+ATT_stage)
        deviation_aver=(deviation_max+deviation_min)/2
        print('偏离平均值:',deviation_aver)   

        if np.abs(deviation_aver)<=0.05:
            Vctrl_origin[ATT_stage]=CurretVctrl
            print('最终调谐电压为:',CurretVctrl)
            break
                
        if np.abs(deviation_aver)>=0.1:
            k=1.1
        else:
            k=0.6
        CurretVctrl=CurretVctrl+0.02*deviation_aver*k

print('当前XY通道校准完成')
   
rounded_Vctrl_origin=[round(num, 4) for num in Vctrl_origin] #取小数点后4位
print(rounded_Vctrl_origin)

import os
folder_path = "D:\LBJ\project_files\\vscode_project\TwoSignalAdder_V1\\3671E_XYcal_files"   # 设置文件夹路径和文件名
file_path = os.path.join(folder_path, DUT_num)  
if os.path.exists(file_path):  # 检查文件是否已存在,若存在,则打开文件并读取行数
    with open(file_path, 'r') as file:
        lines = file.readlines()
else:
    lines = []

if len(lines) >= 4:   # 判断文件的行数是否已达到限制
    print("本文件已写满,请检查是否为下一个模块的数据")
else:
    with open(file_path, 'a') as file:    # 打开文件进行写入
        file.write(f"ch{len(lines)+1},{','.join(map(str, rounded_Vctrl_origin))}\n")        # 写入数据
    print(f"数据已写入{file_path}")

3.5 测试校准结果是否准确

python 复制代码
#test
for ATT_stage_test in range(0,17,1):
    CurretVctrl_test=rounded_Vctrl_origin[ATT_stage_test]
    create_serial_command(COM_port, baudrate, chn, CurretVctrl_test) #串口下发衰减态
    time.sleep(1.5)
    # 选择测量类型(此处以S21为例)
    instrument.write("CALC:PAR:SEL 'S21'")  # 选择S21参数
    # 选择数据格式(例如CSV)
    instrument.write("FORM:DATA ASCii")  # 设置为ASCII格式
    # 获取数据并保存到文件
    data_test = instrument.query("CALC:DATA? FDATA")  # 获取测量数据
    # 假设数据是以逗号分隔的多行文本
    data_list_test = data_test.splitlines()  # 按行分割数据
    # 将每行数据转换为浮点数,并转换为numpy数组
    data_array_test = np.array([list(map(float, row.split(','))) for row in data_list_test])

    deviation_max_test=np.max(data_array_test-data_0dB+ATT_stage_test)  #取偏离值的最大值和最小值,无偏离时,理论为0
    deviation_min_test=np.min(data_array_test-data_0dB+ATT_stage_test)
    deviation_aver_test=(deviation_max_test+deviation_min_test)/2
    print('偏离平均值:',deviation_aver_test)   

3.6 关闭连接

python 复制代码
# 关闭连接
instrument.close()

四、资源下载

Python代码下载链接:Python与矢量网络分析仪3671E:通道插损自动化校准(Vscode)资源-CSDN文库

自动化校准所需串口下发函数下载链接:

Python通道插损自动化校准,串口下发指令函数资源-CSDN文库

相关推荐
飞鸟真人12 小时前
关于python -m http.server的一些安全问题
python·安全·http
tjjucheng12 小时前
小程序定制开发哪家性价比高
python
No0d1es12 小时前
2025年12月 GESP CCF编程能力等级认证Python六级真题
python·青少年编程·gesp·ccf·六级
亮子AI13 小时前
【Python】比较两个cli库:Click vs Typer
开发语言·python
CappuccinoRose13 小时前
流计算概述
python·flink·流计算·数据流·pyflink
Dragon水魅13 小时前
Fandom Wiki 网站爬取文本信息踩坑实录
爬虫·python
Darkershadow13 小时前
蓝牙学习之unprovision beacon
python·学习·ble
小龙在山东13 小时前
基于 plumbum 跨平台执行Shell脚本
python
星辰烈龙13 小时前
黑马程序员JavaSE基础加强d5
服务器·网络·php
单片机系统设计14 小时前
基于STM32的水质检测系统
网络·stm32·单片机·嵌入式硬件·毕业设计·水质检测