目录
前提摘要:
准备工作:
如何配置:
实现过程
连接设备
封装发送指令的函数
输出电力信号的底层函数
输出电压
输出电流
开始输出/停止输出
写在最后:
首先介绍一下Fluke设备,设备是美国福禄克公司生产的,价值几百万的电能输出装置,可以输出电压,电流,谐波,间谐波,闪变,Dip,Swell等等各种所需的电力信号,由于精度很高,所以该设备可以用来做测量,也可以用来校准测量设备。
有人不了解该设备什么样子,所以贴个图吧;
Fluke是一台支持GPIB协议的NI设备,接线拓扑图如下:
1. PC机安装NI-visa软件
官网下载ni-visa安装文件,安装完成后打开NI Package Manager,
软件安装、更新完成后按照提示重启电脑。
2.安装NI-488.2驱动程序
在NI Package Manager中搜索NI-488.2驱动程序,安装最新版本
3.使用NI MAX链接GPIB-ENET 1000
NI MAX->右击Network Devices->Add GPIB Ethernet Device
4.扫描FLUKE装置
在NI Max中选择已经连接成功的NI GPIB-ENET 1000装置,点击下图中的‘Scan for instruments’按钮
扫描结束后会显示如下图的 6105A ‘GPIB::18::INSTR’ 装置 :
至此,FULKE与PC机的连接完成。可以愉快的使用python调用 FULKE了 。
好了,废话不多说,下面就介绍一下该项目。这个项目主要用到的第三方库就是pyvisa,是一个控制各种计量设备的第三方库,这个项目的主要目的就是利用python完全控制Fluke 6105a 设备,解放双手来输出各种电量,更好的服务于自动化测试。
关于pyvisa的使用方法可以参考pyvisa的官方文档。
关于具体的命令这块可以参考我上传的资源:Fluke 6105A6100B英文版用户手册(最全).pdf
首先用pyvisa库的list_resource方法列出当前所有的设备,然后判断你的设备名称是否在列表中
import enum
import hashlib
import time
import pyvisa
class Fluke():
# region fluke initial
@classmethod
def _open_signal_analyzer_connection(cls, ipAddress):
ipAddress = str(ipAddress)
resourceName = 'TCPIP0::{:s}::inst0::INSTR'.format(ipAddress)
connectionID = cls.get_connectionID(resourceName)
if connectionID not in cls._connections:
cls._connections[connectionID] = cls._sigAnalyzer_connection(resourceName)
cls._active_connection = connectionID
print('Connect to SA successful')
return (connectionID, cls._connections[connectionID])
@classmethod
def _close_signal_analyzer_connection(cls, connectionID=None):
connectionID = cls._check_connectionID(connectionID)
try:
cls._connections[connectionID].close()
except SignalError as err:
print('{!s}'.format(err))
del cls._connections[connectionID]
cls._active_connection = None if not cls._connections else next(iter(cls._connections.keys()))
print('Disconnected with SA')
return (cls._active_connection, cls._connections[cls._active_connection] if cls._active_connection else None)
def send_raw_command(self, command, *args): # 很主要很核心的一个函数,用来向设备发送各种命令
if not command:
raise ValueError('Command string is empty')
try:
execStatus = self.inst.write(command)
return execStatus
except:
self._fluke_disconnection()
raise IOError('Send command ({:s}) to fluke is failed.'.format(command))
用来生成谐波信号的一个底层函数,后面会被其他函数调用,以此来实现电压,电流 等信号的输出
def _generic_harmonic_output(self, outputType, phase_id, frequency=None, phi=None, amp=None, h=None, net=1, enableChannel=1):
'''
用来生成谐波信号的一个底层函数,后面会被其他函数调用,以此来实现电压,电流 等信号的输出
'''
outputType = str(outputType).upper()[:4]
phase_id = int(phase_id)
frequency = float(frequency) if frequency is not None else frequency
phi = int(phi) if phi is not None else phi
amp = float(amp) if amp is not None else amp
net = int(net)
enableChannel = int(enableChannel)
ampRange = self._fluke_get_output_range(outputType, amp)
if outputType not in ['VOLT', 'CURR']:
raise ValueError('Invalid output type "{:s}"'.format(outputType))
if phi < -180 or phi > 180:
raise ValueError('Invalid angle of {:f}; must be in the range of (-180, 180)'.format(phi))
harmParameters = []
h_string = []
if frequency is not None:
harmParameters.append(':FREQ {:f}'.format(frequency))
if amp is not None:
harmParameters.append(':PHAS{:d}:{:s}:RANG {:f},{:f}'.format(phase_id, outputType, ampRange[0], ampRange[1]))
if enableChannel is not None:
harmParameters.append('STAT {:d}'.format(enableChannel))
if phi is not None and amp is not None:
h_string.append('HARM1 {:f},{:f}'.format(amp, phi))
if h is not None:
harmParameters.append('MHAR:STAT ON')
if self._get_dimensions(h) != 2:
raise AssertionError('The {} is not a two-dimensional array, it should be like:[[2,0,0],[3,0,0]] '.format(h))
for h_x in h:
h_order = int(h_x[0])
h_amp = float(h_x[1])
h_angle = float(h_x[2])
if h_order < 2:
raise ValueError(
'Invalid harmonic order of {:d}; must be greater than or equal to 2'.format(h_order))
if h_amp < 0 or h_amp > frequency:
raise ValueError(
'Invalid harmonic Amplitude of {:f}; must be in the range of [0, {}]'.format(frequency, h_amp))
if h_angle < -180 or h_angle > 180:
raise ValueError(
'Invalid harmonic angle of {:f}; must be in the range of [-180, 180]'.format(h_angle))
h_string.append('HARM{:d} {:f},{:f}'.format(h_order, h_amp, h_angle))
else:
harmParameters.append('MHAR:STAT OFF')
if len(harmParameters) > 1:
self.send_raw_command('{:s};{:s}'.format(';'.join(harmParameters), ';'.join(h_string)))
else:
print('No command sent, no parameter was set')
利用前面的输出信号的底层函数再次封装,进行电压输出
# region Voltage Output
def _set_harmonic_phase_voltage_output(self, phase_id, frequency, phi=0, u=0, mu=1, h=None, net=1):# 设置某一相位的谐波电压输出
self._generic_harmonic_output(outputType='VOLTAGE', phase_id=phase_id, frequency=frequency, amp=u, phi=phi, h=h)
def set_harmonic_voltage_output(self, frequency, phi_a=0, phi_b=-120, phi_c=120, ua=0, ub=0, uc=0, h_a=None, h_b=None, h_c=None, net=1):# 设置谐波电压输出(3个相位)
self._set_harmonic_phase_voltage_output(phase_id=1, frequency=frequency, u=ua, phi=phi_a, h=h_a)
self._set_harmonic_phase_voltage_output(phase_id=2, frequency=frequency, u=ub, phi=phi_b, h=h_b)
self._set_harmonic_phase_voltage_output(phase_id=3, frequency=frequency, u=uc, phi=phi_c, h=h_c)
def set_voltage_output(self, frequency, phi_a=0, phi_b=-120, phi_c=120, ua=0, ub=0, uc=0, net=1):# 设置电压信号输出(3个相位)
self._set_harmonic_phase_voltage_output(phase_id=1, frequency=frequency, u=ua, phi=phi_a)
self._set_harmonic_phase_voltage_output(phase_id=2, frequency=frequency, u=ub, phi=phi_b)
self._set_harmonic_phase_voltage_output(phase_id=3, frequency=frequency, u=uc, phi=phi_c)
同理,进行封装后可输出电流
def _set_harmonic_phase_current_output(self, phase_id, frequency, phi=0, i=0, mi=1, h=None, net=1):# 设置某一相位的谐波电流输出
self._generic_harmonic_output(outputType='CURRENT', phase_id=phase_id, frequency=frequency, amp=i, phi=phi, h=h)
def set_harmonic_current_output(self,frequency, phi_a=0, phi_b=-120, phi_c=120, ia=0, ib=0, ic=0, h_a=None, h_b=None, h_c=None, net=1):# 设置谐波电流输出(3个相位)
self._set_harmonic_phase_current_output(phase_id=1, frequency=frequency, i=ia, phi=phi_a, h=h_a)
self._set_harmonic_phase_current_output(phase_id=2, frequency=frequency, i=ib, phi=phi_b, h=h_b)
self._set_harmonic_phase_current_output(phase_id=3, frequency=frequency, i=ic, phi=phi_c, h=h_c)
def set_current_output(self, frequency, phi_a=0, phi_b=-120, phi_c=120, ia=0, ib=0, ic=0, net=1):# 设置电流信号输出(3个相位)
self._set_harmonic_phase_current_output(phase_id=1, frequency=frequency, i=ia, phi=phi_a)
self._set_harmonic_phase_current_output(phase_id=2, frequency=frequency, i=ib, phi=phi_b)
self._set_harmonic_phase_current_output(phase_id=3, frequency=frequency, i=ic, phi=phi_c)
前面的函数只是进行输出信号的配置,设置好以后需要设置开始方可激活输出
def activate_output(self):# 正式激活输出
self.send_raw_command(command='OUTP:STAT ON')
def deactivate_output(self):# 正式关闭输出
self.send_raw_command(command='OUTP:STAT OFF')
当年做这个项目主要文档就是Fluke设备的一份英文用户手册,大部分的命令都在手册中,具体实现都是参考这份手册。不过手册在远程控制部分没有中文,所以这个文档很难肯,前后做了两个多月完成!
该项目5月结束,一直没空写文章,今天周五,抽空写个文章,做个记录,留下个痕迹!
除了以上电压电流的基本操作好包括其他功能,比如谐波电压的输出,谐波电流的输出,间谐波的电压电流输出,Flicker(闪变信号)的输出等等。
有需要源码的同学可以私聊我,或者WX直接加xgh321324,随时在线!!!