Skip to content

Commit

Permalink
Merge pull request #2 from amtelford/master
Browse files Browse the repository at this point in the history
Cleaned up my code and added info lines
  • Loading branch information
amtelford authored Jun 4, 2018
2 parents 52ac899 + f2162e9 commit 361bfe8
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 180 deletions.
135 changes: 7 additions & 128 deletions Devices/Dummy_ZA.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@ def __init__(self, address='GPIB::20', name='Dummy ZA', info=None):
if info is not None:
self.info.update(info)

# Opening the device is essential. Here is an example for a VISA-based instrument
# rm = visa.ResourceManager()
# self.device = rm.open_resource("{}".format(address))
##self.device = None

##self.i_range = ['auto', '1e-9 A', '10e-9 A', '100e-9 A', '1e-6 A', '10e-6 A', '100e-6 A', '1e-3 A', '10e-3 A',
## '100e-3 A']
##self.v_range = ['auto', '1.1 V', '11 V']
##self.log_points = ['5', '10', '25', '50']
##self.int_time = ['0.416', '4', '16.67', '20']

def query(self, msg):
""" Send a message to the instrument and then waits for an answer. depending on the nature of the device and
Expand Down Expand Up @@ -66,150 +56,39 @@ def close(self):
pass


def set_za_function(self, function, fixed):
def set_za_function(self, fixed):
""" Sets the functionality of the source, what to bias and how to do it.
:param function: 'dc' or 'sweep', dc or sweep operating function
:param source: 'v' or 'i', voltage or current source
:param fixed: variable indicating whethe rbias or frequency are fixed
:return: None
"""

self.fixed = fixed
#self.function = function


def update_compliance(self, compliance, measRange):
""" Updates the compliance and the measurement range.
:param compliance: current or voltage compliance, oposite to the selected source
:param measRange: the meas range as the index of self.i_range or self.v_range
:return: None
"""

self.compliance = compliance
self.measRange = measRange


def update_integration_time(self, new_time):
""" Sets the integration time.
:param new_time: new integration time as the index from the self.int_time list
:return: None
"""

self.itime = new_time


def update_waiting_time(self, new_time):
""" Sets the delay time between setting a bias and starting a measurement
:param new_time: New delay time in ms.
:return: None
"""
self.delay = new_time


def setup_measurement(self, plot_format, options):
""" Prepares and triggers the IV measurement.
:param function: 'dc' or 'sweep', dc or sweep operating function
:param source: 'v' or 'i' for voltage or current biasing, respectively
:param compliance: meas compliance
:param measRange: the meas range as the index of self.i_range or self.v_range
:param delay: the delay between applying a bias and taking the meas
:param intTime: integration time as the index from the self.int_time list
:return: The measured data
""" Sets up the scan.
"""

##self.set_source_function(function, fixed)
##self.update_compliance(compliance, measRange)
##self.update_integration_time(intTime)
##self.update_waiting_time(delay)

## Setup fixed variable, its value, and the sweep parameters.


def measure(self, options):
""" Prepares and triggers the IV measurement.
:param source: 'v' or 'i' for voltage or current biasing, respectively
:param start: start bias
:param stop: stop bias
:param points: points to measure per decade in current bias mode
:param step: step size in voltage bias mode
:param compliance: meas compliance
:param measRange: the meas range as the index of self.i_range or self.v_range
:param delay: the delay between applying a bias and taking the meas
:param intTime: integration time as the index from the self.int_time list
:return: The estimated measuring time
"""

# First we setup the experiment

# We program the sweep.
# We typically will use the AUTO fixed range for the bias, as it might cover may orders of magnitude


# We estimate the runing time of the sweep, set the timeout time accordingly and return the control to the IV module.
# This will wait in a "safe way" during the measurement, avoiding freezing the program
#self.totalPoints = nop
#minimumWait = 1 ## in ms
#measTime = self.totalPoints * minimumWait
##if self.measRange == 0:
## measTime = measTime * 10
# self.device.timeout = None
#print("Waiting for Dummy.\nEstimated measurement time = {} s".format(measTime / 1000))


# Finally, we trigger the sweep. Depending on the SMU, you might need to turn it on first


#return measTime


##def set_bias(self, biasValue=0.0):
""" Set a bias to the source. If the source is not turned on or the function is not set to 'dc',
the bias will not be applied
:param biasValue: the chosen bias
:return: None
""" Starts the scan.
"""

# First we check that the experiment has been setup for DC bias/meas
##if self.function != 'dc':
## print('DC measurement not setup correctly. Call self.setup_experiment before setting the bias')
## return

# Set the bias in the SMU

# And triger it, if need it


def return_data(self):
""" We get the data fromt he SMU. Depending on the order provided by the SMU we need to invert the output to
have voltage-current, regardless of who is the bias or the meas. We convert the data to an array and re-shape
it in two columns.
""" Generate random data for testing.
:return: the measured data, a tuple with two vectors: voltage and current
:return: the generated data, a tuple with two vectors: voltage and current
"""

# If we are in sweep function, we have to really wait until the meas is finished. In some SMU this is not needed
# as they will not response until they are finished. In others, they don't like to be bothered while measuring.
# Then, we have to turn off the source if not done automatically. In the dc function, the source is turn off externally

totalPoints = 100
# Get the data.
# Here we just simulate some random data. two points for DC or a large number for a sweep
data = np.random.rand(3*totalPoints)
data = np.array(data, dtype=np.float32).reshape((-1, 3))


# Depending of what we are biasing, we might need to invert the order of the output
# We assume in the example that the source produces bias-meas and we want voltage-current, so we invert it
##if self.source == 0:
return data[:, 0], data[:, 1], data[:, 2]
##else:
## return data[:, 1], data[:, 0]


def operate_off(self):
""" Turn off the output of the SMU
Expand Down
66 changes: 24 additions & 42 deletions Devices/KeysightE4990A.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class KeysightE4990A:
"""
Keysight E4990A impedance analyser
Keysight E4990A impedance analyser class
"""
def __init__(self, address='USB0::0x0957::0x1809::MY54101596::0::INSTR', name='Keysight E4990A', info=None):
""" Constructor of the device class. Add here whatever initialisation routing needed by the SMU.
Expand Down Expand Up @@ -71,18 +71,14 @@ def close(self):
self.rm.close()

def setup_measurement(self, plot_format, options):
""" Prepares and triggers the IV measurement.
:param function: 'dc' or 'sweep', dc or sweep operating function
:param source: 'v' or 'i' for voltage or current biasing, respectively
:param compliance: meas compliance
:param measRange: the meas range as the index of self.i_range or self.v_range
:param delay: the delay between applying a bias and taking the meas
:param intTime: integration time as the index from the self.int_time list
:return: The measured data
""" Prepares the measurement by setting up the scan parameters.
:param plot_format: dictionary of setup parameters for plotting the data
:param options: dictionary of setup parameters for the scan
:return: None
"""
## Clear buffer
#self.device.write('*CLS')
self.device.write('*CLS')

## Set DC bias mode to Voltage
self.device.write(':SOURce1:BIAS:MODE %s' % ('VOLTage'))
Expand Down Expand Up @@ -140,9 +136,11 @@ def setup_measurement(self, plot_format, options):
self.device.write(':CALCulate1:PARameter4:DEFine %s' % ('IDC')) ## Trace 4 = IDC

def measure(self, options):
""" Triggers the measurement.
""" Starts and stops the measurement.
:return: None
"""

if options['fixed_value'] != 0:
self.device.write(':SOURce:BIAS:STATe %s' % ('ON'))
self.device.write(':TRIGger:SEQuence:SOURce %s' % ('BUS'))
Expand All @@ -153,12 +151,11 @@ def measure(self, options):
self.device.write(':SOURce:BIAS:STATe %s' % ('OFF'))

def return_data(self):
""" We get the data fromt he SMU. Depending on the order provided by the SMU we need to invert the output to
have voltage-current, regardless of who is the bias or the meas. We convert the data to an array and re-shape
it in two columns.
""" Retrieves the data from the instrument
:return: the measured data, a tuple with two vectors: voltage and current
:return: the measured data, a tuple with three vectors, which depend on the type of measurement performed
"""

## Autoscale all traces
self.device.write(':DISPlay:WINDow1:TRACe1:Y:SCALe:AUTO')
self.device.write(':DISPlay:WINDow1:TRACe2:Y:SCALe:AUTO')
Expand All @@ -175,40 +172,25 @@ def return_data(self):
data = np.column_stack((x_data, Ch1_data, Ch2_data)) ## Aggregate data
return data[:, 0], data[:, 1], data[:, 2]

def operate_off(self):
""" Turn off the output of the SMU
:return: None
"""
pass

def operate_on(self):
""" Turn on the output of the SMU
:return: None
"""
pass

def interface(self, master):
messagebox.showinfo(message='No specific configuration available for {0}'.format(self.info['Name']),
""" Givces error if Mordor cannot locate a configuration file for the instrument.
:return: Error - no configuration available.
"""
messagebox.showinfo(message='No specific configuration available for {0}'.format(self.info['Name']),
detail='Press OK to continue.', title='Device configuration')

def abort_sweep(self):
""" Aborts scan.
:return: None
"""

self.device.write(':ABORt')
self.device.write(':SOURce:BIAS:STATe %s' % ('OFF'))

class New(KeysightE4990A):
""" Standarised name for the KeysightE4990A class"""
pass


#if __name__ == '__main__':
# za = New()
# za.gen_setup()
# za.setup_measurement()
# za.measure()
# temp_values = za.device.query_ascii_values('*OPC?')
# opc = int(temp_values[0])
# data = za.get_data()
# za.close()
# za.rm.close()
Loading

0 comments on commit 361bfe8

Please sign in to comment.