前提摘要:

首先介绍一下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

光说文字太枯燥,直接上代码吧,不懂的地方看注释:

import enum
import hashlib
import time
import pyvisa# region enum class
class HarmonicMode(enum.Enum):  # 用于fluke设置选项的枚举类ABSOLUTE_RMS = 'ABS'PERCENT_OF_RMS = 'PRMS'PERCENT_OF_FUNDAMENTAL = 'PFUN'DB_DOWN_FROM_FUNDAMENTAL = 'DBF'class FlickerShape(enum.Enum):# 用于fluke设置选项的枚举类RECTANGULAR = 'RECT'SINUSOIDAL = 'SIN'SQUARE = 'SQU'class FlickerUnit(enum.Enum):# 用于fluke设置选项的枚举类HZ = 1CPM = 2class AngelUnit(enum.Enum):# 用于fluke设置选项的枚举类DEGREES = 'DEG'RADIANS = 'RAD'class SenseSetting(enum.Enum):# 用于fluke设置选项的枚举类FOUR_WIRE = 1TWO_WIRE = 0class TerminalRoute(enum.Enum):# 用于fluke设置选项的枚举类UPPER = 'UPPer'LOWER = 'LOWer'class UnbalanceSTD(enum.Enum):# 用于fluke设置选项的枚举类NEMA = 'NEMA'IEC = 'IEC'class FlickerSTD(enum.Enum):# 用于fluke设置选项的枚举类EDITION_2003 = 'STD1'EDITION_LATEST = 'STD2'class FlickShap(enum.Enum):# 用于fluke设置选项的枚举类RECTANGULAR = 'RECT'SINUSOIDAL = 'SIN'SQUARE = 'SQU'class ConstantUnits(enum.Enum):# 用于fluke设置选项的枚举类IPWH = 'IPWH'IPKWH = 'IPKWH'IPMWH = 'IPMWH'WHPI = 'WHPI'KWHPI = 'KWHPI'MWHPI = 'MWHPI'class EnergyMode(enum.Enum):# 用于fluke设置选项的枚举类COUNTED_TIME_MODE = 'TCO'GATE_MODE = 'GATE'PACKET_MODE = 'PACK'FREE_RUN_MODE = 'FRUN'class Derivation(enum.Enum):# 用于fluke设置选项的枚举类AS_TIME_SECONDS = 'SEC'AS_TIME_MINUTES = 'MIN'AS_TIME_HOURS = 'HOUR'AS_PULSE_PERIODS = 'PPER'AS_ENERGY_WH = 'WH'AS_ENERGY_KWH = 'KWH'AS_ENERGY_MWH = 'MWH'class MUTSources(enum.Enum):# 用于fluke设置选项的枚举类CHANNEL1 = 'CH1'CHANNEL1_2 = 'CH1TO2'CHANNEL1_3 = 'CH1TO3'CHANNEL1_4 = 'CH1TO4'CHANNEL1_5 = 'CH1TO5'CHANNEL1_6 = 'CH1TO6'class FlickerValuesHz(enum.Enum):# 用于fluke设置选项的枚举类HZ1 = 0.5HZ2 = 1HZ3 = 1.5HZ4 = 2HZ5 = 2.5HZ6 = 3HZ7 = 3.5HZ8 = 4HZ9 = 4.5HZ10 = 5HZ11 = 5.5HZ12 = 6HZ13 = 6.5HZ14 = 7HZ15 = 7.5HZ16 = 8HZ17 = 8.5HZ18 = 9HZ19 = 9.5HZ20 = 10HZ21 = 10.5HZ22 = 11HZ23 = 11.5HZ24 = 12HZ25 = 13HZ26 = 14HZ27 = 15HZ28 = 16HZ29 = 17HZ30 = 18HZ31 = 19HZ32 = 20HZ33 = 21HZ34 = 22HZ35 = 23HZ36 = 24HZ37 = 21.5HZ38 = 25.5HZ39 = 28HZ40 = 30.5HZ41 = 33.333HZ42 = 37HZ43 = 40class FlickerValuesCPM(enum.Enum):CPM1 = 1CPM2 = 2CPM3 = 7CPM4 = 39CPM5 = 110CPM6 = 1620CPM7 = 4000CPM8 = 4800class ReferenceSources(enum.Enum):# 用于fluke设置选项的枚举类MAIN = 'MAIN'CH6 = 'CH6'SUM_CHANNEL_4_5_6 = 'SUM456'MEAN_CHANNEL_4_5_6 = 'MEAN456'MEAN_CHANNEL_5_6 = 'MEAN56'MEAN_ALL_MUT = 'MMUT'class PullUpChoice(enum.Enum):# 用于fluke设置选项的枚举类R_150 = 'R150'R_1000 = 'R1000'# endregionclass Fluke():def __init__(self, resourceName, *args, **kwargs):# 初始化设备,连接设备self.resourceName = resourceNameself.inst = self._fluke_connection(visa_resource_name=self.resourceName)self.fluke_initialize()def _to_enum(self, name, enumClass): #用于枚举的方法if not issubclass(enumClass, enum.Enum):raise IOError('Class {:s} is not a subclass of {:s}'.format(enumClass.__name__, enum.Enum.__name__))if issubclass(name.__class__, enum.Enum) and name.__class__ == enumClass:return nameelif isinstance(name, str):# TODO: what about string enum values?try:return enumClass[name]except KeyError:raise KeyError('Enum class {:s} does not have an item with name {:s}'.format(enumClass.__name__, name))else:try:return enumClass(name)except:raise ValueError('Object of type {:s} is not a valid {:s} enum item'.format(type(name).__name__, enumClass.__name__))TRUE_STRINGS = {'TRUE', 'YES', 'ON', '1'}FALSE_STRINGS = {'FALSE', 'NO', 'OFF', '0', 'NONE', ''}def _is_truthy(self, item):if isinstance(item, str):return item.upper() not in self.FALSE_STRINGSreturn bool(item)# region fluke initialdef _fluke_connection(self, visa_resource_name): # 连接fluke设备rm = pyvisa.ResourceManager()resource_list = rm.list_resources(query='?*::INSTR')if visa_resource_name in resource_list:inst = rm.open_resource(visa_resource_name)inst.clear()inst.timeout = 8000return instelse:raise AssertionError("This fluke is not online.")def _fluke_disconnection(self): # 断开连接self.inst.close()def _fluke_read(self): # 读fluke设备返回的内容try:content = self.inst.read()except Exception as err:self._fluke_disconnection()raise IOError('Read error:{}'.format(err))return contentdef _fluke_query(self, command): # 查询fluke设备的内容data_length = len(command)if data_length != 0:try:content = self.inst.query(command)except Exception as err:self._fluke_disconnection()raise IOError("Query command ({:s}) to  fluke is failed:{:s}".format(command, err))else:raise AssertionError('This command is not correct!')return contentdef _fluke_reset(self): # 设备的重置self.send_raw_command('*CLS')self.send_raw_command('*RST')self._fluke_error_query()def _fluke_error_query(self): # 设备的错误信息查询self.send_raw_command(command=':SYST:ERR?')content = self._fluke_read()flag = content.split(',')[0]if flag != '0':self._fluke_disconnection()raise AssertionError('Already has error:{}'.format(content))def send_raw_command(self, command, *args): # 很主要很核心的一个函数,用来向设备发送各种命令if not command:raise ValueError('Command string is empty')try:execStatus = self.inst.write(command)return execStatusexcept:self._fluke_disconnection()raise IOError('Send command ({:s}) to fluke is failed.'.format(command))def fluke_initialize(self, reset=True): # 初始化设备(包括重置)self.send_raw_command('*IDN?')data = self._fluke_read()if 'Fluke' in data:if reset is True:self._fluke_reset()else:passelse:raise AssertionError('Fluke initialize failed: fluke general inoformation is wrong.The return content is: {}'.format(data))# endregion# region Device Lockingdef lock_device(self, cleanStart=True): # 锁定设备if self._locked:raise IOError('Device {:s} already locked'.format(self.resourceName))self._fluke_connection(visa_resource_name=self.resourceName)self._locked = Trueif cleanStart:passdef unlock_device(self):if not self._locked:raise IOError('Not locked any device')self._fluke_disconnection()self._locked = False@staticmethoddef get_connectionID(resourceName, *args, **kwargs):return hashlib.sha1(str(resourceName).lower().encode('utf-8')).hexdigest()# endregion# region Aux Outputdef activate_aux_output(self, u, auxID=1):raise NotImplementedError()def deactivate_aux_output(self, auxID=1):raise NotImplementedError()# endregion# region fluke settingdef fluke_configure_global_setting(self, frequency, lineLock=None, voltageHarmonicMode=None, currentHarmonicMode=None, angle=None, sense=None, currentTerminal=None, terminalRoute=None, unbalanceStandard=None, flickerStandard=None, ramp='FAST'):"""set the global setting:param frequency: float:param lineLock: True or False:param voltageHarmonicMode:ABSOLUTE_RMS, PERCENT_OF_RMS, PERCENT_OF_FUNDAMENTAL, DB_DOWN_FROM_FUNDAMENTAL:param currentHarmonicMode: ABSOLUTE_RMS, PERCENT_OF_RMS, PERCENT_OF_FUNDAMENTAL, DB_DOWN_FROM_FUNDAMENTAL:param angle:DEG or RAD:param sense: FOUR_WIR or TWO_WIR:param currentTerminal: True or False:param terminalRoute:UPPer or LOWer:param unbalanceStandard:NEMA or IEC:param flickerStandard: STD1 or STD2:return:None"""frequency = float(frequency)lineLock = self._is_truthy(lineLock) if lineLock is not None else lineLockvoltageHarmonicMode = self._to_enum(voltageHarmonicMode, HarmonicMode) if voltageHarmonicMode is not None else voltageHarmonicModecurrentHarmonicMode = self._to_enum(currentHarmonicMode, HarmonicMode) if currentHarmonicMode is not None else currentHarmonicModeangle = self._to_enum(angle, AngelUnit) if angle is not None else anglesense = self._to_enum(sense, SenseSetting) if sense is not None else sensecurrentTerminal = self._is_truthy(currentTerminal) if currentTerminal is not None else currentTerminalterminalRoute = self._to_enum(terminalRoute, TerminalRoute) if terminalRoute is not None else terminalRouteunbalanceStandard = self._to_enum(unbalanceStandard, UnbalanceSTD) if unbalanceStandard is not None else unbalanceStandardflickerStandard = self._to_enum(flickerStandard, FlickerSTD) if flickerStandard is not None else flickerStandardramp = str(ramp).upper()settingParameters = []if frequency is not None:settingParameters.append(':SOUR:FREQ {:f}'.format(frequency))if lineLock is not None:settingParameters.append(':SOUR:FREQ:LINE {:d}'.format(int(lineLock)))if voltageHarmonicMode is not None:settingParameters.append(':UNIT:MHAR:VOLT {:s}'.format(voltageHarmonicMode.value))if currentHarmonicMode is not None:settingParameters.append(':UNIT:MHAR:CURR {:s}'.format(currentHarmonicMode.value))if angle is not None:settingParameters.append(':UNIT:ANGL {:s}'.format(angle.value))if sense is not None:settingParameters.append(':OUTP:SENS {:d}'.format(sense.value))if currentTerminal is not None:settingParameters.append(':TERM {:d}'.format(int(currentTerminal)))if terminalRoute is not None:settingParameters.append(':TERM:ROUT {:s}'.format(terminalRoute.value))if unbalanceStandard is not None:settingParameters.append(':POW:UNB:STAN {:s}'.format(unbalanceStandard.value))if flickerStandard is not None:settingParameters.append(':FLIC:STAN {:s}'.format(flickerStandard.value))if ramp not in ['FAST', 'SLOW']:raise ValueError('Invalid ramp value of {:s}'.format(ramp))settingParameters.append(':OUTP:RAMP {:s}'.format(ramp))if len(settingParameters) > 1:self.send_raw_command('{:s}'.format(';'.join(settingParameters)))else:print('No command sent, no setting parameter was set')def _fluke_get_output_range(self, outputType, amp=None):uLow = 0amp = float(amp)if outputType == 'VOLT':if amp < 0 or amp > 1008:raise ValueError('Voltgae value should between 0 and 1008V !')elif amp > 650:uHigh = 1008elif amp > 360:uHigh = 650elif amp > 180:uHigh = 360elif amp > 90:uHigh = 180elif amp > 23:uHigh = 90else:uHigh = 23return float(uLow), float(uHigh)else:if amp < 0 or amp > 21:raise ValueError('Current value should between 0 and 21A !')elif 10 < amp <= 21:iLow, iHigh = 2, 21elif 1 < amp <= 10:iLow, iHigh = 1, 10elif 0.5 < amp <= 1:iLow, iHigh = 0.1, 1else:iLow, iHigh = 0.05, 0.5return float(iLow), float(iHigh)def fluke_config_energy_setting(self, mode=None, baseUnit=None, warmUpUnit=None, warmUpDuration=None, testUnit=None, testDuration=None, MUTSource=None, MUTConstantUnit=None, MUTConstant=None, MUTPullUp=None, refrenceSource=None, referConstantUnit=None, referConstant=None, referPullUp=None, outputConstantUnit=None, outputConstant=None, EnableOutputPullUp=None):'''energy 模块的全局设置'''mode = self._to_enum(mode, EnergyMode) if mode is not None else modebaseUnit = str(baseUnit).upper()warmUpUnit = self._to_enum(warmUpUnit, Derivation) if warmUpUnit is not None else warmUpUnitwarmUpDuration = float(warmUpDuration) if warmUpDuration is not None else warmUpDurationtestUnit = self._to_enum(testUnit, Derivation) if testUnit is not None else testUnittestDuration = float(testDuration) if testDuration is not None else testDurationMUTSource = self._to_enum(MUTSource, MUTSources) if MUTSource is not None else MUTSourceMUTConstantUnit = self._to_enum(MUTConstantUnit, ConstantUnits) if MUTConstantUnit is not None else MUTConstantUnitMUTConstant = float(MUTConstant) if MUTConstant is not None else MUTConstantMUTPullUp = self._to_enum(MUTPullUp, PullUpChoice) if MUTPullUp is not None else MUTPullUprefrenceSource = self._to_enum(refrenceSource, ReferenceSources) if refrenceSource is not None else refrenceSourcereferConstantUnit = self._to_enum(referConstantUnit, ConstantUnits) if referConstantUnit is not None else referConstantUnitreferConstant = float(referConstant) if referConstant is not None else referConstantreferPullUp = self._to_enum(referPullUp, PullUpChoice) if referPullUp is not None else referPullUpoutputConstantUnit = self._to_enum(outputConstantUnit, ConstantUnits) if outputConstantUnit is not None else outputConstantUnitoutputConstant = float(outputConstant) if outputConstant is not None else outputConstantEnableOutputPullUp = self._is_truthy(EnableOutputPullUp) if EnableOutputPullUp is not None else EnableOutputPullUpif refrenceSource in [ReferenceSources.MEAN_ALL_MUT, ReferenceSources.MAIN]:referConstantUnit, referConstant, referPullUp= None, None, NoneenergyParameters = []if mode is not None:energyParameters.append(':SOUR:ENER:MODE {:s}'.format(mode.value))if baseUnit is not None:energyParameters.append(':ENER:UNIT {:s}'.format(baseUnit))if warmUpUnit is not None and warmUpDuration is not None:energyParameters.append(':ENER:WUP:DUR {:s},{:f}'.format(warmUpUnit.value, warmUpDuration))if testUnit is not None and testDuration is not None:energyParameters.append(':ENER:TEST:DUR {:s},{:f}'.format(testUnit.value, testDuration))if MUTSource is not None:energyParameters.append(':ENER:MUT:SOUR {:s}'.format(MUTSource.value))if MUTConstantUnit is not None:energyParameters.append(':ENER:MUT:CONS:UNIT {:s}'.format(MUTConstantUnit.value))if MUTConstant is not None:energyParameters.append(':ENER:MUT:CONS {:f}'.format(MUTConstant))if MUTPullUp is not None:energyParameters.append(':ENER:MUT:PULL {:s}'.format(MUTPullUp.value))if refrenceSource is not None:energyParameters.append(':ENER:REF:SOUR {:s}'.format(refrenceSource.value))if referConstantUnit is not None:energyParameters.append(':ENER:REF:CONS:UNIT {:s}'.format(referConstantUnit.value))if referConstant is not None:energyParameters.append(':ENER:REF:CONS {:f}'.format(referConstant))if referPullUp is not None:energyParameters.append(':ENER:REF:PULL {:s}'.format(referPullUp.value))if outputConstantUnit is not None:energyParameters.append(':ENER:OUTP:CONS:UNIT {:s}'.format(outputConstantUnit.value))if outputConstant is not None:energyParameters.append(':ENER:OUTP:CONS {:f}'.format(outputConstant))if EnableOutputPullUp is not None:energyParameters.append(':ENER:OUT:PULL:STAT {:d}'.format(int(EnableOutputPullUp)))if len(energyParameters) > 1:self.send_raw_command('{:s}'.format(';'.join(energyParameters)))else:print('No energy parameters was sent!')def fluke_display_energy(self, channel, accumulatedWays='ENER', measuredWays='PERR'):channel = int(channel) #TODO Other parameter processingself.send_raw_command(':ENER:PRES {:s},{:s}'.format(accumulatedWays, measuredWays))result = self._fluke_query(':ENER:RES? CH{:d}'.format(channel))results = str(result).strip().split(',')return results# endregion# region Outputdef _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 frequencyphi = int(phi) if phi is not None else phiamp = float(amp) if amp is not None else ampnet = 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')def _get_dimensions(self, testList, dim=0):# 判断一个列表是否是二维的if isinstance(testList, list):if not testList:return dimdim += 1dim = self._get_dimensions(testList[0], dim)return dimelse:if dim == 0:return -1else:return dimdef _generic_interharmonic_output(self, outputType, phase_id, frequency=None, phi=None, amp=None, inter_h=None):'''用来生成间谐波信号的一个底层函数,后面会被其他函数调用,以此来实现间谐波电压,间谐波电流等信号的输出'''outputType = str(outputType).upper()[:4]frequency = float(frequency) if frequency is not None else frequencyphase_id = int(phase_id)amp = float(amp) if amp is not None else ampphi = int(phi) if phi is not None else phiinterNum = len(inter_h) if inter_h is not None else inter_hself._generic_harmonic_output(outputType=outputType, phase_id=phase_id, frequency=frequency, phi=phi, amp=amp, h=None)if inter_h is not None:if self._get_dimensions(inter_h) != 2:raise AssertionError('The {} is not a two-dimensional array, it should be like:[[amp,freq], [amp2,freq2]] or [[amp,freq]] !'.format(inter_h))if interNum > 2:raise AssertionError('Fluke each phase can only support interharmonic up to 2 times at a time')interh_string = []signalNum = 1for h_x in inter_h:h_freq = float(h_x[0])h_amp = float(h_x[1])if h_amp < 0 :raise ValueError('Invalid interharmonic Amplitude of {:f}'.format(h_amp))if h_freq < 5 or h_freq > 2850:raise ValueError('Invalid interharmonic frequency of {:f}'.format(h_freq))interh_string.append('SIGN{:d} ON,{:f},{:f}'.format(signalNum, h_amp, h_freq))signalNum += 1self.send_raw_command(':PHAS{:d}:{:s}:STAT ON;IHAR:STAT ON;{:s}'.format(phase_id, outputType, ';'.join(interh_string)))def _generic_flicker_output(self, outputType, phase_id, frequency, phi=None, amp=None, shap=None, depth=None, freq=None, unit=FlickerUnit.HZ):'''用来生成闪变信号的一个底层函数,后面会被其他函数调用,以此来实现闪变信号的输出'''outputType = str(outputType).upper()[:4]frequency = float(frequency) if frequency is not None else frequencyphase_id = int(phase_id)amp = float(amp) if amp is not None else ampphi = int(phi) if phi is not None else phishap = self._to_enum(shap, FlickerShape) if shap is not None else shapdepth = float(depth) if depth is not None else depthfreq = float(freq) if freq is not None else frequnit = self._to_enum(unit, FlickerUnit)if outputType not in ['VOLT', 'CURR']:raise ValueError('Invalid output type {:s}'.format(outputType))if amp not in [120, 230]:raise ValueError('Invalid amp value of {:s},it should be 120 or 230 V!'.format(amp))if unit == FlickerUnit.HZ:try:freq = self._to_enum(freq, FlickerValuesHz)except ValueError:raise ValueError('Invalid change rate of {:s}.'.format(freq))else:try:freq = int(freq)freq = self._to_enum(freq, FlickerValuesCPM)except ValueError:raise ValueError('Invalid change rate of {:s}.'.format(freq))flickParameters = []if shap is not None:flickParameters.append('SHAP {:s}'.format(shap.value))if depth is not None:flickParameters.append('DEPT {:f}'.format(depth))if unit is not None:flickParameters.append('FREQ:UNIT {:s}'.format(unit.name))if freq is not None:flickParameters.append(':PHAS{:d}:VOLT:FLIC:FREQ {:f}'.format(phase_id, float(freq.value)))self._generic_harmonic_output(outputType=outputType, phase_id=phase_id, frequency=frequency, phi=phi, amp=amp,h=None)if len(flickParameters) > 1:self.send_raw_command(':PHAS{:d}:VOLT:FLIC:STAT ON;{:s}'.format(phase_id, ';'.join(flickParameters)))else:print('No flicker Command sent, no parameter was set!')# endregion# region Voltage Outputdef _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_simple_voltage_output(self, frequency, amplitude):# 再次封装,实现简易的电压信号输出self.set_voltage_output(frequency=frequency, phi_a=0, phi_b=-120, phi_c=120, ua=amplitude, ub=amplitude, uc=amplitude)def _set_interharmonic_phase_voltage_output(self, phase_id, frequency, phi=0, u=0, inter_h=None):# 设置某一相位的间谐波电流输出self._generic_interharmonic_output(outputType='VOLTAGE', phase_id=phase_id, frequency=frequency, amp=u, phi=phi, inter_h=inter_h)def set_interharmonic_voltage_output(self, frequency, phi_a=0, phi_b=-120, phi_c=120, ua=0, ub=0, uc=0, inter_h_a=None, inter_h_b=None, inter_h_c=None):# 设置间谐波电压输出(3个相位)self._set_interharmonic_phase_voltage_output(phase_id=1, frequency=frequency, phi=phi_a, u=ua, inter_h=inter_h_a)self._set_interharmonic_phase_voltage_output(phase_id=2, frequency=frequency, phi=phi_b, u=ub, inter_h=inter_h_b)self._set_interharmonic_phase_voltage_output(phase_id=3, frequency=frequency, phi=phi_c, u=uc, inter_h=inter_h_c)def _set_flicker_phase_voltage_output(self, phase_id, frequency, phi=0, u=0, shap=None, depth=None, freq=None, unit=None):# 设置某一相位的闪变电压信号输出self._generic_flicker_output(outputType='VOLT', phase_id=phase_id, frequency=frequency, phi=phi, amp=u, shap=shap, depth=depth, freq=freq, unit=unit)def set_flicker_voltage_output(self, frequency, phi_a=0, phi_b=-120, phi_c=120, ua=0, ub=0, uc=0, shap=None, depth=None, freq=None, unit=None):# 设置闪变电压信号输出(3个相位)self._set_flicker_phase_voltage_output(phase_id=1, frequency=frequency, phi=phi_a, u=ua, shap=shap, depth=depth, freq=freq, unit=unit)self._set_flicker_phase_voltage_output(phase_id=2, frequency=frequency, phi=phi_b, u=ub, shap=shap, depth=depth, freq=freq, unit=unit)self._set_flicker_phase_voltage_output(phase_id=3, frequency=frequency, phi=phi_c, u=uc, shap=shap, depth=depth, freq=freq, unit=unit)# endregion# region Current Outputdef _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 set_simple_current_output(self, frequency, amplitude):self.set_current_output(frequency, 0, -120, 120, ia=amplitude, ib=amplitude, ic=amplitude)def _set_interharmonic_phase_current_output(self, phase_id, frequency, phi=0, i=0, inter_h=None):# 设置某一相位的间谐波电流输出self._generic_interharmonic_output(outputType='CURRENT', phase_id=phase_id, frequency=frequency, amp=i, phi=phi, inter_h=inter_h)def set_interhamonic_current_output(self, frequency, phi_a=0, phi_b=-120, phi_c=120, ia=0, ib=0, ic=0, inter_h_a=None, inter_h_b=None, inter_h_c=None):# 设置间谐波电流输出(3个相位)self._set_interharmonic_phase_current_output(phase_id=1, frequency=frequency, phi=phi_a, i=ia, inter_h=inter_h_a)self._set_interharmonic_phase_current_output(phase_id=2, frequency=frequency, phi=phi_b, i=ib, inter_h=inter_h_b)self._set_interharmonic_phase_current_output(phase_id=3, frequency=frequency, phi=phi_c, i=ic, inter_h=inter_h_c)# endregion# region Outputdef activate_output(self):# 正式激活输出self.send_raw_command(command='OUTP:STAT ON')def deactivate_output(self):# 正式关闭输出self.send_raw_command(command='OUTP:STAT OFF')def clear_output(self):self.deactivate_output()#endregionif __name__=='__main__':device= Fluke('GPIB0::18::INSTR')device.send_raw_command(':FREQ 55;:UNIT:MHAR:VOLT ABS;:PHAS1:VOLT:RANG 0,180;STATE ON;MHAR:STAT OFF;CLE;HARM1 22,0')device.activate_output()

写在最后:

好了,其实我们这边写代码是从来不加中文注释的,英文注释也很少很少加,因为加了注释以后代码会显得不美观(没办法,追求细节追求完美的德国小哥的要求),加了注释代码易读,但是不美观;不加注释美观,但是不易读,各有优缺点吧。

为了写这个博客我特意给代码加的注释,大家应该都能看懂哈! 看不懂的私信我,不过我估计国内用python做测试的大豆在互联网行业,用python控硬件设备的同志应该不多。

忘了说,做这个项目主要文档就是Fluke设备的一份英文用户手册,大部分的命令都在手册中,具体实现都是参考这份手册。不过手册在远程控制部分没有中文,所以这个文档很难肯,前后做了两个多月完成!

该项目5月结束,一直没空写文章,今天周五,抽空写个文章,做个记录,留下个痕迹!

2020,再不顺,也要加油!!!努力工作!!努力生活!!

Python使用 Pyvisa库 控制 NI 设备Fluke(详细)相关推荐

  1. Python中sympy库的使用方法(详细)

    Python中sympy库的使用方法(详细) python拥有强大的数学计算能力,Matlab确实有很强的计算能力,但是python在这方面更加灵活,运行速度更快,所以python在这方面拥有较大优势 ...

  2. 基于python pyvisa模块控制GPIB设备识别不到设备资源号问题

    项目场景: 要注意首先安装GPIB的驱动和NI-VISA软件. 使用python控制E4440A频谱分析仪等设备,主要获取测试时的参数,数据保存到某平台报表.但在调试过程中主要遇到控制最大的问题就是找 ...

  3. 【测试】Python手机自动化测试库uiautomator2和weditor的详细使用

    1.说明 我们之前在电脑操作手机进行自动化测试,基本上都是通过Appium的,这个工具确实强大,搭配谷歌官方的UiAutomator基本上可以完成各种测试,但缺点也很明显,配置环境太麻烦了,需要jdk ...

  4. python的api库_python 利用toapi库自动生成api

    在学习做接口测试自动化的时候,我们往往会自己动手写一些简单的API,比如写一个简单的TODO API之类. 不过自己写API的时候经常需要造一些假数据,以及处理分页逻辑,开始的时候还觉得比较有意思,但 ...

  5. python如何安装wordcloud_基于python的wordcloud库的安装方法

    基于python的wordcloud是最近十分流行的一项技术,而在学习这门技术之前,一定要学会安装.下面给大家介绍一下wordcloud的安装步骤. Tip: python第三方组件有很多都是whl文 ...

  6. python硬件库网址_python dev安装包 Python安装第三方库 - 硬件设备 - 服务器之家

    python dev安装包 Python安装第三方库 发布时间:2017-05-10 来源:服务器之家 Ubuntu 12.04 LTS 默认安装Python 2.7.3,没有安装python-dev ...

  7. python拼音怎么写-Python 中拼音库 PyPinyin 的用法

    [摘要] 最近碰到了一个问题,项目中很多文件都是接手过来的中文命名的一些素材,结果在部署的时候文件名全都乱码了,导致项目无法正常运行. 后来请教了一位大佬怎么解决文件名乱码的问题,他说这个需要正面解决 ...

  8. Python 中拼音库 PyPinyin 的用法,没错见名知意它就是用来翻译汉字的

    最近碰到了一个问题,项目中很多文件都是接手过来的中文命名的一些素材,结果在部署的时候文件名全都乱码了,导致项目无法正常运行. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基 ...

  9. python常用第三方库(转载)

    Python标准库与第三方库详解(转载) 转载地址: http://www.codeweblog.com/python%e6%a0%87%e5%87%86%e5%ba%93%e4%b8%8e%e7%a ...

最新文章

  1. Centos7Yum安装Mysql8
  2. 自学python数据分析要多久-如果只有1小时学Python,看这篇就够了
  3. RegionServer宕机的原因
  4. oracle之 11g RAC R2 体系结构---Grid
  5. stm32_can错误中断 清除重点
  6. 全球最权威人脸识别测试,中国团队依图科技夺得第一
  7. jquery事件 on(),live(),delegate(),blind()
  8. 微信小程序 promise 化
  9. webstorm license key
  10. C++ STL 一个简单的stack程序
  11. 2021年软件测试工具总结——单元测试工具
  12. 为什么有的计算机没有ppt,电脑上没有ppt怎么办
  13. 矢量图标库Font Awesome的SVG新版本图标库5.x
  14. python图像平移,Python 图像扩充之旋转、平移、缩放、裁剪
  15. 第九章 姜小白大难不死登君位 公子纠迟来一步梦成空
  16. Sketch掌握常用快捷键提升工作效率
  17. 谷歌又在开发新AI框架!这次瞄准的是:通用人工智能(AGI)
  18. 如何查询快递单号物流
  19. Celery 分发任务
  20. java多线程12:阻塞队列Queue

热门文章

  1. Airbnb暂停中国境内服务 中国民宿市场消化15万房源
  2. 360如何清理注册表
  3. amcharts的使用介绍
  4. 百度云c++语言模拟器,Android模拟器中运行纯C++程序(一)
  5. 【学习资源】光学、物理类、电子学实验合集
  6. 数学杂记(1)一些无处安放的数学推导
  7. Android Launcher或 ROM开发,系统级别的应用(系统功能),ROM裁剪
  8. el-upload编辑时回显图片
  9. Java程序设计(二)
  10. L1-049 天梯赛座位分配 (Python)