Skip to content

Commit

Permalink
Merge pull request heeres#3 from ggdeboo/master
Browse files Browse the repository at this point in the history
Ipython version detection update and new drivers
heeres committed Jun 2, 2015
2 parents 9ef1eac + f436f9f commit d2f3118
Showing 16 changed files with 3,470 additions and 45 deletions.
4 changes: 2 additions & 2 deletions INSTALL
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ B) other programs.
scipy has many math routines (like fitting), based on numpy.
URL: scipy.org (for both numpy and scipy)

3a) ipython (>=0.10)
3a) ipython (>=1.0.0)
3b) pyreadline (>=1.5)

enhanced interactive shell for python
@@ -58,7 +58,7 @@ B) other programs.
libraries used for creating graphical interfaces.
URL: pygtk.org

5) pyvisa (1.3)
5) pyvisa (1.3, < 1.6)

library for communication with GPIB/USB/SERIAL instruments
URL: pyvisa.sourceforge.net/
4 changes: 4 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
QT Lab environment

requirements:
IPython ≥ 1.0.0
pyVISA < 1.5
220 changes: 220 additions & 0 deletions instrument_plugins/Agilent_81180A.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Agilent_81180A.py class, to perform the communication between the Wrapper and the device
# Pablo Asshoff, Dec. 2013
#
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
import visa
import types
import logging
import numpy

class Agilent_81180A(Instrument):
'''
This is the driver for the Agilent_81180A Signal Genarator
Usage:
Initialize with
<name> = instruments.create('<name>', 'Agilent_81180A', address='<GBIP address>, reset=<bool>')
'''

def __init__(self, name, address, reset=False):
'''
Initializes the Agilent_81180A, and communicates with the wrapper.
Input:
name (string) : name of the instrument
address (string) : GPIB address
reset (bool) : resets to default values, default=False
'''
logging.info(__name__ + ' : Initializing instrument Agilent_81180A')
Instrument.__init__(self, name, tags=['physical'])

# Add some global constants
self._address = address
self._visainstrument = visa.instrument(self._address)

self.add_parameter('channel',
flags=Instrument.FLAG_GETSET, units='', type=types.IntType)
self.add_parameter('output',
flags=Instrument.FLAG_GETSET, units='', type=types.StringType)
self.add_parameter('frequency',
flags=Instrument.FLAG_GETSET, units='Hz', minval=1e5, maxval=20e9, type=types.FloatType)
self.add_parameter('voltage',
flags=Instrument.FLAG_GETSET, units='V', minval=0.05, maxval=0.5, type=types.FloatType)


self.add_function('reset')
self.add_function ('get_all')


if (reset):
self.reset()
else:
self.get_all()

def reset(self):
'''
Resets the instrument to default values
Input:
None
Output:
None
'''
logging.info(__name__ + ' : resetting instrument')
self._visainstrument.write('*RST\n')
self.get_all()

def get_all(self):
'''
Reads all implemented parameters from the instrument,
and updates the wrapper.
Input:
None
Output:
None
'''
logging.info(__name__ + ' : get all')
self.get_channel()
self.get_output()
#self.get_power()
#self.get_phase()
self.get_frequency()


def do_set_channel(self, channelnumber):
'''
Set the active channel
Input:
channel (integer) : 1 or 2
Output:
None
'''
logging.debug(__name__ + ' : set active channel: %i' % channelnumber)
self._visainstrument.write('INST:SEL %i \n' % channelnumber)

def do_get_channel(self):
'''
Reads the active channel from the instrument
Input:
None
Output:
Active Channel : 1 or 2
'''
logging.debug(__name__ + ' : active channel')
return int(self._visainstrument.ask('INST:SEL?\n'))

def do_set_output(self, on_off):
'''
Set the active channel
Input:
on or off (str) :
Output:
None
'''
logging.debug(__name__ + ' : set output of active channel: %s' % on_off)
self._visainstrument.write('OUTP:STAT %s\n' % on_off)

def do_get_output(self):
'''
Reads weather the output is on or off from the instrument
Input:
None
Output:
On or Off (1/0)
'''
logging.debug(__name__ + ' : output is on or off')
return str(self._visainstrument.ask('OUTP:STAT?\n'))


def do_set_frequency(self, freq):
'''
Set the frequency of the instrument
Input:
freq (float) : Frequency in Hz
Output:
None
'''
logging.debug(__name__ + ' : set frequency to %f' % freq)
self._visainstrument.write('SOUR:FREQ %f\n' % freq)


def do_get_frequency(self):
'''
Reads the frequency of the signal from the instrument
Input:
None
Output:
freq (float) : Frequency in Hz
'''
logging.debug(__name__ + ' : get frequency')
return float(self._visainstrument.ask('SOUR:FREQ?\n'))







def do_set_voltage(self, volt):
'''
Set the voltage of the instrument
Input:
volt (float) : voltage in V
Output:
None
'''
logging.debug(__name__ + ' : set vooltage to %f' % volt)
self._visainstrument.write('SOUR:VOLT %f\n' % volt)


def do_get_frequency(self):
'''
Reads the voltage setting from the instrument
Input:
None
Output:
volt (float) : voltage in V
'''
logging.debug(__name__ + ' : get voltage')
return float(self._visainstrument.ask('SOUR:VOLT?\n'))







412 changes: 412 additions & 0 deletions instrument_plugins/Agilent_8648C.py

Large diffs are not rendered by default.

262 changes: 262 additions & 0 deletions instrument_plugins/Agilent_8753E2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
# Agilent_8753E2.py class, to perform the communication between the Wrapper and the device
# Pablo Asshoff <techie@gmx.de>, 2013
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
import visa
import types
import logging
import numpy
import math

class Agilent_8753E2(Instrument):
'''
This is the driver for the Agilent 8753E2 Network Analyzer
Usage:
Initialize with
<name> = instruments.create('name', 'Agilent_8753E2', address='<GPIB address>',
reset=<bool>)
'''

def __init__(self, name, address, reset=False):
'''
Initializes the Agilent_8753E2, and communicates with the wrapper.
Input:
name (string) : name of the instrument
address (string) : GPIB address
reset (bool) : resets to default values, default=false
Output:
None
'''
logging.info(__name__ + ' : Initializing instrument')
Instrument.__init__(self, name, tags=['physical'])

self._address = address
self._visainstrument = visa.instrument(self._address)
self._visainstrument.timeout = 1

# Add parameters
self.add_parameter('startfrequency', type=types.FloatType,
flags=Instrument.FLAG_GETSET | Instrument.FLAG_GET_AFTER_SET,
minval=9e3, maxval=6e9,
units='Hz', format='%.04e')
self.add_parameter('stopfrequency', type=types.FloatType,
flags=Instrument.FLAG_GETSET | Instrument.FLAG_GET_AFTER_SET,
minval=9e3, maxval=6e9,
units='Hz', format='%.04e')
self.add_parameter('span', type=types.FloatType,
flags=Instrument.FLAG_GETSET | Instrument.FLAG_GET_AFTER_SET,
minval=0, maxval=3e9,
units='Hz', format='%.04e')

# Add functions
self.add_function('reset')
self.add_function('get_all')
self.add_function('read_trace')
# self.add_function('plot_trace')
# self.add_function('save_trace')

if reset:
self.reset()
else:
self.get_all()

# Functions
def reset(self):
'''
Resets the instrument to default values
Input:
None
Output:
None
'''
logging.info(__name__ + ' : Resetting instrument')
self._visainstrument.write('*RST;*CLS') # zuvor nur *RST
self.get_all()

def get_all(self):
'''
Reads all implemented parameters from the instrument,
and updates the wrapper.
Input:
None
Output:
None
'''
logging.info(__name__ + ' : reading all settings from instrument')
self.get_startfrequency()
self.get_stopfrequency()
self.get_span()

def read_trace(self):
'''
Read a trace
p.427 Manual
Input:
None
Output:
trace
'''
logging.debug(__name__ + ' : performing trace readout')
#self._visainstrument.write('OPC?;SING;')
#only use previous command if single sweep is required, not for readout of display as is.
self._visainstrument.write('FORM4;')
return(self._visainstrument.ask('OUTPFORM;'))

# def plot_trace(self,trace):
# '''
# plot the trace returned from read_trace()
# p.427 Manual
#
# Input:
# Trace
#
# Output:
# trace
# '''
# array1 = trace
# array2 = array1.replace('E','e')
# array2 = array2.replace('\n',',')
# array3 = numpy.fromstring(array2, sep=',')
# y = array3[::2]
# startfreq = self.get_startfrequency()
# stopfreq = self.get_stopfrequency()
# steps = (stopfreq-startfreq)/(len(y)-1)
# x = arange(startfreq,stopfreq+0.001,steps)
# qt.Plot2D(x,y)
#
# def save_trace(self,trace,filename):
# '''
# plot the trace returned from read_trace()
# p.427 Manual
#
# Input:
# Trace
#
# Output:
# trace
# '''
# #convert data returned from instrument:
# array1 = trace
# array2 = array1.replace('E','e')
# array2 = array2.replace('\n',',')
# array3 = numpy.fromstring(array2, sep=',')
# y = array3[::2]
# startfreq = self.get_startfrequency()
# stopfreq = self.get_stopfrequency()
# steps = (stopfreq-startfreq)/(len(y)-1)
# x = arange(startfreq,stopfreq+0.001,steps)
# qt.Plot2D(x,y)
# #create a file and save trace:
# f = open(filename, 'w')
# f.write('frequency[Hz] power[dB]')
# for i in range(len(x)):
# f.write(str(x[i]))
# f.write(' ')
# f.write(str(y[i]))
# f.write('\n')
# f.close()

# communication with machine
def do_get_startfrequency(self):
'''
Get start frequency from device
Input:
None
Output:
startfrequency (float) : start frequency in Hz
'''
logging.debug(__name__ + ' : reading start frequency from instrument')
return float(self._visainstrument.ask('STAR?;'))

def do_set_startfrequency(self, startfrequency):
'''
Set start frequency of device
Input:
startfrequency (float) : start frequency in Hz
Output:
None
'''
logging.debug(__name__ + ' : setting start frequency to %s GHz' % startfrequency)
self._visainstrument.write('STAR; %e' % startfrequency)
#self._visainstrument.write('STAR; %e MHZ;' % startfrequency)

def do_get_stopfrequency(self):
'''
Get stop frequency from device
Input:
None
Output:
stopfrequency (float) : stop frequency in Hz
'''
logging.debug(__name__ + ' : reading stop frequency from instrument')
return float(self._visainstrument.ask('STOP?;'))

def do_set_stopfrequency(self, stopfrequency):
'''
Set stop frequency of device
Input:
stopfrequency (float) : stop frequency in Hz
Output:
None
'''
logging.debug(__name__ + ' : setting stop frequency to %s GHz' % stopfrequency)
self._visainstrument.write('STOP; %e' % stopfrequency)
#self._visainstrument.write('STAR; %e MHZ;' % startfrequency)

def do_get_span(self):
'''
Get span from device
Input:
None
Output:
span (float) : span in Hz
'''
logging.debug(__name__ + ' : reading span from instrument')
return float(self._visainstrument.ask('SPAN?;'))

def do_set_span(self,span):
'''
Set span of device
Input:
span (float) : span in Hz
Output:
None
'''
logging.debug(__name__ + ' : setting span to %s Hz' % span)
self._visainstrument.write('SPAN; %e' % span)

92 changes: 92 additions & 0 deletions instrument_plugins/Bristol_621.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Bristol_621.py - Instrument plugin to communicate with a Bristol 621
# wavelengthmeter
# Gabriele de Boo <g.deboo@student.unsw.edu.au>
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
import types
import logging
from ctypes import *

CLDevIFace = cdll.CLDevIFace

CLOpenUSBSerialDevice = CLDevIFace.CLOpenUSBSerialDevice
CLOpenUSBSerialDevice.restype = c_long
CLCloseDevice = CLDevIFace.CLCloseDevice
CLSetLambdaUnits = CLDevIFace.CLSetLambdaUnits
CLSetLambdaUnits.restype = c_int
CLGetLambdaReading = CLDevIFace.CLGetLambdaReading
CLGetLambdaReading.restype = c_double
CLGetPowerReading = CLDevIFace.CLGetPowerReading
CLGetPowerReading.restype = c_float

class Bristol_621(Instrument):
'''Bristol 621 Wavelength meter'''

def __init__(self, name, address=None, reset=False):
Instrument.__init__(self,name)
self.devHandle = CLOpenUSBSerialDevice(c_long(address))
logging.info('Device handle of Bristol wavemeter is %s' % self.devHandle)
# Set wavelength reading to nm
CLSetLambdaUnits(c_int(self.devHandle), c_uint(0))

self.add_parameter('wavelength',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='nm')
# self.add_parameter('frequency',
# type=types.FloatType,
# flags=Instrument.FLAG_GET,
# units='THz')
self.add_parameter('power',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='mW')

self.add_function('close_device')

if reset:
self.reset()
else:
self.get_all()

#### initialization related

def reset(self):
print __name__ + ' : resetting instrument'

def get_all(self):
print __name__ + ' : reading all settings from instrument'
self.get_wavelength()
self.get_power()

#### communication with machine

def do_get_wavelength(self):
wavelength = None
while wavelength == None:
wavelength = CLGetLambdaReading(c_int(self.devHandle))
logging.debug('Measured wavelength is %s.' % wavelength)
return wavelength

def do_get_power(self):
power = CLGetPowerReading(c_int(self.devHandle))
logging.debug('Measured power is %s.' % power)
return power

def close_device(self):
if (CLCloseDevice(c_int(self.devHandle)) != 0):
logging.warning('%s: Closing device was unsuccesfull.' % self.name)
83 changes: 83 additions & 0 deletions instrument_plugins/Delta_PSC232.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Delta_PSC232.py driver for the PSC232 Delta Power Supply Controller
# Gabriele de Boo <g.deboo@student.unsw.edu.au>, 2012
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
import types
import visa

class Delta_PSC232(Instrument):

def __init__(self, name, address=None, channel=1):
Instrument.__init__(self, name, tags=['measure'])

self._address = address
# self._term_chars = '\n\r\x04'
self._channel = channel
self._visains = visa.instrument(address) #, term_chars = "\n\r\x04") # Hoo Rah
self._visains.baud_rate = 4800L
self._visains.write("*R") # Reset the instrument
self._visains.write("CH "+str(channel)) # Talking to the correct instrument

self.add_parameter('Minimum_Voltage', type=types.FloatType,
flags=Instrument.FLAG_SET | Instrument.FLAG_SOFTGET)
self.add_parameter('Maximum_Voltage', type=types.FloatType,
flags=Instrument.FLAG_SET | Instrument.FLAG_SOFTGET)
self.add_parameter('Minimum_Current', type=types.FloatType,
flags=Instrument.FLAG_SET | Instrument.FLAG_SOFTGET)
self.add_parameter('Maximum_Current', type=types.FloatType,
flags=Instrument.FLAG_SET | Instrument.FLAG_SOFTGET)
self.add_parameter('Voltage', type=types.FloatType,
flags=Instrument.FLAG_GETSET)
self.add_parameter('Current', type=types.FloatType,
flags=Instrument.FLAG_GETSET)

# self.add_function('set_defaults')
self.set_defaults()

def set_defaults(self):
'''Set default parameters.'''
self.set_Minimum_Voltage(0)
self.set_Maximum_Voltage(30)
self.set_Minimum_Current(0)
self.set_Maximum_Current(5)
self._visains.write("REMOTE")

def do_set_Minimum_Voltage(self, minvol):
self._visains.write("SOUR:VOLT:MIN " + str(minvol))

def do_set_Maximum_Voltage(self, maxvol):
self._visains.write("SOUR:VOLT:MAX " + str(maxvol))

def do_set_Minimum_Current(self, mincur):
self._visains.write("SOUR:CURR:MIN " + str(mincur))

def do_set_Maximum_Current(self, maxcur):
self._visains.write("SOUR:CURR:MAX " + str(maxcur))

def do_set_Voltage(self, V):
self._visains.write("SOU:VOLT " + str(V))

def do_set_Current(self, I):
self._visains.write("SOU:CURR " + str(I))

def do_get_Voltage(self):
# return self._remove_EOT(self._visains.ask("MEAS:VOLT?"))
return float(self._visains.ask("MEAS:VOLT?"))

def do_get_Current(self):
return float(self._visains.ask("MEAS:CURR?"))

254 changes: 254 additions & 0 deletions instrument_plugins/HP_3325B.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
# HP_3325B.py class, to perform the communication between the Wrapper and the device
# Gabriele de Boo <ggdeboo@gmail.com> 2014
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
from visa import instrument
import types
import logging
from time import sleep

class HP_3325B(Instrument):
'''
This is the python driver for the HP 3325B
synthesizer
Usage:
Initialize with
<name> = instruments.create('<name>', 'HP_33120A', address='<GPIB address>',
reset=<bool>)
'''

def __init__(self, name, address, reset=False):
'''
Initializes the HP_3325B, and communicates with the wrapper.
Our model doesn't have the high voltage option so I didn't add the use
of that option in this wrapper.
Input:
name (string) : name of the instrument
address (string) : GPIB address
reset (bool) : resets to default values, default=false
Output:
None
'''
Instrument.__init__(self, name, tags=['physical'])

self._address = address
self._visainstrument = instrument(self._address)

self.add_parameter('frequency',
type=types.FloatType,
flags=Instrument.FLAG_GETSET,
minval=0.0, maxval=60.999999e6,
units='Hz')
self.add_parameter('amplitude',
type=types.FloatType,
flags=Instrument.FLAG_GETSET,
minval=0.001, maxval=40.0,
units='V')
self.add_parameter('offset',
type=types.FloatType,
flags=Instrument.FLAG_GETSET,
minval=-5.0, maxval=5.0,
units='V')
self.add_parameter('connected_output',
type=types.StringType,
flags=Instrument.FLAG_GETSET,
option_list=['front','rear'])
self.add_parameter('function',
type=types.StringType,
flags=Instrument.FLAG_GETSET,
option_list=['DC','sine','square','triangle','positive ramp','negative ramp'])
self.add_parameter('amplitude_modulation_status',
type=types.BooleanType,
flags=Instrument.FLAG_GET)

self.add_function('reset')
self.add_function('get_all')

if reset:
self.reset()
else:
self.get_all()

def get_all(self):
self.get_frequency()
self.get_connected_output()
self.get_amplitude()
self.get_offset()
self.get_function()
self.get_amplitude_modulation_status()

def reset(self):
logging.info(__name__ + ' : Resetting instrument')
self._visainstrument.write('*RST')
sleep(0.1)
self.get_all()

# Parameters

def do_set_frequency(self, freq):
'''
Sets the frequency. Uses Hz.
'''
logging.debug(__name__ + ' : Setting frequency')
self._visainstrument.write('FR%8.3fHZ' % freq)

def do_get_frequency(self):
logging.debug(__name__ + ' : Getting frequency')
response = self._visainstrument.ask('IFR')
if response[-2:] == 'HZ':
freq = response[2:-2]
elif response[-2:] == 'KH':
freq = response[2:-2]*1e3
elif response[-2:] == 'MH':
freq = response[2:-2]*1e6
else:
logging.warning(__name__ + ' : Response incorrect.')
return False
return float(freq)

def do_set_amplitude(self, amp):
logging.debug(__name__ + ' : Setting amplitude')
self._visainstrument.write('AM%5.6fVO' % amp)

def do_get_amplitude(self):
'''
Gets the amplitude in V.
'''
logging.debug(__name__ + ' : Getting amplitude')
response = self._visainstrument.ask('IAM')
if not response.startswith('AM'):
logging.warning(__name__ + ' : Wrong response.')
raise ValueError('Response from instrument was wrong.')
amp = response[2:-2]
if response[-2:] == 'VO':
return amp
elif response[-2:] == 'MV':
return amp*1000
# elif response[-2:] == 'DB':
# elif response[-2:] == 'DV':

def do_set_offset(self, amp):
logging.debug(__name__ + ' : Setting amplitude')
self._visainstrument.write('OF%5.6fVO' % amp)

def do_get_offset(self):
'''
Gets the amplitude in V.
'''
logging.debug(__name__ + ' : Getting amplitude')
response = self._visainstrument.ask('IOF')
if not response.startswith('OF'):
logging.warning(__name__ + ' : Wrong response.')
raise ValueError('Response from instrument was wrong.')
amp = response[2:-2]
if response[-2:] == 'VO':
return amp
elif response[-2:] == 'MV':
return amp*1000

def do_get_connected_output(self):
logging.debug(__name__ + ' : Getting which output is connected.')
response = self._visainstrument.ask('IRF')
if response == 'RF1':
return 'front'
elif response == 'RF2':
return 'rear'
else:
logging.warning(__name__ + ' : Response incorrect.')
return False

def do_set_connected_output(self, output):
'''
Options are 'front' and 'rear'.
'''
logging.debug(__name__ + ' : Setting the connected output to %s.' % output)
if output == 'FRONT':
self._visainstrument.write('RF1')
else:
self._visainstrument.write('RF2')

def do_get_function(self):
'''
Get the current waveform function of the instrument.
options are:
'DC'
'sine'
'square'
'triangle'
'positive ramp'
'negative ramp'
'''
logging.debug(__name__ + ' : Getting the waveform function.')
response = self._visainstrument.ask('IFU')
if not response.startswith('FU'):
logging.warning(__name__ + ' : Wrong response.')
raise ValueError('Response from instrument was wrong.')
if response[2] == '0':
return 'DC'
elif response[2] == '1':
return 'sine'
elif response[2] == '2':
return 'square'
elif response[2] == '3':
return 'triangle'
elif response[2] == '4':
return 'positive ramp'
elif response[2] == '5':
return 'negative ramp'

def do_set_function(self, function):
'''
Set the current waveform function of the instrument.
options are:
'DC'
'sine'
'square'
'triangle'
'positive ramp'
'negative ramp'
'''
logging.debug(__name__ + ' : Setting the waveform function to %s.' % function)
if function == 'DC':
self._visainstrument.write('FU0')
if function == 'SINE':
self._visainstrument.write('FU1')
if function == 'SQUARE':
self._visainstrument.write('FU2')
if function == 'TRIANGLE':
self._visainstrument.write('FU3')
if function == 'POSITIVE RAMP':
self._visainstrument.write('FU4')
if function == 'NEGATIVE RAMP':
self._visainstrument.write('FU5')

def do_get_amplitude_modulation_status(self):
'''
Get the amplitude modulation status.
Returns True or False
'''
logging.debug(__name__ + ' : Getting the amplitude modulation status.')
response = self._visainstrument.ask('IMA')
if not response.startswith('MA'):
logging.warning(__name__ + ' : Wrong response.')
raise ValueError('Response from instrument was wrong.')
if response[2] == '0':
return False
if response[2] == '1':
return True
86 changes: 86 additions & 0 deletions instrument_plugins/HighFinesse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# HighFinesse.py - Instrument plugin to communicate with a High Finesse
# wavelengthmeter
# Gabriele de Boo <g.deboo@student.unsw.edu.au>
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
import types
from ctypes import *

wlmData = windll.wlmData

GetWvl = wlmData.GetWavelength
GetWvl.restype = c_double
GetFrq = wlmData.GetFrequency
GetFrq.restype = c_double
GetLw = wlmData.GetLinewidth
GetLw.restype = c_double
GetPwr = wlmData.GetPowerNum
GetPwr.restype = c_double

class HighFinesse(Instrument):
'''High Finesse Wavelength meter'''

def __init__(self, name, reset=False):
Instrument.__init__(self,name)

self.add_parameter('wavelength',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='nm')
self.add_parameter('frequency',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='THz')
self.add_parameter('linewidth',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='THz')
self.add_parameter('power',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='microW')

if reset:
self.reset()
else:
self.get_all()

#### initialization related

def reset(self):
print __name__ + ' : resetting instrument'

def get_all(self):
print __name__ + ' : reading all settings from instrument'
self.get_wavelength()
self.get_frequency()

#### communication with machine

def do_get_wavelength(self):
Wavelength = GetWvl(c_double(0))
return Wavelength

def do_get_power(self):
return GetPwr(c_long(1), c_double(0))

def do_get_frequency(self):
return GetFrq(c_double(0))

def do_get_linewidth(self):
return GetLw(c_char_p(cReturnFrequency),c_double(0))

287 changes: 287 additions & 0 deletions instrument_plugins/JDSU_SWS15101.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
# JDSU_SWS15101 driver July 4, 2014
#
# Gabriele de Boo <g.deboo@student.unsw.edu.au>
# Chunming Yin <c.yin@unsw.edu.au>
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
import visa
import types
import logging
import numpy
from time import sleep

class JDSU_SWS15101(Instrument):
'''
This is the driver for the JDSU SWS15101 Tunable Laser Source
Usage:
Initialize with
<name> = instruments.create('<name>', 'JDSU_SWS15101', address='<GPIB address>')
'''

def __init__(self, name, address, reset=False):
'''
Input:
name (string) : name of the instrument
address (string) : GPIB address
'''
logging.info(__name__ + ' : Initializing instrument JDSU_SWS15101')
Instrument.__init__(self, name, tags=['physical'])

# Add some global constants
self._address = address
self._visainstrument = visa.instrument(self._address)

self.add_parameter('power',
flags=Instrument.FLAG_GETSET, units='mW', minval=0, maxval=10, type=types.FloatType)
self.add_parameter('diode_current',
flags=Instrument.FLAG_GETSET, units='mA', minval=0, maxval=150, type=types.FloatType)
self.add_parameter('wavelength',
flags=Instrument.FLAG_GETSET, units='nm', minval=1460, maxval=1600, type=types.FloatType)
self.add_parameter('output_status',
flags=Instrument.FLAG_GETSET, type=types.BooleanType)
self.add_parameter('FSCWaveL',
flags=Instrument.FLAG_SET, units='pm', minval=-22.4, maxval=+22.4, type=types.FloatType)

self.add_function ('get_all')

#self.get_all()
def reset(self):
'''
Resets the instrument to default values
Input:
None
Output:
None
'''
logging.info(__name__ + ' : resetting instrument')
self._visainstrument.write('*RST')
self.get_all()

def get_all(self):
'''
Reads all implemented parameters from the instrument,
and updates the wrapper.
Input:
None
Output:
None
'''
logging.info(__name__ + ' : get all')
self.get_power()
self.get_diode_current()
self.get_wavelength()
self.get_output_status()

def do_get_power(self):
'''
Reads the power of the signal from the instrument
Input:
None
Output:
ampl (?) : power in ?
'''
logging.debug(__name__ + ' : get power')
'''return float(self._visainstrument.ask('P?'))
'''
# Make sure that the information in buffer has been read out.
attempt = 0
Stat_word = self._visainstrument.stb
while (Stat_word != 1) and (attempt<10):
self._visainstrument.read()
Stat_word = self._visainstrument.stb
attempt += 1
sleep(0.01)
if attempt >= 10:
logging.warning(__name__ + ' may not be running properly: Status Code %s.' % Stat_word)
self._visainstrument.write('P?')
# Wait until the status word shows the parameter available for reading.
while ((Stat_word & 0b00010000) == 0) and (attempt<100):
Stat_word = self._visainstrument.stb
attempt += 1
sleep(0.01)
if attempt >= 100:
logging.warning(__name__ + ' may not be responding correctly: Status Code %s.' % Stat_word)

P = self._visainstrument.read()
if P == ('DISABLED'):
return 0
elif (P[0] == 'P'):
return float(P[2:])
else:
logging.warning(__name__ + ' did not reply correctly: %s.' % P )
return 0

def do_set_power(self, pow):
'''
Set the power of the signal
Input:
amp (float) : power in ??
Output:
None
'''
logging.debug(__name__ + ' : set power to %f' % pow)
self._visainstrument.write('P=%s' % pow)

def do_get_diode_current(self):
'''
Read the diode current.
'''
logging.debug(__name__ + ' : get diode_current.')
attempt = 0
Stat_word = self._visainstrument.stb
while (Stat_word != 1) and (attempt<10):
self._visainstrument.read()
Stat_word = self._visainstrument.stb
attempt += 1
sleep(0.01)
if attempt >= 10:
logging.warning(__name__ + ' may not be running properly: Status Code %s.' % Stat_word)
self._visainstrument.write('I?')
# Wait until the status word shows the parameter available for reading.
while ((Stat_word & 0b00010000) == 0) and (attempt<100):
Stat_word = self._visainstrument.stb
attempt += 1
sleep(0.01)
if attempt >= 100:
logging.warning(__name__ + ' may not be responding correctly: Status Code %s.' % Stat_word)

I = self._visainstrument.read()
if I == ('DISABLED'):
logging.info(__name__ + ' : Output is disabled.')
return 0
elif (I[0] == 'I'):
return float(I[2:])
else:
logging.warning(__name__ + ' did not reply correctly: %s.' % I )
return 0

def do_set_diode_current(self, curr):
'''
Set the diode current.
'''
logging.debug(__name__ + ' : set diode_current to %.1f.' % curr)
self._visainstrument.write('I=%.1f' % curr)

def do_get_wavelength(self):
'''
Reads the wavelength from the laser
Input:
None
Output:
L (float) : Wavelength in nm
'''
logging.debug(__name__ + ' : get wavelength')
'''return float(self._visainstrument.ask('L?'))
'''
attempt = 0
Stat_word = self._visainstrument.stb
while (Stat_word != 1) and (attempt<10):
self._visainstrument.read()
Stat_word = self._visainstrument.stb
attempt += 1
sleep(0.01)
if attempt >= 10:
logging.warning(__name__ + ' may not be running properly: Status Code %s.' % Stat_word)
self._visainstrument.write('L?')
# Wait until the status word shows the parameter available for reading.
while ((Stat_word & 0b00010000) == 0) and (attempt<100):
Stat_word = self._visainstrument.stb
attempt += 1
sleep(0.01)
if attempt >= 100:
logging.warning(__name__ + ' may not be responding correctly: Status Code %s.' % Stat_word)

L = self._visainstrument.read()


if L == ('DISABLED'):
L = 0
elif (L[0] == 'L'):
return float(L[2:])
else:
logging.warning(__name__ + ' did not reply correctly: %s.' % L )
return 0

def do_set_wavelength(self, wavel):
'''
Set the frequency of the instrument
Input:
freq (float) : Frequency in Hz
Output:
None
'''
logging.debug(__name__ + ' : set wavelength to %f' % wavel)
self._visainstrument.write('L=%s' % wavel)

def do_set_FSCWaveL(self, FSCL):
'''
Set the frequency of the instrument
Input:
freq (float) : Frequency in Hz
Output:
None
'''
logging.debug(__name__ + ' : set FSCwavelength to %f' % FSCL)
self._visainstrument.write('FSCL=%s' % FSCL)

def do_get_output_status(self):
'''
Reads the output status from the instrument
Input:
None
Output:
status (Boolean) : True for 'on' or False for 'off'
'''
logging.debug(__name__ + ' : get status')
P = self.get_power()
if P == 0:
return False
else:
return True

def do_set_output_status(self, status):
'''
Set the output status of the instrument
Input:
status (Boolean) : True or False
Output:
None
'''
logging.debug(__name__ + ' : set status to %s' % status)
if status:
self._visainstrument.write('ENABLE')
else:
self._visainstrument.write('DISABLE')
532 changes: 532 additions & 0 deletions instrument_plugins/RS_FSL6.py

Large diffs are not rendered by default.

613 changes: 613 additions & 0 deletions instrument_plugins/SRS_SG380.py

Large diffs are not rendered by default.

497 changes: 497 additions & 0 deletions instrument_plugins/Superlum_BS_1060.py

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions instrument_plugins/Thorlabs_FiberSwitch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Thorlabs_FiberSwitch.py - Instrument plugin to communicate with
# a Thorlabs Fiberswitch
# Gabriele de Boo <g.deboo@student.unsw.edu.au>
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from instrument import Instrument
from qt import msleep
import logging
from visa import SerialInstrument
import types

class Thorlabs_FiberSwitch(Instrument):
'''
Thorlabs Fiber Switch
The switch is being used to switch between two inputs for a connected
wavemeter. The wavemeter reading should be accessed through this wrapper
so that the correct reading is given for the specified port and because
it will block access during that time for other readings.
When creating the instrument the used wavemeter should be specified.
'''

def __init__(self, name, address, wavemeter, reset=False):
logging.debug('Initializing fiber switch on port %s.' % address)
Instrument.__init__(self, name, tags=['physical'])
self._visainstrument = SerialInstrument(address)
self._visainstrument.baud_rate = 115200
self._visainstrument.term_chars = '\n'

self.wait_time = 0.3
self._wavemeter = wavemeter

self.add_parameter('active_port',
type=types.IntType,
flags=Instrument.FLAG_GETSET,
minval=1, maxval=2)
self.add_parameter('port1_wavelength',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='nm')
self.add_parameter('port2_wavelength',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='nm')
self.add_parameter('port1_power',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='mW')
self.add_parameter('port2_power',
type=types.FloatType,
flags=Instrument.FLAG_GET,
units='mW')

if reset:
self.reset()
else:
self.get_all()

#### initialization related

def reset(self):
print __name__ + ' : resetting instrument'

def get_all(self):
print __name__ + ' : reading all settings from instrument'
self.get_active_port()
self.get_port1_wavelength()
self.get_port1_power()
self.get_port2_wavelength()
self.get_port2_power()

#### communication with machine
def do_get_active_port(self):
return self._visainstrument.ask('S?')

def do_set_active_port(self, port):
self._visainstrument.write('S %i' %port)
if self.get_active_port() == port:
return True
else:
raise Warning('The switch did not reply with the expected port.')

def do_get_port1_wavelength(self):
if self.get_active_port() == 2:
self.set_active_port(1)
msleep(self.wait_time)
return self._wavemeter.get_wavelength()

def do_get_port2_wavelength(self):
if self.get_active_port() == 1:
self.set_active_port(2)
msleep(self.wait_time)
return self._wavemeter.get_wavelength()

def do_get_port1_power(self):
if self.get_active_port()==2:
self.set_active_port(1)
msleep(self.wait_time)
return self._wavemeter.get_power()

def do_get_port2_power(self):
if self.get_active_port()==1:
self.set_active_port(2)
msleep(self.wait_time)
return self._wavemeter.get_power()
4 changes: 2 additions & 2 deletions source/lib/gui/functionframe.py
Original file line number Diff line number Diff line change
@@ -46,8 +46,8 @@ def set_arg_spec(self, argspec):
if argspec is None:
return

names = argspec['args']
defaults = argspec['defaults']
names = argspec.args
defaults = argspec.defaults
for i, name in enumerate(names):
if name in self._exclude:
continue
45 changes: 4 additions & 41 deletions source/lib/misc.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import types
import sys
import time
from IPython import get_ipython

def dict_to_ordered_tuples(dic):
'''Convert a dictionary to a list of tuples, sorted by key.'''
@@ -25,12 +26,6 @@ def get_dict_keys(dic, keys):
ret[key] = dic[key]
return ret

def invert_dict(dic):
ret = {}
for key, val in dic.iteritems():
ret[val] = key
return ret

def seconds_to_str(secs):
'''Convert a number of seconds to hh:mm:ss string.'''
hours = np.floor(secs / 3600)
@@ -100,55 +95,23 @@ def usleep(usec):
while (exact_time() - start) * 1e6 < usec:
pass

def get_ipython():
import IPython
if ipython_is_newer((0, 11)):
return IPython.core.ipapi.get()
else:
return IPython.ipapi.get()

def get_traceback():
if ipython_is_newer((0, 11)):
from IPython.core.ultratb import AutoFormattedTB
else:
from IPython.ultraTB import AutoFormattedTB
from IPython.core.ultratb import AutoFormattedTB
return AutoFormattedTB

def ipython_is_newer(vin):
"""
vin is tuple of version (a,b,c) for version "a.b.c"
result gives True for larger or equal version
"""
import IPython
vs = IPython.__version__.split('.')
for i in range(len(vs)):
if i > (len(vin)-1):
return True
if int(vs[i]) > vin[i]:
return True
elif int(vs[i]) < vin[i]:
return False
return True

def is_ipython():
return get_ipython() != None

def exit_shell():
if is_ipython():
ip = get_ipython()
if ipython_is_newer((0, 11)):
ip.exit() # FIXME This gives annoying request for y/n when called
else:
ip.magic('Exit')
ip.exit() # FIXME This gives annoying request for y/n when called
sys.exit()

def register_exit(func):
if is_ipython():
ip = get_ipython()
if ipython_is_newer((0, 11)):
ip.hooks['shutdown_hook'].add(func, 1)
else:
ip.IP.hooks.shutdown_hook.add(func, 1)
ip.hooks['shutdown_hook'].add(func, 1)
else:
import atexit
atexit.register(func)

0 comments on commit d2f3118

Please sign in to comment.