Creating a Simple Sequence for an SMU in Python

Updated Mar 14, 2023

Environment

Driver

  • NI-DCPower

Programming Language

  • Python

This article demonstrates how to write a Python script that configures a Simple Sequence for a PXI Source Measurement Unit (SMU).


Prerequisites

In your Python development environment, follow the steps below to create a Simple Sequence. For demonstration purposes, this example uses a PXIe-4137 SMU and a Sequence that generates a series of voltage outputs.

1. Import the following required modules:  
import hightime
import nidcpower

2. Define a main() function with the following input parameters:
  • resource_name: used to specify the name of the PXI SMU.
  • options: used to specify simulation and driver options.
  • voltage_max: used to specify the maximum voltage that will be generated.
  • current_limit: used to specify the current limit.
  • number_of_outputs: used to specify the number of voltages to generate.
  • delay_in_seconds: used to define timeouts.
def main(resource_name, options, voltage_max, current_limit, number_of_outputs, delay_in_seconds):

3. Inside main(), define a timeout of delay_in_seconds  + 1 second.
timeout = hightime.timedelta(seconds=(delay_in_seconds + 1.0))

4. Create an NIDCPower session that uses resource_name and options to define the session parameters.
with nidcpower.Session(resource_name=resource_name, options=options) as session:

5. Inside, the NIDCPower Session, configure the Source Mode (session.source_mode) and Output Function (session.output_function).
  • source_mode must be set to SEQUENCE.
  • For this example, output_function is set to DC_VOLTAGE. Refer to the output_function documentation to see other possible values.
session.source_mode = nidcpower.SourceMode.SEQUENCE
session.output_function=nidcpower.OutputFunction.DC_VOLTAGE

6. Define voltage and Source Delay arrays that will be used by the Sequence.
  1. Define an empty array called voltages.
  2. Define an empty array called source_delays.
  3. Calculate the voltage_step by dividing voltage_max by number_of_outputs.
  4. Define a for loop that iterates for number_of_outputs iterations.
  5. Inside the for loop, append voltage_step*i to the voltages array. This creates an array that consists of voltages ranging from 0 to voltage_max, in equal steps.
  6. Append delay_in_seconds to the source_delays array. This ensures that there is the same source_delay between each output voltage.
  7. This section should resemble the following code:
voltages = []
source_delays = []
voltage_step = voltage_max/number_of_outputs
for i in range(number_of_outputs):
	voltages.append(voltage_step*i)
	source_delays.append(delay_in_seconds)

7. Outside of the for loop, define the sequence and finish configuring the session.
  1. Pass the voltages and source_delays arrays to the set_sequence method. This configures the steps in the sequence.
  2. Set session.voltage_level_range to voltage_max.
  3. Set session.current_limit to current_limit.
  4. Set session.current_limit_range to current_limit.
  5. Set session.aperture_time to a suitable value. This example uses an Aperture Time of 0.0001 seconds.
  6. This section should resemble the following code:
session.set_sequence(voltages, source_delays)
session.voltage_level_range = voltage_max
session.current_limit = current_limit
session.current_limit_range = current_limit
session.aperture_time = 0.0001

8. Initiate the session and fetch measurement points.
  1. Call the initiate method.
  2. Set the session to wait for the SEQUENCE_ENGINE_DONE event with the wait_for_event method.
  3. Define a variable called measurement_group that stores the results from session.fetch_multiple.
  4. [Optional] use [External] input() to force the Python script to wait for a user input before continuing. This can be useful if you intend to monitor the sequence from InstrumentStudio later.
  5. This section should resemble the following code:
session.initiate()
session.wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE)
measurement_group = session.fetch_multiple(len(voltages),timeout=timeout)
input('Wait before printing results')

9. Format the fetched data and print the results.
  1. Define a variable called line_format that formats a string as 3 columns, which are left-aligned. Refer to [External] Common String Operations to understand string formatting.
  2. Print three columns, titled 'Num', 'Voltage', and 'Current'.
  3. Define a for loop that iterates over each measurement stored in measurement_group.
  4. Inside the for loop, set num to 0.
  5. Print num, measurements[0] and measurements[1] formatted with line_format. This will print values under each 'Num', 'Voltage' and 'Current' column respectively.
  6. This section of code should resemble the following:
line_format= '{:<10}{:<10}{:<10}'
print(line_format.format('Num', 'Voltage', 'Current'))
for i, measurements in enumerate(measurement_group):
	num = 0
	print(line_format.format(num, measurements[0], measurements[1]))

10. Define the options to pass to the main function.
  1. Exit the main function.
  2. Enter options={'simulate': <Simulated>, 'driver_setup': {'Model' : '<Model>', 'BoardType'': '<BoardType>', }, } Where:
    • <Simulated> is either True or False, depending on whether you wish to simulate the SMU.
    • <Model> is the model number of the SMU. For this example, <Model> is 4137.
    • <BoardType> is either PXI or PXIe.
options = {'simulate': False, 'driver_setup': {'Model': '4137', 'BoardType': 'PXIe', }, }

11. Call the main function with required parameter values. From the example code below:
  • resource_name is set to PXI1Slot2. Ensure this matches the Name of your SMU listed in NI Measurement & Automation Explorer (MAX).
  • options is set to options.
  • voltage_max is set to 10.
  • current_limit is set to 0.5.
  • number_of_outputs is set to 10.
  • delay_in_seconds is set to 0.5.
main('PXI1Slot2', options, 10,  0.5, 10, 0.5)

The full code should resemble the following:
 
import hightime
import nidcpower

def main(resource_name, options, voltage_max, current_limit, number_of_outputs, delay_in_seconds):
	timeout = hightime.timedelta(seconds=(delay_in_seconds + 1.0))
	with nidcpower.Session(resource_name=resource_name, options=options) as session:
		session.source_mode = nidcpower.SourceMode.SEQUENCE
		session.output_function=nidcpower.OutputFunction.DC_VOLTAGE
		voltages = []
		source_delays = []
		voltage_step = voltage_max/number_of_outputs
		for i in range(number_of_outputs):
			voltages.append(voltage_step*i)
			source_delays.append(delay_in_seconds)
		session.set_sequence(voltages, source_delays)
		session.voltage_level_range = voltage_max
		session.current_limit = current_limit
		session.current_limit_range = current_limit
		session.aperture_time = 0.0001
		session.initiate()
		session.wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE)
		measurement_group = session.fetch_multiple(len(voltages),timeout=timeout)
		input('Wait before printing results')
		line_format= '{:<10}{:<10}{:<10}'
		print(line_format.format('Num', 'Voltage', 'Current'))
		for i, measurements in enumerate(measurement_group):
			num = 0
			print(line_format.format(num, measurements[0], measurements[1]))

options = {'simulate': False, 'driver_setup': {'Model': '4137', 'BoardType': 'PXIe', }, }
main('PXI1Slot2', options, 11, 0.5, 10, 0.5)

The printed output appears as:

python output.PNG