diff --git a/lppinstru/Agilent_34410A.py b/lppinstru/Agilent_34410A.py new file mode 100644 --- /dev/null +++ b/lppinstru/Agilent_34410A.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Simple python library to communicate with Agilent 34410A over USB-TMC. +""" +import time +import sys +import os +import agilenttmc + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Development" + +class Agilent3441xA(usbtmc.UsbTmc): + def __init__(self,ref,serial=""): + isnt=usbtmc.findInstrument(ref,serial) + if inst=="": + raise UserWarning("Can't find instrument "+ref) + self.UsbTmc.__init__(isnt) diff --git a/lppinstru/__init__.py b/lppinstru/__init__.py --- a/lppinstru/__init__.py +++ b/lppinstru/__init__.py @@ -7,4 +7,4 @@ __version__ = "1.0.0" __maintainer__ = "Alexis Jeandet" __email__ = "alexis.jeandet@member.fsf.org" -__status__ = "Production" +__status__ = "Development" diff --git a/lppinstru/agilent3441xA.py b/lppinstru/agilent3441xA.py new file mode 100644 --- /dev/null +++ b/lppinstru/agilent3441xA.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Simple python library to communicate with Agilent 34410A over USB-TMC. +""" +import time +import sys +import os +import agilenttmc + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Development" + +"34410A" + +class Agilent3441xA(agilentusbtmc.AgilentUsbTmc): + def __init__(self,serial=""): + isnt=usbtmc.findInstrument("3441[0-1]A",serial) + if inst=="": + raise UserWarning("Can't find instrument "+ref) + self.UsbTmc.__init__(isnt) diff --git a/lppinstru/agilenttmc.py b/lppinstru/agilenttmc.py new file mode 100644 --- /dev/null +++ b/lppinstru/agilenttmc.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Common Agilent USB-TMC/SCPI traits. +""" +import time +import sys +import os +import usbtmc + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Development" + +class AgilentUsbTmc(usbtmc.UsbTmc): + def __init__(self,ref,serial=""): + isnt=usbtmc.findInstrument(ref,serial) + if inst=="": + raise UserWarning("Can't find instrument "+ref) + self.UsbTmc.__init__(isnt) diff --git a/lppinstru/discovery.py b/lppinstru/discovery.py --- a/lppinstru/discovery.py +++ b/lppinstru/discovery.py @@ -1,331 +1,333 @@ -#!/usr/bin/env python -#-*- coding: utf-8 -*- -"""Simple python library to drive the analog discovery module from www.digilentinc.com -""" - -from ctypes import * -import time -import sys -import os -import matplotlib.pyplot as plt -import numpy as np - -__author__ = "Alexis Jeandet" -__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" -__credits__ = [] -__license__ = "GPLv2" -__version__ = "1.0.0" -__maintainer__ = "Alexis Jeandet" -__email__ = "alexis.jeandet@member.fsf.org" -__status__ = "Production" - - -nodev = c_int(0) -DwfStateDone = c_int(2) - -DECIAnalogInChannelCount = c_int(1) -DECIAnalogOutChannelCount = c_int(2) -DECIAnalogIOChannelCount = c_int(3) -DECIDigitalInChannelCount = c_int(4) -DECIDigitalOutChannelCount = c_int(5) -DECIDigitalIOChannelCount = c_int(6) -DECIAnalogInBufferSize = c_int(7) -DECIAnalogOutBufferSize = c_int(8) -DECIDigitalInBufferSize = c_int(9) -DECIDigitalOutBufferSize = c_int(10) - -trigsrcNone = c_byte(0) -trigsrcPC = c_byte(1) -trigsrcDetectorAnalogIn = c_byte(2) -trigsrcDetectorDigitalIn = c_byte(3) -trigsrcAnalogIn = c_byte(4) -trigsrcDigitalIn = c_byte(5) -trigsrcDigitalOut = c_byte(6) -trigsrcAnalogOut1 = c_byte(7) -trigsrcAnalogOut2 = c_byte(8) -trigsrcAnalogOut3 = c_byte(9) -trigsrcAnalogOut4 = c_byte(10) -trigsrcExternal1 = c_byte(11) -trigsrcExternal2 = c_byte(12) -trigsrcExternal3 = c_byte(13) -trigsrcExternal4 = c_byte(14) -trigAuto = c_byte(254) -trigNormal = c_byte(255) - -AnalogOutNodeCarrier = c_int(0) -AnalogOutNodeFM = c_int(1) -AnalogOutNodeAM = c_int(2) - - -shapes = {'DC' : 0, - 'Sine' : 1, - 'Square' : 2, - 'Triangle' : 3, - 'RampUp' : 4, - 'RampDown' : 5, - 'Noise' : 6, - 'Custom' : 30, - 'Play' :31, } - -closed=False -opened=True - - -class discoveryLimits(): - class limitRange(): - def __init__(self,Min,Max,name="Unknow",unit=""): - self.Min = Min - self.Max = Max - self.name = name - self.unit = unit - - def conform(self,value): - if valueself.Max: - raise UserWarning("Parameter "+self.name+" out of bound\nValue="+str(value)+"\nForce to "+str(self.Max)) - return self.Max - return value - - def printme(self): - print(self.name + ":\n Min="+str(self.Min)+" "+self.unit+",Max="+str(self.Max)+" "+self.unit) - - errors = {0: RuntimeError("No card opened"), - 1: UserWarning("Parameter out of bound"), - } - def __init__(self,libdwf,hdwf): - self.limits=[] - self.ACQ_IN_RANGES=[0.0] - if hdwf.value == nodev.value: - return - self.__hdwf=hdwf - self.__libdwf=libdwf - Mind=c_double() - Maxd=c_double() - Mini=c_int() - Maxi=c_int() - StepsCount=c_int() - Steps=(c_double*32)() - self.__libdwf.FDwfAnalogInBufferSizeInfo(self.__hdwf, byref(Mini), byref(Maxi)) - self.ACQ_BUF=self.limitRange(Mini.value,Maxi.value,"ACQ Buffer Size","Sps") - self.limits.append(self.ACQ_BUF) - self.__libdwf.FDwfAnalogInFrequencyInfo(self.__hdwf, byref(Mind), byref(Maxd)) - self.ACQ_FREQ=self.limitRange(Mind.value,Maxd.value,"ACQ Frequency","Hz") - self.limits.append(self.ACQ_FREQ) - self.__libdwf.FDwfAnalogInChannelRangeSteps(self.__hdwf, byref(Steps), byref(StepsCount)) - self.ACQ_IN_RANGES=Steps[0:StepsCount.value] - self.__libdwf.FDwfAnalogOutNodeAmplitudeInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, -byref(Mind), byref(Maxd)) - self.GEN_AMPL=self.limitRange(Mind.value,Maxd.value,"GEN Amplitude","V") - self.limits.append(self.GEN_AMPL) - self.__libdwf.FDwfAnalogOutNodeFrequencyInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, -byref(Mind), byref(Maxd)) - self.GEN_FREQ=self.limitRange(Mind.value,Maxd.value,"GEN Frequency","Hz") - self.limits.append(self.GEN_FREQ) - self.__libdwf.FDwfAnalogOutNodeOffsetInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, -byref(Mind), byref(Maxd)) - self.GEN_OFFSET=self.limitRange(Mind.value,Maxd.value,"GEN Offset","V") - self.limits.append(self.GEN_OFFSET) - self.__libdwf.FDwfAnalogOutNodeDataInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, -byref(Mini), byref(Maxi)) - self.GEN_BUFF=self.limitRange(Mini.value,Maxi.value,"GEN Buffer size","Sps") - self.limits.append(self.GEN_BUFF) - - - def __conformParam(self,minVal,maxVal,val): - if valmaxVal: - raise self.errors.get(1) - print("Force to "+str(maxVal)) - return maxVal - return val - - def acqFreq(self, value): - return self.ACQ_FREQ.conform(value) - - def acqBufSize(self, value): - return self.ACQ_BUF.conform(value) - - def genFreq(self, value): - return self.GEN_FREQ.conform(value) - - def genAmplitude(self, value): - return self.GEN_AMPL.conform(value) - - def genOffset(self, value): - return self.GEN_OFFSET.conform(value) - - def genBuffSize(self, value): - return self.GEN_BUFF.conform(value) - - def printme(self): - for i in self.limits: - i.printme() - print("ACQ Input ranes: "+str(self.ACQ_IN_RANGES)) - - -class discovery(): - - errors = {0: RuntimeError("No card opened"), - 1: UserWarning("Parameter out of bound"), - } - def __init__(self,card=-1): - if sys.platform.startswith("win"): - self.__libdwf = cdll.dwf - elif sys.platform.startswith("darwin"): - self.__libdwf = cdll.LoadLibrary("libdwf.dylib") - else: - self.__libdwf = cdll.LoadLibrary("libdwf.so") - self.__opened = True - self.__hdwf = c_int() - self.__libdwf.FDwfDeviceOpen(c_int(card), byref(self.__hdwf)) - if self.__hdwf.value == nodev.value: - szerr = create_string_buffer(512) - self.__libdwf.FDwfGetLastErrorMsg(szerr) - print(szerr.value) - print("failed to open device") - self.__opened=False - self.__limits=discoveryLimits(self.__libdwf,self.__hdwf) - self.__limits.printme() - - @property - def opened(self): - return self.__opened - - -############################################################# -# Power Supply -############################################################# - def setPower(self,fiveVolt=1,minusFiveVolt=1,master=True): - if not self.__opened: - raise self.errors.get(0) - # enable positive supply - self.__libdwf.FDwfAnalogIOChannelNodeSet(self.__hdwf, 0, 0, c_double(fiveVolt)) - # enable negative supply - self.__libdwf.FDwfAnalogIOChannelNodeSet(self.__hdwf, 1, 0, c_double(minusFiveVolt)) - # master enable - return self.__libdwf.FDwfAnalogIOEnableSet(self.__hdwf, master) - - def getPower(self): - if not self.__opened: - raise self.errors.get(0) - supplyVoltage = c_double() - supplyCurrent = c_double() - IsEnabled = c_bool() - self.__libdwf.FDwfAnalogIOStatus(self.__hdwf) - self.__libdwf.FDwfAnalogIOChannelNodeStatus(self.__hdwf, c_int(3), c_int(0), byref(supplyVoltage)) - self.__libdwf.FDwfAnalogIOChannelNodeStatus(self.__hdwf, c_int(3), c_int(1), byref(supplyCurrent)) - self.__libdwf.FDwfAnalogIOEnableStatus(self.__hdwf, byref(IsEnabled)) - return [IsEnabled.value,supplyVoltage.value,supplyCurrent.value] - -############################################################# -# AnalogIn -############################################################# - def analogInRead(self,ch1=True,ch2=True,frequency=100000000,samplesCount=100,ch1range=5.0,ch2range=5.0,trigger=trigsrcNone): - if not self.__opened: - raise self.errors.get(0) - cnt=self.__limits.acqBufSize(samplesCount) - self.__libdwf.FDwfAnalogInFrequencySet(self.__hdwf, c_double(self.__limits.acqFreq(frequency))) - f=c_double() - self.__libdwf.FDwfAnalogInFrequencyGet(self.__hdwf, byref(f)) - frequency=f.value - self.__libdwf.FDwfAnalogInBufferSizeSet(self.__hdwf, c_int(cnt)) - self.__libdwf.FDwfAnalogInChannelEnableSet(self.__hdwf, c_int(0), c_bool(ch1)) - self.__libdwf.FDwfAnalogInChannelRangeSet(self.__hdwf, c_int(0), c_double(ch1range)) - self.__libdwf.FDwfAnalogInChannelEnableSet(self.__hdwf, c_int(1), c_bool(ch2)) - self.__libdwf.FDwfAnalogInChannelRangeSet(self.__hdwf, c_int(1), c_double(ch2range)) - self.setAnaloInTrigger(trigger) - self.__libdwf.FDwfAnalogInConfigure(self.__hdwf, c_bool(False), c_bool(True)) - status = c_byte() - while True: - self.__libdwf.FDwfAnalogInStatus(self.__hdwf, c_int(1), byref(status)) - if status.value == DwfStateDone.value : - break - time.sleep(0.1) - if ch1: - ch1data = (c_double*cnt)() - self.__libdwf.FDwfAnalogInStatusData(self.__hdwf, 0, ch1data, cnt) - if ch2: - ch2data = (c_double*cnt)() - self.__libdwf.FDwfAnalogInStatusData(self.__hdwf, 1, ch2data, cnt) - return [np.array([ch1data,ch2data]),frequency] - else: - return [np.array([ch1data]),frequency] - if ch2: - ch2data = (c_double*cnt)() - self.__libdwf.FDwfAnalogInStatusData(self.__hdwf, 1, ch2data, cnt) - return [np.array([ch2data]),frequency] - - - def setAnaloInTrigger(self,trigger=trigAuto,autoTimeout=0.0): - if not self.__opened: - raise self.errors.get(0) - if trigger == trigAuto: - self.__libdwf.FDwfAnalogInTriggerSourceSet(self.__hdwf,trigsrcDetectorAnalogIn) - self.__libdwf.FDwfAnalogInTriggerAutoTimeoutSet(self.__hdwf,c_double(autoTimeout)) - return - if trigger == trigNormal: - self.__libdwf.FDwfAnalogInTriggerSourceSet(self.__hdwf,trigsrcDetectorAnalogIn) - self.__libdwf.FDwfAnalogInTriggerAutoTimeoutSet(self.__hdwf,c_double(0.0)) - return - self.__libdwf.FDwfAnalogInTriggerSourceSet(self.__hdwf,trigger) - -############################################################# -# AnalogOut -############################################################# - def analogOutGen(self,frequency=1000, shape='Sine', channel=0, amplitude=1.0, offset=0.0): - self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(False)) - self.__libdwf.FDwfAnalogOutNodeEnableSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_bool(True)) - self.__libdwf.FDwfAnalogOutNodeFunctionSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_int(shapes.get(shape))) - self.__libdwf.FDwfAnalogOutNodeFrequencySet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genFreq(frequency))) - self.__libdwf.FDwfAnalogOutNodeAmplitudeSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genAmplitude(amplitude))) - self.__libdwf.FDwfAnalogOutNodeOffsetSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genOffset(offset))) - self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(True)) - - def analogOutGenArbit(self,samplesBuffer ,repeatingFrequency=100, channel=0, amplitude=1.0, offset=0.0): - self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(False)) - cnt=self.__limits.genBuffSize(len(samplesBuffer)) - buf=(c_double*cnt)() - buf[:]=samplesBuffer[0:cnt] - repeatingFrequency = self.__limits.genFreq(repeatingFrequency*cnt)/cnt - self.__libdwf.FDwfAnalogOutNodeEnableSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_bool(True)) - self.__libdwf.FDwfAnalogOutNodeFunctionSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_int(shapes.get("Custom"))) - self.__libdwf.FDwfAnalogOutNodeFrequencySet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(repeatingFrequency)) - self.__libdwf.FDwfAnalogOutNodeAmplitudeSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genAmplitude(amplitude))) - self.__libdwf.FDwfAnalogOutNodeOffsetSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genOffset(offset))) - self.__libdwf.FDwfAnalogOutNodeDataSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, buf, c_int(cnt)) - self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(True)) - - - def __del__(self): - if self.__opened: - self.__libdwf.FDwfDeviceClose(self.__hdwf) - - - - -if __name__ == '__main__': - print("open first dev") - test = discovery() - test.setPower() - for i in range(2): - time.sleep(0.2) - print(test.getPower()) - test.analogOutGen() - res=test.analogInRead(frequency=1000000,samplesCount=1000) - print(res) - plt.plot(range(len(res[0][0])),res[0][0]) - plt.plot(range(len(res[0][0])),res[0][1]) - plt.show() - test.temp() -# del test - quit() - - - - - +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Simple python library to drive the analog discovery module from www.digilentinc.com +""" + +from ctypes import * +import time +import sys +import os +import matplotlib.pyplot as plt +import numpy as np + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Production" + + +nodev = c_int(0) +DwfStateDone = c_int(2) + +DECIAnalogInChannelCount = c_int(1) +DECIAnalogOutChannelCount = c_int(2) +DECIAnalogIOChannelCount = c_int(3) +DECIDigitalInChannelCount = c_int(4) +DECIDigitalOutChannelCount = c_int(5) +DECIDigitalIOChannelCount = c_int(6) +DECIAnalogInBufferSize = c_int(7) +DECIAnalogOutBufferSize = c_int(8) +DECIDigitalInBufferSize = c_int(9) +DECIDigitalOutBufferSize = c_int(10) + +trigsrcNone = c_byte(0) +trigsrcPC = c_byte(1) +trigsrcDetectorAnalogIn = c_byte(2) +trigsrcDetectorDigitalIn = c_byte(3) +trigsrcAnalogIn = c_byte(4) +trigsrcDigitalIn = c_byte(5) +trigsrcDigitalOut = c_byte(6) +trigsrcAnalogOut1 = c_byte(7) +trigsrcAnalogOut2 = c_byte(8) +trigsrcAnalogOut3 = c_byte(9) +trigsrcAnalogOut4 = c_byte(10) +trigsrcExternal1 = c_byte(11) +trigsrcExternal2 = c_byte(12) +trigsrcExternal3 = c_byte(13) +trigsrcExternal4 = c_byte(14) +trigAuto = c_byte(254) +trigNormal = c_byte(255) + +AnalogOutNodeCarrier = c_int(0) +AnalogOutNodeFM = c_int(1) +AnalogOutNodeAM = c_int(2) + + +shapes = {'DC' : 0, + 'Sine' : 1, + 'Square' : 2, + 'Triangle' : 3, + 'RampUp' : 4, + 'RampDown' : 5, + 'Noise' : 6, + 'Custom' : 30, + 'Play' :31, } + +closed=False +opened=True + + +class DiscoveryLimits(): + class limitRange(): + def __init__(self,Min,Max,name="Unknow",unit=""): + self.Min = Min + self.Max = Max + self.name = name + self.unit = unit + + def conform(self,value): + if valueself.Max: + raise UserWarning("Parameter "+self.name+" out of bound\nValue="+str(value)+"\nForce to "+str(self.Max)) + return self.Max + return value + + def __str__(self): + return self.name + ":\n Min="+str(self.Min)+" "+self.unit+",Max="+str(self.Max)+" "+self.unit + + errors = {0: RuntimeError("No card opened"), + 1: UserWarning("Parameter out of bound"), + } + def __init__(self,libdwf,hdwf): + self.limits=[] + self.ACQ_IN_RANGES=[0.0] + if hdwf.value == nodev.value: + return + self.__hdwf=hdwf + self.__libdwf=libdwf + Mind=c_double() + Maxd=c_double() + Mini=c_int() + Maxi=c_int() + StepsCount=c_int() + Steps=(c_double*32)() + self.__libdwf.FDwfAnalogInBufferSizeInfo(self.__hdwf, byref(Mini), byref(Maxi)) + self.ACQ_BUF=self.limitRange(Mini.value,Maxi.value,"ACQ Buffer Size","Sps") + self.limits.append(self.ACQ_BUF) + self.__libdwf.FDwfAnalogInFrequencyInfo(self.__hdwf, byref(Mind), byref(Maxd)) + self.ACQ_FREQ=self.limitRange(Mind.value,Maxd.value,"ACQ Frequency","Hz") + self.limits.append(self.ACQ_FREQ) + self.__libdwf.FDwfAnalogInChannelRangeSteps(self.__hdwf, byref(Steps), byref(StepsCount)) + self.ACQ_IN_RANGES=Steps[0:StepsCount.value] + self.__libdwf.FDwfAnalogOutNodeAmplitudeInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, +byref(Mind), byref(Maxd)) + self.GEN_AMPL=self.limitRange(Mind.value,Maxd.value,"GEN Amplitude","V") + self.limits.append(self.GEN_AMPL) + self.__libdwf.FDwfAnalogOutNodeFrequencyInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, +byref(Mind), byref(Maxd)) + self.GEN_FREQ=self.limitRange(Mind.value,Maxd.value,"GEN Frequency","Hz") + self.limits.append(self.GEN_FREQ) + self.__libdwf.FDwfAnalogOutNodeOffsetInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, +byref(Mind), byref(Maxd)) + self.GEN_OFFSET=self.limitRange(Mind.value,Maxd.value,"GEN Offset","V") + self.limits.append(self.GEN_OFFSET) + self.__libdwf.FDwfAnalogOutNodeDataInfo(self.__hdwf,c_int(0), AnalogOutNodeCarrier, +byref(Mini), byref(Maxi)) + self.GEN_BUFF=self.limitRange(Mini.value,Maxi.value,"GEN Buffer size","Sps") + self.limits.append(self.GEN_BUFF) + + + def __conformParam(self,minVal,maxVal,val): + if valmaxVal: + raise self.errors.get(1) + print("Force to "+str(maxVal)) + return maxVal + return val + + def acqFreq(self, value): + return self.ACQ_FREQ.conform(value) + + def acqBufSize(self, value): + return self.ACQ_BUF.conform(value) + + def genFreq(self, value): + return self.GEN_FREQ.conform(value) + + def genAmplitude(self, value): + return self.GEN_AMPL.conform(value) + + def genOffset(self, value): + return self.GEN_OFFSET.conform(value) + + def genBuffSize(self, value): + return self.GEN_BUFF.conform(value) + + def __str__(self): + res=str() + for i in self.limits: + res+=i.__str__()+"\n" + res+="ACQ Input ranes: "+str(self.ACQ_IN_RANGES) + return res + + +class Discovery(): + + errors = {0: RuntimeError("No card opened"), + 1: UserWarning("Parameter out of bound"), + } + def __init__(self,card=-1): + if sys.platform.startswith("win"): + self.__libdwf = cdll.dwf + elif sys.platform.startswith("darwin"): + self.__libdwf = cdll.LoadLibrary("libdwf.dylib") + else: + self.__libdwf = cdll.LoadLibrary("libdwf.so") + self.__opened = True + self.__hdwf = c_int() + self.__libdwf.FDwfDeviceOpen(c_int(card), byref(self.__hdwf)) + if self.__hdwf.value == nodev.value: + szerr = create_string_buffer(512) + self.__libdwf.FDwfGetLastErrorMsg(szerr) + print(szerr.value) + print("failed to open device") + self.__opened=False + self.__limits=DiscoveryLimits(self.__libdwf,self.__hdwf) + print(self.__limits) + + @property + def opened(self): + return self.__opened + + +############################################################# +# Power Supply +############################################################# + def set_power(self,fiveVolt=1,minusFiveVolt=1,master=True): + if not self.__opened: + raise self.errors.get(0) + # enable positive supply + self.__libdwf.FDwfAnalogIOChannelNodeSet(self.__hdwf, 0, 0, c_double(fiveVolt)) + # enable negative supply + self.__libdwf.FDwfAnalogIOChannelNodeSet(self.__hdwf, 1, 0, c_double(minusFiveVolt)) + # master enable + return self.__libdwf.FDwfAnalogIOEnableSet(self.__hdwf, master) + + def get_power(self): + if not self.__opened: + raise self.errors.get(0) + supplyVoltage = c_double() + supplyCurrent = c_double() + IsEnabled = c_bool() + self.__libdwf.FDwfAnalogIOStatus(self.__hdwf) + self.__libdwf.FDwfAnalogIOChannelNodeStatus(self.__hdwf, c_int(3), c_int(0), byref(supplyVoltage)) + self.__libdwf.FDwfAnalogIOChannelNodeStatus(self.__hdwf, c_int(3), c_int(1), byref(supplyCurrent)) + self.__libdwf.FDwfAnalogIOEnableStatus(self.__hdwf, byref(IsEnabled)) + return [IsEnabled.value,supplyVoltage.value,supplyCurrent.value] + +############################################################# +# AnalogIn +############################################################# + def analog_in_read(self,ch1=True,ch2=True,frequency=100000000,samplesCount=100,ch1range=5.0,ch2range=5.0,trigger=trigsrcNone): + if not self.__opened: + raise self.errors.get(0) + cnt=self.__limits.acqBufSize(samplesCount) + self.__libdwf.FDwfAnalogInFrequencySet(self.__hdwf, c_double(self.__limits.acqFreq(frequency))) + f=c_double() + self.__libdwf.FDwfAnalogInFrequencyGet(self.__hdwf, byref(f)) + frequency=f.value + self.__libdwf.FDwfAnalogInBufferSizeSet(self.__hdwf, c_int(cnt)) + self.__libdwf.FDwfAnalogInChannelEnableSet(self.__hdwf, c_int(0), c_bool(ch1)) + self.__libdwf.FDwfAnalogInChannelRangeSet(self.__hdwf, c_int(0), c_double(ch1range)) + self.__libdwf.FDwfAnalogInChannelEnableSet(self.__hdwf, c_int(1), c_bool(ch2)) + self.__libdwf.FDwfAnalogInChannelRangeSet(self.__hdwf, c_int(1), c_double(ch2range)) + self.set_analog_in_trigger(trigger) + self.__libdwf.FDwfAnalogInConfigure(self.__hdwf, c_bool(False), c_bool(True)) + status = c_byte() + while True: + self.__libdwf.FDwfAnalogInStatus(self.__hdwf, c_int(1), byref(status)) + if status.value == DwfStateDone.value : + break + time.sleep(0.1) + if ch1: + ch1data = (c_double*cnt)() + self.__libdwf.FDwfAnalogInStatusData(self.__hdwf, 0, ch1data, cnt) + if ch2: + ch2data = (c_double*cnt)() + self.__libdwf.FDwfAnalogInStatusData(self.__hdwf, 1, ch2data, cnt) + return [np.array([ch1data,ch2data]),frequency] + else: + return [np.array([ch1data]),frequency] + if ch2: + ch2data = (c_double*cnt)() + self.__libdwf.FDwfAnalogInStatusData(self.__hdwf, 1, ch2data, cnt) + return [np.array([ch2data]),frequency] + + + def set_analog_in_trigger(self,trigger=trigAuto,autoTimeout=0.0): + if not self.__opened: + raise self.errors.get(0) + if trigger == trigAuto: + self.__libdwf.FDwfAnalogInTriggerSourceSet(self.__hdwf,trigsrcDetectorAnalogIn) + self.__libdwf.FDwfAnalogInTriggerAutoTimeoutSet(self.__hdwf,c_double(autoTimeout)) + return + if trigger == trigNormal: + self.__libdwf.FDwfAnalogInTriggerSourceSet(self.__hdwf,trigsrcDetectorAnalogIn) + self.__libdwf.FDwfAnalogInTriggerAutoTimeoutSet(self.__hdwf,c_double(0.0)) + return + self.__libdwf.FDwfAnalogInTriggerSourceSet(self.__hdwf,trigger) + +############################################################# +# AnalogOut +############################################################# + def analog_out_gen(self,frequency=1000, shape='Sine', channel=0, amplitude=1.0, offset=0.0): + self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(False)) + self.__libdwf.FDwfAnalogOutNodeEnableSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_bool(True)) + self.__libdwf.FDwfAnalogOutNodeFunctionSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_int(shapes.get(shape))) + self.__libdwf.FDwfAnalogOutNodeFrequencySet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genFreq(frequency))) + self.__libdwf.FDwfAnalogOutNodeAmplitudeSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genAmplitude(amplitude))) + self.__libdwf.FDwfAnalogOutNodeOffsetSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genOffset(offset))) + self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(True)) + + def analog_out_gen_arbit(self,samplesBuffer ,repeatingFrequency=100, channel=0, amplitude=1.0, offset=0.0): + self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(False)) + cnt=self.__limits.genBuffSize(len(samplesBuffer)) + buf=(c_double*cnt)() + buf[:]=samplesBuffer[0:cnt] + repeatingFrequency = self.__limits.genFreq(repeatingFrequency*cnt)/cnt + self.__libdwf.FDwfAnalogOutNodeEnableSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_bool(True)) + self.__libdwf.FDwfAnalogOutNodeFunctionSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_int(shapes.get("Custom"))) + self.__libdwf.FDwfAnalogOutNodeFrequencySet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(repeatingFrequency)) + self.__libdwf.FDwfAnalogOutNodeAmplitudeSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genAmplitude(amplitude))) + self.__libdwf.FDwfAnalogOutNodeOffsetSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, c_double(self.__limits.genOffset(offset))) + self.__libdwf.FDwfAnalogOutNodeDataSet(self.__hdwf, c_int(channel), AnalogOutNodeCarrier, buf, c_int(cnt)) + self.__libdwf.FDwfAnalogOutConfigure(self.__hdwf, c_int(channel), c_bool(True)) + + + def __del__(self): + if self.__opened: + self.__libdwf.FDwfDeviceClose(self.__hdwf) + + + + +if __name__ == '__main__': + print("open first dev") + test = Discovery() + test.set_power() + for i in range(2): + time.sleep(0.2) + print(test.get_power()) + test.analog_out_gen() + res=test.analog_in_read(frequency=1000000,samplesCount=1000) + print(res) + plt.plot(range(len(res[0][0])),res[0][0]) + plt.plot(range(len(res[0][0])),res[0][1]) + plt.show() + test.temp() +# del test + quit() + + + + + diff --git a/lppinstru/gpd_xxx.py b/lppinstru/gpd_xxx.py --- a/lppinstru/gpd_xxx.py +++ b/lppinstru/gpd_xxx.py @@ -1,128 +1,126 @@ -#-*- coding: utf-8 -*- -#Copyright 2015 Alexis Jeandet -#This file is part of lppinstru. - -#lppinstru is free software: you can redistribute it and/or modify -#it under the terms of the GNU General Public License as published by -#the Free Software Foundation, either version 3 of the License, or -#(at your option) any later version. - -#pydiscovery is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with pydiscovery. If not, see . -import time -import sys -import os -import matplotlib.pyplot as plt -import numpy as np -import serial - -class gpd_xxx(): - conf = {"GPD-3303S" : (2,0.0,30.0), - "GPD-3303" : (), - } - trackingMode = {"Independent" : '0', - "Series" : '1', - "Parallel" : '2', - } - trackingModeStat = {"01": "Independent", - "11" : "Series", - "10" : "Parallel", - } - def __init__(self,port): - self.i=0 - self.__port=serial.Serial(port,timeout=0.5) - - def idn(self): - self.__port.setTimeout(0.1) - self.__port.write(b"*IDN?\n") - return self.__port.readall() - - def setVoltage(self,index,tension): - if index < 2: - self.__port.write("VSET"+str(index+1)+":"+str(tension)+"\n") - else: - raise UserWarning("Parameter out of bound") - - def voltageSet(self,index): - if index < 2: - self.__port.setTimeout(0.1) - self.__port.write("VSET"+str(index+1)+"?\n") - V=self.__port.readall() - return float(V.split("V")[0]) - else: - raise UserWarning("Parameter out of bound") - - def voltage(self,index): - if index < 2: - self.__port.setTimeout(0.1) - self.__port.write("VOUT"+str(index+1)+"?\n") - V=self.__port.readall() - return float(V.split("V")[0]) - else: - raise UserWarning("Parameter out of bound") - - def setCurrentLimit(self,index,limit): - if index < 2: - self.__port.write("ISET"+str(index+1)+":"+str(limit)+"\n") - else: - raise UserWarning("Parameter out of bound") - - def currentLimit(self,index): - if index < 2: - self.__port.setTimeout(0.1) - self.__port.write("ISET"+str(index+1)+"?\n") - I = self.__port.readall() - return float(I.split("A")[0]) - else: - raise UserWarning("Parameter out of bound") - - def current(self,index): - if index < 2: - self.__port.setTimeout(0.1) - self.__port.write("IOUT"+str(index+1)+"?\n") - I = self.__port.readall() - return float(I.split("A")[0]) - else: - raise UserWarning("Parameter out of bound") - - def turnOn(self,on=True): - if on: - self.__port.write("OUT1\n") - else: - self.__port.write("OUT0\n") - - def setTracking(self,mode="Independent"): - self.__port.write("TRACK"+self.trackingMode.get(mode)+"\n") - - def setBeep(self,on=True): - if on: - self.__port.write("BEEP1\n") - else: - self.__port.write("BEEP0\n") - - def tracking(self): - self.__port.write("STATUS?\n") - self.__port.setTimeout(0.1) - STAT = self.__port.readall() - BITS = STAT.split(" ") - return self.trackingModeStat.get(''.join(BITS[2:4])) - - def save(self,mem=1): - if mem>=1 and mem<=4: - self.__port.write("SAV"+str(mem)+"\n") - else: - raise UserWarning("Parameter mem of bound 1-4") - - def recal(self,mem=1): - if mem>=1 and mem<=4: - self.__port.write("RCL"+str(mem)+"\n") - else: - raise UserWarning("Parameter mem of bound 1-4") - -if __name__ == '__main__': - print("") +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Simple python library to communicate with GW Instek GPD-Series power supplies. +""" +import time +import sys +import os +import matplotlib.pyplot as plt +import numpy as np +import serial + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Development" + + +class gpd_xxx(): + conf = {"GPD-3303S" : (2,0.0,30.0), + "GPD-3303" : (), + } + trackingMode = {"Independent" : '0', + "Series" : '1', + "Parallel" : '2', + } + trackingModeStat = {"01": "Independent", + "11" : "Series", + "10" : "Parallel", + } + def __init__(self,port): + self.i=0 + self.__port=serial.Serial(port,timeout=0.5) + + def idn(self): + self.__port.setTimeout(0.1) + self.__port.write(b"*IDN?\n") + return self.__port.readall() + + def setVoltage(self,index,tension): + if index < 2: + self.__port.write("VSET"+str(index+1)+":"+str(tension)+"\n") + else: + raise UserWarning("Parameter out of bound") + + def voltageSet(self,index): + if index < 2: + self.__port.setTimeout(0.1) + self.__port.write("VSET"+str(index+1)+"?\n") + V=self.__port.readall() + return float(V.split("V")[0]) + else: + raise UserWarning("Parameter out of bound") + + def voltage(self,index): + if index < 2: + self.__port.setTimeout(0.1) + self.__port.write("VOUT"+str(index+1)+"?\n") + V=self.__port.readall() + return float(V.split("V")[0]) + else: + raise UserWarning("Parameter out of bound") + + def setCurrentLimit(self,index,limit): + if index < 2: + self.__port.write("ISET"+str(index+1)+":"+str(limit)+"\n") + else: + raise UserWarning("Parameter out of bound") + + def currentLimit(self,index): + if index < 2: + self.__port.setTimeout(0.1) + self.__port.write("ISET"+str(index+1)+"?\n") + I = self.__port.readall() + return float(I.split("A")[0]) + else: + raise UserWarning("Parameter out of bound") + + def current(self,index): + if index < 2: + self.__port.setTimeout(0.1) + self.__port.write("IOUT"+str(index+1)+"?\n") + I = self.__port.readall() + return float(I.split("A")[0]) + else: + raise UserWarning("Parameter out of bound") + + def turnOn(self,on=True): + if on: + self.__port.write("OUT1\n") + else: + self.__port.write("OUT0\n") + + def setTracking(self,mode="Independent"): + self.__port.write("TRACK"+self.trackingMode.get(mode)+"\n") + + def setBeep(self,on=True): + if on: + self.__port.write("BEEP1\n") + else: + self.__port.write("BEEP0\n") + + def tracking(self): + self.__port.write("STATUS?\n") + self.__port.setTimeout(0.1) + STAT = self.__port.readall() + BITS = STAT.split(" ") + return self.trackingModeStat.get(''.join(BITS[2:4])) + + def save(self,mem=1): + if mem>=1 and mem<=4: + self.__port.write("SAV"+str(mem)+"\n") + else: + raise UserWarning("Parameter mem of bound 1-4") + + def recal(self,mem=1): + if mem>=1 and mem<=4: + self.__port.write("RCL"+str(mem)+"\n") + else: + raise UserWarning("Parameter mem of bound 1-4") + +if __name__ == '__main__': + print("") diff --git a/lppinstru/transfertFunction.py b/lppinstru/transfertFunction.py --- a/lppinstru/transfertFunction.py +++ b/lppinstru/transfertFunction.py @@ -1,71 +1,71 @@ -#!/usr/bin/env python -#-*- coding: utf-8 -*- -"""Simple python library to compute transfert functions -""" -import time -import sys -import os -import matplotlib.pyplot as plt -import numpy as np -from scipy import fftpack - -__author__ = "Alexis Jeandet" -__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" -__credits__ = [] -__license__ = "GPLv2" -__version__ = "1.0.0" -__maintainer__ = "Alexis Jeandet" -__email__ = "alexis.jeandet@member.fsf.org" -__status__ = "Production" - - - -def __parseFFT(FFTi,FFTo,signalFreq,samplingFreq): - index=signalFreq*len(FFTi)/samplingFreq - powI=np.abs(FFTi[index-4:index+4]) - i=np.argmax(powI)+index-4 - mod=np.abs(FFTo[i])/np.abs(FFTi[i]) - arg=np.angle(FFTo[i])-np.angle(FFTi[i]) - if arg<-np.pi: - arg = (np.pi*2)+arg - if arg>np.pi: - arg = (-np.pi*2)+arg - return [signalFreq,mod,arg] - -def __step(device,freq,offset=0.0,maxAmp=5.0,lastAmp=1.0): - device.analogOutGen(freq, shape='Sine', channel=0, amplitude=lastAmp, offset=offset) - samplesCount=8192 - if freq > 500000: - FS=freq*samplesCount/500.0 - elif freq > 100000: - FS=freq*samplesCount/50.0 - else: - FS=freq*samplesCount/10.0 - res=device.analogInRead(ch1=True,ch2=True,frequency=FS,samplesCount=samplesCount,ch1range=5.0,ch2range=5.0) - FFTi=fftpack.fft(res[0][0]) - FFTo=fftpack.fft(res[0][1]) - return __parseFFT(FFTi,FFTo,freq,res[1]) - - -def computeTF(device,startFreq=1.0,stopFreq=100.0,offset=0.0,maxAmp=5.0,nstep=100): - freq=np.zeros(nstep) - f=[] - mod=[] - arg=[] - for i in range(int(nstep)) : - freq[i]=startFreq*np.power(10,((np.log10(stopFreq/startFreq))*i/(nstep-1))) - lastAmp=0.1 - for i in range(len(freq)): - step=__step(device,freq[i],offset=offset,maxAmp=maxAmp,lastAmp=lastAmp) - f.append(step[0]) - mod.append(step[1]) - arg.append(step[2]) - return [f,mod,arg] - - -if __name__ == '__main__': - print("") - - - - +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Simple python library to compute transfert functions +""" +import time +import sys +import os +import matplotlib.pyplot as plt +import numpy as np +from scipy import fftpack + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Development" + + + +def __parseFFT(FFTi,FFTo,signalFreq,samplingFreq): + index=signalFreq*len(FFTi)/samplingFreq + powI=np.abs(FFTi[index-4:index+4]) + i=np.argmax(powI)+index-4 + mod=np.abs(FFTo[i])/np.abs(FFTi[i]) + arg=np.angle(FFTo[i])-np.angle(FFTi[i]) + if arg<-np.pi: + arg = (np.pi*2)+arg + if arg>np.pi: + arg = (-np.pi*2)+arg + return [signalFreq,mod,arg] + +def __step(device,freq,offset=0.0,maxAmp=5.0,lastAmp=1.0): + device.analog_out_gen(freq, shape='Sine', channel=0, amplitude=lastAmp, offset=offset) + samplesCount=8192 + if freq > 500000: + FS=freq*samplesCount/500.0 + elif freq > 100000: + FS=freq*samplesCount/50.0 + else: + FS=freq*samplesCount/10.0 + res=device.analog_in_read(ch1=True,ch2=True,frequency=FS,samplesCount=samplesCount,ch1range=5.0,ch2range=5.0) + FFTi=fftpack.fft(res[0][0]) + FFTo=fftpack.fft(res[0][1]) + return __parseFFT(FFTi,FFTo,freq,res[1]) + + +def computeTF(device,startFreq=1.0,stopFreq=100.0,offset=0.0,maxAmp=5.0,nstep=100): + freq=np.zeros(nstep) + f=[] + mod=[] + arg=[] + for i in range(int(nstep)) : + freq[i]=startFreq*np.power(10,((np.log10(stopFreq/startFreq))*i/(nstep-1))) + lastAmp=0.1 + for i in range(len(freq)): + step=__step(device,freq[i],offset=offset,maxAmp=maxAmp,lastAmp=lastAmp) + f.append(step[0]) + mod.append(step[1]) + arg.append(step[2]) + return [f,mod,arg] + + +if __name__ == '__main__': + print("") + + + + diff --git a/lppinstru/usbtmc.py b/lppinstru/usbtmc.py new file mode 100644 --- /dev/null +++ b/lppinstru/usbtmc.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +#-*- coding: utf-8 -*- +"""Simple python library to communicate over USB-TMC protocol with linux's + usbtmc module. +""" +import time +import sys +import os +import glob +import re + +__author__ = "Alexis Jeandet" +__copyright__ = "Copyright 2015, Laboratory of Plasma Physics" +__credits__ = [] +__license__ = "GPLv2" +__version__ = "1.0.0" +__maintainer__ = "Alexis Jeandet" +__email__ = "alexis.jeandet@member.fsf.org" +__status__ = "Development" + + +def find_instrument(ref,serial=""): + instruments=glob.glob("/dev/usbtmc[0-9]") + p = re.compile(ref) + for instrument in instruments: + dev=UsbTmc(instrument) + idn=dev.idn().split(",") + if p.match(idn[1]): + if serial=="" or serial == idn[2]: + return instrument + return "" + +class UsbTmc(): + def __init__(self,dev): + self.__PATH__=dev + self.__FILE__ = os.open(dev, os.O_RDWR) + if self.__FILE__==-1: + raise UserWarning("can't open "+dev) + self.Manufacturer="" + self.Reference="" + self.Serial="" + self.Version="" + + def write(self, command): + os.write(self.__FILE__, command); + + def read(self, length = 4000): + return os.read(self.__FILE__, length) + + def idn(self): + self.write("*IDN?") + return self.read(100) + + def __str__(self): + return self.idn() +"\n"+ self.__PATH__