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()