Examples
You can download all nidigital examples here
nidigital_burst_with_start_trigger.py
1#!/usr/bin/python
2
3import argparse
4import nidigital
5import os
6import sys
7
8
9def example(resource_name, options, trigger_source=None, trigger_edge=None):
10
11 with nidigital.Session(resource_name=resource_name, options=options) as session:
12
13 dir = os.path.join(os.path.dirname(__file__))
14
15 # Load the pin map (.pinmap) created using the Digital Pattern Editor
16 pin_map_filename = os.path.join(dir, 'PinMap.pinmap')
17 session.load_pin_map(pin_map_filename)
18
19 # Load the specifications (.specs), levels (.digilevels), and timing (.digitiming) sheets created using the Digital Pattern Editor
20 spec_filename = os.path.join(dir, 'Specifications.specs')
21 levels_filename = os.path.join(dir, 'PinLevels.digilevels')
22 timing_filename = os.path.join(dir, 'Timing.digitiming')
23 session.load_specifications_levels_and_timing(spec_filename, levels_filename, timing_filename)
24
25 # Apply the settings from the levels and timing sheets we just loaded to the session
26 session.apply_levels_and_timing(levels_filename, timing_filename)
27
28 # Loading the pattern file (.digipat) created using the Digital Pattern Editor
29 pattern_filename = os.path.join(dir, 'Pattern.digipat')
30 session.load_pattern(pattern_filename)
31
32 if trigger_source is None:
33 print('Start bursting pattern')
34 else:
35 # Specify a source and edge for the external start trigger
36 session.start_trigger_type = nidigital.TriggerType.DIGITAL_EDGE
37 session.digital_edge_start_trigger_source = trigger_source
38 session.digital_edge_start_trigger_edge = nidigital.DigitalEdge.RISING if trigger_edge == 'Rising' else nidigital.DigitalEdge.FALLING
39 print('Wait for start trigger and then start bursting pattern')
40
41 # If start trigger is configured, waiting for the trigger to start bursting and then blocks until the pattern is done bursting
42 # Else just start bursting and block until the pattern is done bursting
43 session.burst_pattern(start_label='new_pattern')
44
45 # Disconnect all channels using programmable onboard switching
46 session.selected_function = nidigital.SelectedFunction.DISCONNECT
47 print('Done bursting pattern')
48
49
50def _main(argsv):
51 parser = argparse.ArgumentParser(description='Demonstrates how to create and configure a session that bursts a pattern on the digital pattern instrument using a start trigger', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
52 parser.add_argument('-n', '--resource-name', default='PXI1Slot2,PXI1Slot3', help='Resource name of a NI digital pattern instrument. Ensure the resource name matches the instrument name in the pinmap file.')
53 parser.add_argument('-s', '--simulate', default='True', choices=['True', 'False'], help='Whether to run on simulated hardware or real hardware')
54 subparser = parser.add_subparsers(dest='command', help='Sub-command help')
55 start_trigger = subparser.add_parser('start-trigger', help='Configure start trigger')
56 start_trigger.add_argument('-ts', '--trigger-source', default='/PXI1Slot2/PXI_Trig0', help='Source terminal for the start trigger')
57 start_trigger.add_argument('-te', '--trigger-edge', default='Rising', choices=['Rising', 'Falling'], help='Trigger on rising edge or falling edge of start trigger')
58 args = parser.parse_args(argsv)
59
60 example(args.resource_name,
61 'Simulate=1, DriverSetup=Model:6571' if args.simulate == 'True' else '',
62 args.trigger_source if args.command == 'start-trigger' else None,
63 args.trigger_edge if args.command == 'start-trigger' else None)
64
65
66def main():
67 _main(sys.argv[1:])
68
69
70def test_main():
71 _main([])
72 _main(['start-trigger'])
73
74
75def test_example():
76 resource_name = 'PXI1Slot2,PXI1Slot3'
77 options = {'simulate': True, 'driver_setup': {'Model': '6571'}, }
78 example(resource_name, options)
79
80 trigger_source = '/PXI1Slot2/PXI_Trig0'
81 trigger_edge = 'Rising'
82 example(resource_name, options, trigger_source, trigger_edge)
83
84
85if __name__ == '__main__':
86 main()
nidigital_configure_time_set_and_voltage_levels.py
1#!/usr/bin/python
2
3import argparse
4import nidigital
5import os
6import sys
7
8
9class VoltageLevelsAndTerminationConfig():
10 def __init__(self, vil, vih, vol, voh, vterm, termination_mode, iol, ioh, vcom):
11 self.vil = vil
12 self.vih = vih
13 self.vol = vol
14 self.voh = voh
15 self.vterm = vterm
16 self.termination_mode = termination_mode
17 self.iol = iol
18 self.ioh = ioh
19 self.vcom = vcom
20
21
22class TimeSetConfig():
23 def __init__(self, time_set_name, period, drive_format, drive_on, drive_data, drive_return, drive_off, strobe_edge):
24 self.time_set_name = time_set_name
25 self.period = period
26 self.drive_format = drive_format
27 self.drive_on = drive_on
28 self.drive_data = drive_data
29 self.drive_return = drive_return
30 self.drive_off = drive_off
31 self.strobe_edge = strobe_edge
32
33
34def convert_drive_format(drive_format):
35 converter = {'NR': nidigital.DriveFormat.NR,
36 'RL': nidigital.DriveFormat.RL,
37 'RH': nidigital.DriveFormat.RH,
38 'SBC': nidigital.DriveFormat.SBC}
39 return converter.get(drive_format, None)
40
41
42def example(resource_name,
43 options,
44 channels,
45 voltage_config,
46 time_set_config):
47
48 with nidigital.Session(resource_name=resource_name, options=options) as session:
49
50 dir = os.path.dirname(__file__)
51
52 # Load pin map (.pinmap) created using Digital Pattern Editor
53 pin_map_filename = os.path.join(dir, 'PinMap.pinmap')
54 session.load_pin_map(pin_map_filename)
55
56 # Configure voltage levels and terminal voltage through driver API
57 session.channels[channels].configure_voltage_levels(voltage_config.vil, voltage_config.vih, voltage_config.vol, voltage_config.voh, voltage_config.vterm)
58 if voltage_config.termination_mode == 'High_Z':
59 session.channels[channels].termination_mode = nidigital.TerminationMode.HIGH_Z
60 elif voltage_config.termination_mode == 'Active_Load':
61 session.channels[channels].termination_mode = nidigital.TerminationMode.ACTIVE_LOAD
62 session.channels[channels].configure_active_load_levels(voltage_config.iol, voltage_config.ioh, voltage_config.vcom)
63 else:
64 session.channels[channels].termination_mode = nidigital.TerminationMode.VTERM
65
66 # Configure time set through driver API
67 session.create_time_set(time_set_config.time_set_name) # Must match time set name in pattern file
68 session.configure_time_set_period(time_set_config.time_set_name, time_set_config.period)
69 session.channels[channels].configure_time_set_drive_edges(time_set_config.time_set_name, convert_drive_format(time_set_config.drive_format),
70 time_set_config.drive_on, time_set_config.drive_data,
71 time_set_config.drive_return, time_set_config.drive_off)
72 session.channels[channels].configure_time_set_compare_edges_strobe(time_set_config.time_set_name, time_set_config.strobe_edge)
73
74 # Load the pattern file (.digipat) created using Digital Pattern Editor
75 pattern_filename = os.path.join(dir, 'Pattern.digipat')
76 session.load_pattern(pattern_filename)
77
78 # Burst pattern, blocks until the pattern is done bursting
79 session.burst_pattern(start_label='new_pattern')
80 print('Start bursting pattern')
81
82 # Disconnect all channels using programmable onboard switching
83 session.selected_function = nidigital.SelectedFunction.DISCONNECT
84 print('Done bursting pattern')
85
86
87def _main(argsv):
88 parser = argparse.ArgumentParser(description='Demonstrates how to create an instrument session, configure time set and voltage levels, and burst a pattern on the digital pattern instrument.', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
89 parser.add_argument('-n', '--resource-name', default='PXI1Slot2,PXI1Slot3', help='Resource name of a NI digital pattern instrument, ensure the resource name matches the instrument name in the pinmap file.')
90 parser.add_argument('-s', '--simulate', default='True', choices=['True', 'False'], help='Whether to run on simulated hardware or on real hardware')
91 parser.add_argument('-c', '--channels', default='PinGroup1', help='Channel(s)/Pin(s) to configure')
92
93 # Parameters to configure voltage
94 parser.add_argument('--vil', default=0, type=float, help='The voltage that the instrument will apply to the input of the DUT when the pin driver drives a logic low (0)')
95 parser.add_argument('--vih', default=3.3, type=float, help='The voltage that the instrument will apply to the input of the DUT when the test instrument drives a logic high (1)')
96 parser.add_argument('--vol', default=1.6, type=float, help='The output voltage below which the comparator on the pin driver interprets a logic low (L)')
97 parser.add_argument('--voh', default=1.7, type=float, help='The output voltage above which the comparator on the pin driver interprets a logic high (H)')
98 parser.add_argument('--vterm', default=2, type=float, help='The termination voltage the instrument applies during non-drive cycles when the termination mode is set to Vterm')
99 parser.add_argument('-term-mode', '--termination-mode', default='High_Z', choices=['High_Z', 'Active_Load', 'Three_Level_Drive'])
100 parser.add_argument('--iol', default=0.002, type=float, help='The maximum current that the DUT sinks while outputting a voltage below VCOM')
101 parser.add_argument('--ioh', default=-0.002, type=float, help='The maximum current that the DUT sources while outputting a voltage above VCOM')
102 parser.add_argument('--vcom', default=0.0, type=float, help='The commutating voltage level at which the active load circuit switches between sourcing current and sinking current')
103
104 # Parameters to configure timeset
105 parser.add_argument('--period', default=0.00000002, type=float, help='Period in second')
106 parser.add_argument('-format', '--drive-format', default='NR', choices=['NR', 'RL', 'RH', 'SBC'], help='Non-return | Return to low | Return to high | Surround by complement')
107 parser.add_argument('--drive-on', default=0, type=float, help='The delay in seconds from the beginning of the vector period for turning on the pin driver')
108 parser.add_argument('--drive-data', default=0, type=float, help='The delay in seconds from the beginning of the vector period until the pattern data is driven to the pattern value')
109 parser.add_argument('--drive-return', default=0.000000015, type=float, help='The delay in seconds from the beginning of the vector period until the pin changes from the pattern data to the return value, as specified in the format.')
110 parser.add_argument('--drive-off', default=0.00000002, type=float, help='The delay in seconds from the beginning of the vector period to turn off the pin driver when the next vector period uses a non-drive symbol (L, H, X, V, M, E).')
111 parser.add_argument('--strobe-edge', default=0.00000001, type=float, help='The time in second when the comparison happens within a vector period')
112
113 args = parser.parse_args(argsv)
114 voltage_config = VoltageLevelsAndTerminationConfig(args.vil, args.vih, args.vol, args.voh, args.vterm, args.termination_mode, args.iol, args.ioh, args.vcom)
115 time_set_config = TimeSetConfig("tset0", args.period, args.drive_format, args.drive_on, args.drive_data, args.drive_return, args.drive_off, args.strobe_edge)
116 example(args.resource_name,
117 'Simulate=1, DriverSetup=Model:6571' if args.simulate == 'True' else '',
118 args.channels,
119 voltage_config,
120 time_set_config)
121
122
123def main():
124 _main(sys.argv[1:])
125
126
127def test_main():
128 _main([])
129
130
131def test_example():
132 resource_name = 'PXI1Slot2,PXI1Slot3'
133 options = {'simulate': True, 'driver_setup': {'Model': '6571'}, }
134 channels = 'PinGroup1'
135 voltage_config = VoltageLevelsAndTerminationConfig(vil=0, vih=3.3, vol=1.6, voh=1.7, vterm=2,
136 termination_mode='Active_Load', iol=0.002, ioh=-0.002, vcom=0)
137 time_set_config = TimeSetConfig(time_set_name="tset0",
138 period=0.00000002,
139 drive_format='NR',
140 drive_on=0, drive_data=0, drive_return=0.000000015, drive_off=0.00000002, strobe_edge=0.00000001)
141 example(resource_name, options, channels, voltage_config, time_set_config)
142
143
144if __name__ == '__main__':
145 main()
nidigital_ppmu_source_and_measure.py
1#!/usr/bin/python
2
3import argparse
4import nidigital
5import os
6import pytest
7import sys
8import time
9
10
11def example(resource_name, options, channels, measure, aperture_time,
12 source=None, settling_time=None, current_level_range=None, current_level=None,
13 voltage_limit_high=None, voltage_limit_low=None, current_limit_range=None, voltage_level=None):
14
15 with nidigital.Session(resource_name=resource_name, options=options) as session:
16
17 dir = os.path.join(os.path.dirname(__file__))
18
19 # Load pin map (.pinmap) created using Digital Pattern Editor
20 pin_map_filename = os.path.join(dir, 'PinMap.pinmap')
21 session.load_pin_map(pin_map_filename)
22
23 # Configure the PPMU measurement aperture time
24 session.channels[channels].ppmu_aperture_time = aperture_time
25 session.channels[channels].ppmu_aperture_time_units = nidigital.PPMUApertureTimeUnits.SECONDS
26
27 # Configure and source
28 if source == 'source-current':
29 session.channels[channels].ppmu_output_function = nidigital.PPMUOutputFunction.CURRENT
30
31 session.channels[channels].ppmu_current_level_range = current_level_range
32 session.channels[channels].ppmu_current_level = current_level
33 session.channels[channels].ppmu_voltage_limit_high = voltage_limit_high
34 session.channels[channels].ppmu_voltage_limit_low = voltage_limit_low
35
36 session.channels[channels].ppmu_source()
37
38 # Settling time between sourcing and measuring
39 time.sleep(settling_time)
40
41 elif source == 'source-voltage':
42 session.channels[channels].ppmu_output_function = nidigital.PPMUOutputFunction.VOLTAGE
43
44 session.channels[channels].ppmu_current_limit_range = current_limit_range
45 session.channels[channels].ppmu_voltage_level = voltage_level
46
47 session.channels[channels].ppmu_source()
48
49 # Settling time between sourcing and measuring
50 time.sleep(settling_time)
51
52 pin_info = session.channels[channels].get_pin_results_pin_information()
53
54 # Measure
55 if measure == 'current':
56 current_measurements = session.channels[channels].ppmu_measure(nidigital.PPMUMeasurementType.CURRENT)
57
58 print('{:<6} {:<20} {:<10}'.format('Site', 'Pin Name', 'Current'))
59
60 for pin, current in zip(pin_info, current_measurements):
61 print(f'{pin.site_number:<6d} {pin.pin_name:<20} {current:<10f}')
62 else:
63 voltage_measurements = session.channels[channels].ppmu_measure(nidigital.PPMUMeasurementType.VOLTAGE)
64
65 print('{:<6} {:<20} {:<10}'.format('Site', 'Pin Name', 'Voltage'))
66
67 for pin, voltage in zip(pin_info, voltage_measurements):
68 print(f'{pin.site_number:<6d} {pin.pin_name:<20} {voltage:<10f}')
69
70 # Disconnect all channels using programmable onboard switching
71 session.channels[channels].selected_function = nidigital.SelectedFunction.DISCONNECT
72
73
74def _main(argsv):
75 parser = argparse.ArgumentParser(description='Demonstrates how to source/measure voltage/current using the PPMU on selected channels/pins of the digital pattern instrument',
76 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
77 parser.add_argument('-n', '--resource-name', default='PXI1Slot2,PXI1Slot3', help='Resource name of a NI digital pattern instrument, ensure the resource name matches the instrument name in the pinmap file.')
78 parser.add_argument('-s', '--simulate', default='True', choices=['True', 'False'], help='Whether to run on simulated hardware or on real hardware')
79 parser.add_argument('-c', '--channels', default='DUTPin1, SystemPin1', help='Channel(s)/Pin(s) to use')
80 parser.add_argument('-m', '--measure', default='voltage', choices=['voltage', 'current'], help='Measure voltage or measure current')
81 parser.add_argument('-at', '--aperture-time', default=0.000004, type=float, help='Aperture time in seconds')
82 subparser = parser.add_subparsers(dest='source', help='Sub-command help, by default it measures voltage and does not source')
83
84 source_current = subparser.add_parser('source-current', help='Source current')
85 source_current.add_argument('-clr', '--current-level-range', default=0.000002, type=float, help='Current level range in amps')
86 source_current.add_argument('-cl', '--current-level', default=0.000002, type=float, help='Current level in amps')
87 source_current.add_argument('-vlh', '--voltage-limit-high', default=3.3, type=float, help='Voltage limit high in volts')
88 source_current.add_argument('-vll', '--voltage-limit-low', default=0, type=float, help='Voltage limit low in volts')
89 source_current.add_argument('-st', '--settling-time', default=0.01, type=float, help='Settling time in seconds')
90
91 source_voltage = subparser.add_parser('source-voltage', help='Source voltage')
92 source_voltage.add_argument('-clr', '--current-limit-range', default=0.000002, type=float, help='Current limit range in amps')
93 source_voltage.add_argument('-vl', '--voltage-level', default=3.3, type=float, help='Voltage level in volts')
94 source_voltage.add_argument('-st', '--settling-time', default=0.01, type=float, help='Settling time in seconds')
95
96 args = parser.parse_args(argsv)
97
98 if args.source == 'source-current':
99 example(
100 args.resource_name,
101 'Simulate=1, DriverSetup=Model:6571' if args.simulate == 'True' else '',
102 args.channels,
103 args.measure,
104 args.aperture_time,
105 args.source,
106 args.settling_time,
107 args.current_level_range,
108 args.current_level,
109 args.voltage_limit_high,
110 args.voltage_limit_low)
111 elif args.source == 'source-voltage':
112 example(
113 args.resource_name,
114 'Simulate=1, DriverSetup=Model:6571' if args.simulate == 'True' else '',
115 args.channels,
116 args.measure,
117 args.aperture_time,
118 args.source,
119 args.settling_time,
120 current_limit_range=args.current_limit_range,
121 voltage_level=args.voltage_level)
122 else:
123 if args.measure == 'current':
124 raise ValueError('Cannot measure current on a channel that is not sourcing voltage or current')
125 example(
126 args.resource_name,
127 'Simulate=1, DriverSetup=Model:6571' if args.simulate == 'True' else '',
128 args.channels,
129 args.measure,
130 args.aperture_time)
131
132
133def main():
134 _main(sys.argv[1:])
135
136
137def test_main():
138 _main([])
139 _main(['-m', 'voltage'])
140 with pytest.raises(Exception):
141 _main(['-m', 'current'])
142 _main(['-m', 'voltage', 'source-current'])
143 _main(['-m', 'current', 'source-current'])
144 _main(['-m', 'voltage', 'source-voltage'])
145 _main(['-m', 'current', 'source-voltage'])
146
147
148def test_example():
149 resource_name = 'PXI1Slot2,PXI1Slot3'
150 options = {'simulate': True, 'driver_setup': {'Model': '6571'}, }
151 channels = 'DUTPin1, SystemPin1'
152 aperture_time = 0.000004
153
154 example(resource_name, options, channels, 'voltage',
155 aperture_time)
156 with pytest.raises(Exception):
157 example(resource_name, options, channels, 'current',
158 aperture_time)
159
160 settling_time = 0.01
161 current_level_range = 0.000002
162 current_level = 0.000002
163 voltage_limit_high = 3.3
164 voltage_limit_low = 0
165 example(resource_name, options, channels, 'voltage',
166 aperture_time, 'source-current', settling_time,
167 current_level_range, current_level,
168 voltage_limit_high, voltage_limit_low)
169 example(resource_name, options, channels, 'current',
170 aperture_time, 'source-current', settling_time,
171 current_level_range, current_level,
172 voltage_limit_high, voltage_limit_low)
173
174 current_limit_range = 0.000002
175 voltage_level = 3.3
176 example(resource_name, options, channels, 'voltage',
177 aperture_time, 'source-voltage', settling_time,
178 current_limit_range=current_limit_range,
179 voltage_level=voltage_level)
180 example(resource_name, options, channels, 'current',
181 aperture_time, 'source-voltage', settling_time,
182 current_limit_range=current_limit_range,
183 voltage_level=voltage_level)
184
185
186if __name__ == '__main__':
187 main()