实现自动化控制,本次为大家讲解综测仪E7515B的控制逻辑。
新建底层控制逻辑
在文件basis_contorl.py中写入仪器控制底层代码,代码如下:
import tkinter.messagebox
import pyvisa
class InstrumentControl(object):
inst = None
def __init__(self, equipment_name: str, equipment_visa: str, visa_dll='c:/Windows/System32/visa32.dll'):
"""
建立仪器初始对象
@param equipment_name: 仪器名
@param equipment_visa: 仪器visa地址
@param visa_dll: visa.all地址
"""
try:
self.rm = pyvisa.ResourceManager(visa_dll)
print("打开visa32.dll文件成功")
self.inst = self.open_by_name(equipment_name, equipment_visa)
except Exception as e:
tkinter.messagebox.showerror('错误', '在{}中找不到visa32.dll,请确认正确安装了NI-MAX和驱动')
print(f"打开visa32.dll文件失败, 报错原因:{e}")
pass
def open_by_name(self, device_name, gpib_ip):
"""
仪表通讯
@param device_name:
@param gpib_ip:
@return: 仪器控制对象
"""
self.inst = self.rm.open_resource(gpib_ip)
print(self.inst)
print("打开资源:" + gpib_ip)
query_name_str = self.command_query("*IDN?")
print("查询名称为:" + query_name_str)
if device_name in query_name_str:
print("打开仪表成功,打开的是:" + device_name)
print("打开仪表成功,打开的是:" + device_name)
return self.inst
return self.inst
def command_write(self, write_cmd):
"""
命令写入
@param write_cmd: 写入指令
@return: 执行结果
"""
print("执行了写入指令:" + write_cmd)
ret_res = self.inst.write(write_cmd)
print("返回了:" + str(ret_res))
return ret_res
def command_read(self, read_cmd):
"""
命令读取
@param read_cmd: 读取指令
@return: 读取信息
"""
print("执行了读取指令:" + read_cmd)
ret_res = self.inst.read(read_cmd)
print("返回了:" + str(ret_res))
return ret_res
def command_query(self, query_cmd):
"""
命令查询
@param query_cmd: 查询指令
@return: 查询信息
"""
print("执行了查询指令:" + query_cmd)
ret_res = self.inst.query(query_cmd).replace('\n', '')
print("返回了:" + str(ret_res))
return ret_res
编写好底层控制代码,在文件instrument_uxm_E7515B.py写入综测仪E7515B的控制指令,代码如下:
import time
from instrument_control.basis_contorl import InstrumentControl
class UXMC(InstrumentControl):
def __init__(self, equipment_name: str, equipment_visa: str):
super(UXMC, self).__init__(equipment_name, equipment_visa)
def query_equipment_info(self):
"""
查询设备信息
:return:
"""
result = self.command_query("*IDN?")
return result
def reset_inst(self):
"""
仪器初始化
"""
self.command_write("SYSTem:PRESet:FULL")
time.sleep(30)
def select_sa_nsa(self, model: str):
"""
选择测试模式
:param model: SA或NSA
"""
self.command_write(f"SYSTem:MODE {model}")
time.sleep(15)
def query_test_model(self):
"""
查询测试的制式
:return: NSA/SA
"""
result = self.command_query("SYSTem:MODE?")
return result
def select_test_template(self, template="SA"):
"""
选择测试模板,SA:FR1NRMOP ,NSA:FR1DCMOP
:param template: 模板名称
"""
self.command_write(f"BSE:MEASure:TX:NR5G:CASE:CONFig {template}")
time.sleep(1)
def select_dl_allocation(self, allocation: str):
"""
选择分配RB,SA:FRB
:param allocation: 分配模式
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:DL:PRB:CALLocation {allocation}")
time.sleep(1)
def select_dl_index(self, index: int):
"""
选择DL MCS,SA:4
:param index:
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:DL:MCS:INDex {index}")
time.sleep(1)
def select_padding_status(self, status: int):
"""
打开或关闭padding, open:1, close:0
:param status: 打开或关闭,1/0
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:DL:PADDing {status}")
time.sleep(1)
def select_ul_allocation(self, allocation: str):
"""
选择分配RB,SA:IFUL
:param allocation: 分配模式
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:UL:PRB:CALLocation {allocation}")
time.sleep(1)
def select_ul_index(self, index: int):
"""
选择UL MCS,SA:2
:param index:
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:UL:MCS:INDex {index}")
time.sleep(1)
def select_max_power(self, power: int):
"""
选择最大测试功率,SA:26
:param power: 测试功率
"""
self.command_write(f"BSE:CONFig:NR5G:PMAX:VALue {power}")
time.sleep(1)
def select_band(self, band: str):
"""
选择测试band
:param band: N41, N78.....
"""
self.command_write(f"BSE:CONFig:NR5G:OBANd {band}")
time.sleep(5)
def select_bandwidth(self, bandwidth: int):
"""
设置带宽
:param bandwidth: 带宽
"""
self.command_write(f"BSE:CONFig:NR5G:DL:BW BW{bandwidth}")
time.sleep(2)
def select_scs(self, scs):
"""
设置scs
:param scs: FDD:MU0, TDD:MU1
"""
self.command_write(f"BSE:CONFig:NR5G:SUBCarrier:SPACing:COMMon {scs}")
time.sleep(2)
def select_test_channel(self, channel: int):
"""
选择测试信道
:param channel: 信道
"""
self.command_write(f"BSE:CONFig:NR5G:DL:ARFCn {channel}")
time.sleep(1)
def select_clpc(self, model: str):
"""
选择功率模式,
SA:TARG
:param model:功率模式
"""
self.command_write(f"BSE:CONFig:NR5G:UL:CLPControl:MODE {model}")
time.sleep(1)
def select_test_power(self, test_power: str):
"""
选择测试功率
:param test_power:测试功率
"""
self.command_write(f"BSE:CONFig:NR5G:UL:CLPControl:TARGet {test_power}")
time.sleep(2)
def connect_machine(self, state="SA"):
"""
连接机器
"""
if state == "SA":
self.command_write("BSE:CONNect")
elif state == "NSA":
self.command_write("BSE:CAGGregation:NR5G 'CELL1','CELL1'")
time.sleep(5)
def disconnect_machine(self, state="SA"):
"""
断开连接
"""
if state == "SA":
self.command_write("BSE:DISConnect")
elif state == "NSA":
self.command_write("BSE:CAGGregation:NR5G 'NONE','NONE'")
time.sleep(5)
def query_lte_connect_state(self):
"""
查询连接状态
:return: CONN/ON
"""
result = self.command_query("BSE:STATus:LTE:CELL1?")
return result
def query_connect_status(self):
"""
查询连接状态
:return: CONN/ON
"""
result = self.command_query("BSE:STATus:NR5G:CELL1?")
return result
def query_test_power(self):
"""
获取测试功率
:return:
"""
result = self.command_query("BSE:MEASure:NR5G:CELL1:ULPWr:PUSCh:MEAN:DBM?")
time.sleep(1)
return result
def set_lte_band(self, band: str):
"""
设置LTE的band
:param band: BXX
"""
self.command_write(f"BSE:CONFig:LTE:OBAND {band}")
time.sleep(5)
def set_lte_bw(self, bw: str):
"""
设置BW的带宽
:param bw: BWXX
"""
self.command_write(f"BSE:CONFig:LTE:BW BW{bw}")
time.sleep(5)
def set_lte_type(self, type: str):
"""
设置lte的功率测试模式
:param type: TARG
"""
self.command_write(f"BSE:CONFig:LTE:UL:CLPControl:MODE {type}")
time.sleep(1)
def set_lte_power(self, lte_power: str):
"""
设置lte的功率
:param lte_power: 测试功率
"""
self.command_write(f"BSE:CONFig:LTE:UL:CLPControl:TPOWer {lte_power}")
time.sleep(1)
def set_nsa_dl_rb_allocation(self, allocation: str):
"""
选择dl的分配模式
:param allocation: FRB
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:DL:PRB:CALLocation {allocation}")
time.sleep(1)
def set_nsa_dl_mcs(self, dl_mcs: str):
"""
选择nsa的dl mcs
:param dl_mcs: 4
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:DL:MCS:INDex {dl_mcs}")
time.sleep(1)
def set_nsa_mac_padding(self, state: str):
"""
打开或关闭padding, open:1, close:0
:param state: 打开或关闭,1/0
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:DL:PADDing:STATe {state}")
time.sleep(1)
def set_ul_rb_allocation(self, allocation: str):
"""
选择ul的分配模式
:param allocation: IFUL
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:UL:PRB:CALLocation {allocation}")
time.sleep(1)
def set_nsa_ul_mcs(self, ul_mcs: str):
"""
选择nsa的ul mcs
:param ul_mcs: 2
"""
self.command_write(f"BSE:CONFig:NR5G:SCHeduling:UL:MCS:INDex {ul_mcs}")
time.sleep(1)
def set_nsa_p_NR_fr1(self, value: str):
"""
设置最大功率上限
:param value: 26
"""
self.command_write(f"BSE:CONFig:NR5G:PHY:PNRFr1:VALue {value}")
time.sleep(1)
def set_nr_band(self, band: str):
"""
设置nr的band
:param band: NXX
"""
self.command_write(f"BSE:CONFig:NR5G:OBANd {band}")
time.sleep(5)
def set_nr_bw(self, bw: str):
"""
设置BW的带宽
:param bw: BWXX
"""
self.command_write(f"BSE:CONFig:NR5G:DL:BW {bw}")
time.sleep(1)
def set_nr_type(self, type: str):
"""
设置nr的功率测试模式
:param type: TARG
"""
self.command_write(f"BSE:CONFig:NR5G:UL:CLPControl:MODE {type}")
time.sleep(1)
def set_nr_power(self, nr_power: str):
"""
设置nr的功率
:param nr_power: 测试功率
"""
self.command_write(f"BSE:CONFig:NR5G:UL:CLPControl:TARGet:POWer {nr_power}")
time.sleep(1)
def hccu_set_loss_line(self, line_loss_value: str, use_name="NE_1.RF_1"):
"""
设置线损
:param line_loss_value: 线损值
:param use_name: 线损名(只对NE_1.RF_1生效)
"""
self.command_write("SYSTem:CORRection:STATe DIS")
self.command_write(f'SYSTem:CORRection:CSET1:DATA "{use_name}", {line_loss_value}')
self.command_write(f'SYSTem:CORRection:CSET1:MAPPing "{use_name}", IO')
self.command_write(f'SYSTem:CORRection:CSET1:STATe "{use_name}", ENAB')
self.command_write('SYSTem:CORRection:STATe ENABle')
def select_test_ui(self):
"""
切换回测试界面
"""
self.command_write("SYSTem:SCReen MEAS")
time.sleep(1)
def set_count_number(self, number=1):
"""
设置平均测量次数
:param number: 次数
"""
self.command_write(f"BSE:MEASure:TX:ENGine:NR5G:AVERage:COUNt {number}")
time.sleep(1)
def set_test_channel_type(self, type="PUSCh"):
"""
设置测量信道类型
:param type: 类型
"""
self.command_write(f"BSE:FUNCtion:TXMeas:NR5G:CHANnel:TYPE {type}")
time.sleep(1)
def set_test_list(self, list='"CHP, OBW"'):
"""
选择测试的参数集
:param list: 界面参数集
"""
self.command_write(f'BSE:MEASure:TX:NR5G:LIST {list}')
time.sleep(3)
def query_measure_status(self):
"""
检查测试动作是否完成,返回0代表测量成功
:return: 测量状态码
"""
result = self.command_query("BSE:MEASure:TX:STATus?")
time.sleep(1)
return result
def set_test_abort(self):
"""
测试中止(测试状态不为0时使用)
"""
self.command_write("BSE:MEASure:TX:ABORt")
time.sleep(1)
def set_power_single(self):
"""
进行power单点测试
"""
self.command_write("BSE:MEASure:TX:NR5G:INITiate")
time.sleep(1)
def query_power_value(self):
"""
查询power的值
:return: power值
"""
result = self.command_query("BSE:FUNCtion:TXMeas:NR5G:FETCh:CHP?")
time.sleep(1)
return result
def set_acp_signle(self):
"""
进行ACP单点测试
"""
self.command_write("BSE:FUNCtion:TXMeas:NR5G:INIT:ACP")
time.sleep(1)
def query_acp_value(self):
"""
查询ACP的值
:return: acp值
"""
result = self.command_query("BSE:FUNCtion:TXMeas:NR5G:FETCh:ACP?")
time.sleep(1)
return result
def set_test_continuous(self, status="0"):
"""
设置测试模式single或continuous
:param status: 1/0
"""
self.command_write(f"BSE:MEASure:TX:BASic:CONTinuous {status}")
time.sleep(1)
def set_test_accuracy(self, down_accuracy: str, up_accuracy: str):
"""
设置精度的范围
:param down_accuracy: 下限
:param up_accuracy: 上限
"""
self.command_write(f"BSE:CONFig:NR5G:UL:CLPControl:TARGet:TOLerance:NEGative {down_accuracy}")
self.command_write(f"BSE:CONFig:NR5G:UL:CLPControl:TARGet:TOLerance:POSitive {up_accuracy}")
def set_test_channel(self, test_channel: str):
"""
设置信道LOW/MID/HIGH
:param test_channel: 测试信道
"""
self.command_write(f"BSE:CONFig:NR5G:TEST:CHANnel {test_channel}")
time.sleep(10)
def query_test_channel(self):
"""
查询测试信道
:return: 信道
"""
result = self.command_query("BSE:CONFig:NR5G:DL:ARFCn?")
time.sleep(1)
return result
def set_lte_switch(self, status: str):
"""
开关lte
:param status:1/0
"""
self.command_write(f"BSE:CONFIG:LTE:CELL1:ACTive:STATe {status}")
time.sleep(5)
def set_nr_switch(self, status: str):
"""
开关nr
:param status:1/0
"""
self.command_write(f"BSE:CONFIG:NR5G:CELL1:ACTive:STATe {status}")
time.sleep(5)
def set_rfio_mode(self, status: str):
"""
设置1为默认模式, 设置0为自定义模式
:param status:1/0
"""
self.command_write(f"setup:PORTs:AUTomatic {status}")
time.sleep(5)
def remove_all_ports_roles(self):
"""
删除所有端口配置
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_1"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_2"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_3"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_4"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_5"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_6"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_7"
setup:PORTs:ROLes:REMove:ALL "NE_1.RF_8"
"""
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_1"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_2"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_3"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_4"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_5"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_6"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_7"')
self.command_write('setup:PORTs:ROLes:REMove:ALL "NE_1.RF_8"')
time.sleep(5)
def set_port(self, port_name: str, AntennaDirection: str, Technology: str, Diversity: str):
"""
设置port对应关系
:param port_name: 表名 NE_1.RF_x
:param AntennaDirection: UL/DL
:param Technology: NR/LTE
:param Diversity: Main/Diversity1/Diversity2/Diversity3/Diversity4/Diversity5/Diversity6/Diversity7/Diversity8
"""
cmd = """
setup:ports:roles:add "%s","{'AntennaDirection':'%s','Technology':'%s','SupportedBands':[{'Range':{'Minimum':50000000,'Maximum':6000000000},'Diversity':'%s','RfioGroupId':0,'Identifiers':[]}]}"
""" % (port_name, AntennaDirection, Technology, Diversity)
self.command_write(cmd)
time.sleep(5)
def select_mimo_nr(self, mimo: str):
"""
切换单/多输出
:param mimo: 模式 N1X2, N1X1
"""
self.command_write(f"BSE:CONFIG:NR5G:DL:MIMO:CONFig {mimo}")
time.sleep(5)
def select_mimo_lte(self, mimo: str):
"""
切换单/多输出
:param mimo: 模式 N1X2, N1X1
"""
self.command_write(f"BSE:CONFIG:LTE:DL:MIMO:CONFig {mimo}")
time.sleep(5)
def select_dl_power(self, dl_power: str):
"""
选择dl power
:param dl_power: 下行功率
"""
self.command_write(f"BSE:CONFIG:NR5G:DL:POWer:CHANnel {dl_power}")
time.sleep(2)
def select_dl_channel(self, channel: str):
"""
选择dl channel
:param channel: 下行信道
"""
self.command_write(f"BSE:CONFIG:NR5G:DL:ARFCn {channel}")
time.sleep(2)
def set_sa_dl_mimo(self, status: str):
"""
设置SA的DL MIMO
:param status: N1X1, N1X2, N2X2
"""
self.command_query(f"BSE:CONFIG:NR5G:DL:MIMO:CONFig {status}")
time.sleep(2)
def query_sa_dl_mimo(self):
"""
查询SA的DL MIMO
:return: N1X1, N1X2, N2X2
"""
result = self.command_query(f"BSE:CONFIG:NR5G:DL:MIMO:CONFig?")
return result
控制仪器时先设置控制对象,具体例子如下:
set_equipment_name = "E7515B"
set_equipment_visa = "仪器的GPIB地址"
d66319_object = UXMC(equipment_name=set_equipment_name, equipment_visa=set_equipment_visa)
关于综测仪E7515B的控制方法就到这里了,博主后续还会更新不同仪器的控制方法,各位敬请期待吧,有疑问欢迎找博主解答,我是活动的笑脸。