PyVisa는 Python을 이용하여 visa를 통한 GPIB, RS232, Ethernet, USB등의 Interface를 독립적으로 Control할 수 있는 Software Package입니다. 엔지니어의 Resource를 뺏어가는 가장 큰 요인 중의 하나는 반복적인 측정 업무입니다. 여러 산업에 걸쳐 그에 맞는 수많은 계측기들이 개발되어 왔으나 이를 컨트롤할 수 있는 표준들이 업체나 장비별로 제각각이어서 각각의 측정 장비마다 automation을 하기 위해서는 해당 장비의 library나 programming 언어를 개별적으로 배워야 했으나 90년대에 이르러 이러한 불편함을 해소하고자 VISA(Virtual Instrument Software Architecture)라는 표준 프로토콜이 제정되므로서 GPIB, VXI, PXI, Serial, Ethernet 그리고 USB interfaces등을 아우르는 여러 측정 Interface에서 통용될 수 있게되어 이러한 불편이 해소되었습니다. VISA를 통해 C, C++, LABVIEW등의 프로그래밍 언어로 측정 프로그램을 구현하여 손쉽게 계측 장비를 컨트롤함으로써 반복적이고 긴 시간을 요구하는 측정 업무를 대신할 수 있게 되었고 Python의 PyVisa로도 이러한 VISA Programming이 가능하게 되었다.


아래의 예제는 network analyzer를 컨트롤 할 수 있게끔 구현한 프로그램이다.


#coding:utf-8

import sys
import time
import pyvisa
from PyQt5.QtWidgets import *
from PyQt5 import uic

UserUI = uic.loadUiType("lossmeasurement.ui")[0]

class NetworklossMain(QMainWindow, UserUI):
rm = pyvisa.ResourceManager()
tester_list = rm.list_resources()

def __init__(self, *args, **kwargs):
super(NetworklossMain, self).__init__(*args, **kwargs)
UserUI.__init__(self)
self.setupUi(self)
self.pushButton.clicked.connect(self.EquipmentCheck)
self.pushButton_2.clicked.connect(self.LossCal)
self.pushButton_3.clicked.connect(self.EquipmentCal)
self.textBrowser.setPlainText('')
self.textBrowser_2.setPlainText('')
self.lineEdit.setText("setting.znx")

def EquipmentCheck(self):
try:
self.inst = self.rm.open_resource("TCPIP0:0.0.0.0::INSTR") # set your ip or gpib adress
s = self.inst.query("*IDN?")
name = s.split(",")[1]
if name = "ZNB8-4PORT":
s = self.inst.query("*OPC?")
if s == "1\n":
self.inst.write("*RST")
self.textBrowser.setPlainText("Reset Complete")
else:
self.textBrowser.setPlainText("Reset Fail")
else:
self.textBrowser.setPlainText("Check your config")
except:
self.textBrowser.setPlainText("Please check your Equipment!")

def LossCal(self):
self.inst = self.rm.open_resource("TCPIP0::0.0.0.0::INSTR")
self.inst.write(":SYSTEM:ERROR:DISPLAY:STATE ON")
self.textBrowser_2.clear()
self.inst.write(":MMEM:LOAD:STAT 1,'{0}'".format(self.lineEdit.text()))
self.inst.write("*WAI")
opc = self.inst.query(":SYSTEM:ERROR?")
time.sleep(1)
if "No error" in opc:
pass
else:
self.inst.query(":SYSTEM:ERROR:ALL?")
self.inst.write(":SYSTEM:ERROR:DISPLAY:STATE OFF")
self.inst.write("*RST")
self.textBrowser.setPlainText("set file is not appropriate. Try it again")
return
self.inst.write(":CALCULATE1:MARKER:AOFF")
i = 1
spara = []
fr = open("RFLOSS FREQ TABLE.txt", 'r', encoding='utf-8')
fr2 = open("compensation.txt", 'r', encoding='utf-8')
comp = fr2.readlines()
for line in fr:
line = line.rstrip('\n')
comp[i - 1] = comp[i - 1].rstrip('\n')
if i % 10 == 0:
self.inst.write(":CALCULATE1:MARKER10 ON")
self.inst.write(":CALCULATE1:MARKER10:X" + line + "MHZ")
s = self.inst.query(":CALCULATE1:MARKER10:Y?").
while s == '0\n' or s == '-999\n':
s = self.inst.query(":CALCULATE1:MARKER10:Y?")
s = float(s) - float(comp[i - 1])
s = round(s, 2)
spara.append(s)
self.inst.write(":CALCULATE1:MARKER:AOFF")
i += 1
else:
com1 = ":CALCULATE1:MARKER{0} ON".format(i % 10)
self.inst.write(com1)
com2 = ":CALCULATE1:MARKER{0}:X ".format(i % 10) + line + "MHZ"
self.inst.write(com2)
time.sleep(0.1)
com3 = ":CALCULATE1:MARKER{0}:Y?".format(i % 10)
s = self.inst.query(com3)
while s == '0\n' or s == '-999\n':
s = self.inst.query(com3)
s = float(s) - float(comp[i - 1])
s = round(s, 2)
spara.append(s)
i += 1
fr.close()

dat = self.inst.query(":SYST:DATE?")
dat = dat.split(',')
dat = dat[0].rstrip('\n') + '_' + dat[1].rstrip('\n') + '_' + dat[2].rstrip('\n')
fw = open("MeasuredPathLoss_TE_01Port_{0}.dec".format(dat), 'a')
dat = self.inst.query(":SYST:DATE?")
dat = dat.split(',')
dat = dat[1].rstrip('\n') + '/' + dat[2].rstrip('\n') + '/' + dat[0].rstrip('\n')
tim = self.inst.query("SYST:TIME?")
tim = tim.split('')
h = int(tim[O]) + 9
tim = str(h) + ':' + tim[1].rstrip('\n') + ':' + tim[2].rstrip('\n')
total_date = dat + '' + tim
prescript = "Please describe your comments"
fw.write(prescript)
frr = open("RFLOSS FREQ TABLE.txt", 'r', encoding = 'utf-8')
freqlines = frr.readlines()
j = 1
for val in spara:
if '\n' in freqlines[j - 1]:
pass
else:
freqlines[j - 1] = freqlines[j - 1] + '\n'
if j < 10:
k = '0' + str(i)
script = "Frequency_" + k + "=" + freqlines[j - 1] + "RFLoss_" + k + "=" + str(val) + '\n'
else:
script = "Frequency_{0}=".format(j) + freqlines[j - 1] + "RFLoss_{0}=".format(j) + str(val) +'\n'
fw.write(script)
j += 1
self.textBrowser.setPlainText('Loss Calibration Completed. Measured~~.dec')
fw.close()

def EquipmentCal(self):
self.inst = self.rm.open_resource("TCPIPO::0.0.0.0::INSTR")
s = self.inst.query(":SYSTem:COMMunicate:RDEVice: AKAL:ADDRess:ALL?")
if s == ''"\n":
self.inst.query(":SYSTEM:ERROR:ALL?")
self.inst.write(":SYSTEM:ERROR:DISPLAY:STATE OFF")
self.inst.write("*RST")
self.textBrowser.setPlainText('Please check your device')
return
else:
pass
s = s.rstrip('\n')
self.inst.write(":SYSTem:COMMunicate:RDEVice: AKAL:ADDRess {0}".format(s))
self.inst.write(":SENS1:CORR:COLL:AUTO:ASSignment:DELete:ALL")
self.inst.write(":SENS1:CORR:COLL:AUTO:CONF FNP Factory")
self.inst.write(":SENSе1:CORRection:COLLect:AUTO:ASSignment1:DEF:TPOR:DEF 1,2")
self.inst.write(":SENSе1:CORRection:COLLect:AUTO:ASSignment1:ACQUire")
time.sleep(10)
self.inst.write(":SENSе1:CORRection:COLLect:AUTO:SAVE")
dat = self.inst.query(":SYST:DATE?")
dat = dat.split(',')
dat = dat[0].rstrip('\n') + '_' + dat[1].rstrip('\n') + '_' + dat[2].rstrip('\n')
self.inst.write(":MMEM:STOR:STAT 1:{0}".format(dat))
m = self.inst.query("*OPC?")
if m == '1\n':
self.textBrowser.setPlainText("mission complete")
else:
self.textBrowser.setPlainText("Please try again")

if __name__ == "_main_":
app = QApplication(sys.argv)
window = NetworklossMain()
window.show()
app.exec_()



+ Recent posts