Python使用 Pyvisa库 控制 NI 设备Fluke 6105A

目录

前提摘要: 

准备工作: 

 如何配置:

实现过程

连接设备

封装发送指令的函数

 输出电力信号的底层函数

输出电压

输出电流

开始输出/停止输出

写在最后: 


前提摘要: 

     首先介绍一下Fluke设备,设备是美国福禄克公司生产的,价值几百万的电能输出装置,可以输出电压,电流,谐波,间谐波,闪变,Dip,Swell等等各种所需的电力信号,由于精度很高,所以该设备可以用来做测量,也可以用来校准测量设备。

有人不了解该设备什么样子,所以贴个图吧;

Python使用 Pyvisa库 控制 NI 设备Fluke 6105A_第1张图片

准备工作: 

Fluke是一台支持GPIB协议的NI设备,接线拓扑图如下:

Python使用 Pyvisa库 控制 NI 设备Fluke 6105A_第2张图片

 如何配置:

 1. PC机安装NI-visa软件

官网下载ni-visa安装文件,安装完成后打开NI Package Manager,

软件安装、更新完成后按照提示重启电脑。

2.安装NI-488.2驱动程序

在NI Package Manager中搜索NI-488.2驱动程序,安装最新版本

Python使用 Pyvisa库 控制 NI 设备Fluke 6105A_第3张图片

3.使用NI MAX链接GPIB-ENET 1000

NI MAX->右击Network Devices->Add GPIB Ethernet Device

Python使用 Pyvisa库 控制 NI 设备Fluke 6105A_第4张图片

4.扫描FLUKE装置

 在NI Max中选择已经连接成功的NI GPIB-ENET 1000装置,点击下图中的‘Scan for instruments’按钮

 Python使用 Pyvisa库 控制 NI 设备Fluke 6105A_第5张图片

扫描结束后会显示如下图的  6105A ‘GPIB::18::INSTR’ 装置 :

Python使用 Pyvisa库 控制 NI 设备Fluke 6105A_第6张图片

至此,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,随时在线!!!

你可能感兴趣的:(仪器仪表控制,python,开发语言,Fluke,Pyvisa)