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