diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a4793d5b..4f6b25eff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ - `output_shorted` - Enum values: - `CONSTANT_RESISTANCE` and `CONSTANT_POWER` added to enum `OutputFunction` + - `nidcpower_constant_resistance_and_constant_power.py` and `nidcpower_sink_dc_current_into_electronic_load.py` examples - Changed - Removed diff --git a/docs/nidcpower/examples.rst b/docs/nidcpower/examples.rst index c69c1a009..e0cfbea8e 100644 --- a/docs/nidcpower/examples.rst +++ b/docs/nidcpower/examples.rst @@ -12,6 +12,15 @@ nidcpower_advanced_sequence.py :encoding: utf8 :caption: `(nidcpower_advanced_sequence.py) `_ +nidcpower_constant_resistance_and_constant_power.py +--------------------------------------------------- + +.. literalinclude:: ../../src/nidcpower/examples/nidcpower_constant_resistance_and_constant_power.py + :language: python + :linenos: + :encoding: utf8 + :caption: `(nidcpower_constant_resistance_and_constant_power.py) `_ + nidcpower_lcr_source_ac_voltage.py ---------------------------------- @@ -30,6 +39,15 @@ nidcpower_measure_record.py :encoding: utf8 :caption: `(nidcpower_measure_record.py) `_ +nidcpower_sink_dc_current_into_electronic_load.py +------------------------------------------------- + +.. literalinclude:: ../../src/nidcpower/examples/nidcpower_sink_dc_current_into_electronic_load.py + :language: python + :linenos: + :encoding: utf8 + :caption: `(nidcpower_sink_dc_current_into_electronic_load.py) `_ + nidcpower_source_delay_measure.py --------------------------------- diff --git a/src/nidcpower/examples/nidcpower_advanced_sequence.py b/src/nidcpower/examples/nidcpower_advanced_sequence.py index 5942f602a..280727d02 100644 --- a/src/nidcpower/examples/nidcpower_advanced_sequence.py +++ b/src/nidcpower/examples/nidcpower_advanced_sequence.py @@ -56,7 +56,7 @@ def _main(argsv): parser.add_argument('-v', '--voltage-max', default=1.0, type=float, help='Maximum voltage (V)') parser.add_argument('-i', '--current-max', default=0.001, type=float, help='Maximum Current (I)') parser.add_argument('-d', '--delay', default=0.05, type=float, help='Source delay (s)') - parser.add_argument('-op', '--option-string', default='', type=str, help='Option string') + parser.add_argument('-op', '--option-string', default='', type=str, help='Option String') args = parser.parse_args(argsv) example(args.resource_name, args.option_string, args.voltage_max, args.current_max, args.number_steps, args.delay) diff --git a/src/nidcpower/examples/nidcpower_constant_resistance_and_constant_power.py b/src/nidcpower/examples/nidcpower_constant_resistance_and_constant_power.py new file mode 100644 index 000000000..4a124eca1 --- /dev/null +++ b/src/nidcpower/examples/nidcpower_constant_resistance_and_constant_power.py @@ -0,0 +1,116 @@ +#!/usr/bin/python + +import argparse +import nidcpower +import sys + + +def example( + resource_name, + options, + output_function, + constant_resistance_level, + constant_resistance_level_range, + constant_resistance_current_limit, + constant_power_level, + constant_power_level_range, + constant_power_current_limit, + source_delay, +): + assert output_function in ( + nidcpower.OutputFunction.CONSTANT_RESISTANCE, nidcpower.OutputFunction.CONSTANT_POWER + ), 'This example only supports CONSTANT_RESISTANCE and CONSTANT_POWER output functions.' + + with nidcpower.Session(resource_name=resource_name, options=options) as session: + # Configure the session. + session.source_mode = nidcpower.SourceMode.SINGLE_POINT + session.output_function = output_function + if output_function == nidcpower.OutputFunction.CONSTANT_RESISTANCE: + session.constant_resistance_level = constant_resistance_level + session.constant_resistance_level_range = constant_resistance_level_range + session.constant_resistance_current_limit = constant_resistance_current_limit + else: + session.constant_power_level = constant_power_level + session.constant_power_level_range = constant_power_level_range + session.constant_power_current_limit = constant_power_current_limit + # Configure the source_delay to allow for sufficient startup delay for the input to sink to + # the desired level. When starting from a 0 A or Off state, the electronic load requires + # additional startup delay before the input begins to sink the desired level. The default + # source_delay in this example takes this startup delay into account. In cases where + # the electronic load is already sinking, less settling time may be needed. + session.source_delay = source_delay + + with session.initiate(): + session.wait_for_event(event_id=nidcpower.Event.SOURCE_COMPLETE) + measurement = session.measure_multiple()[0] + in_compliance = session.query_in_compliance() + print(f'Channel : {measurement.channel}') + print(f'Voltage Measurement : {measurement.voltage:f} V') + print(f'Current Measurement : {measurement.current:f} A') + print(f'Compliance / Limit Reached: {in_compliance}') + print(f'Resistance Measurement : {measurement.voltage / measurement.current:f} Ω') + print(f'Power Measurement : {measurement.voltage * measurement.current:f} W') + + session.reset() + + +def _main(argsv): + parser = argparse.ArgumentParser( + description=( + 'Demonstrates how to use the Constant Resistance Output Function to force a resistance' + ' level on the electronic load and how to use the Constant Power Output Function to' + ' force a power level on the electronic load.' + ), + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0', help='Resource names of NI electronic loads') + parser.add_argument('-o', '--output-function', default='CONSTANT_RESISTANCE', type=str, choices=('CONSTANT_RESISTANCE', 'CONSTANT_POWER'), help='Output function') + parser.add_argument('-rl', '--constant-resistance-level', default=15.0, type=float, help='Constant resistance level (Ω)') + parser.add_argument('-rr', '--constant-resistance-level-range', default=1.0e3, type=float, help='Constant resistance level range (Ω)') + parser.add_argument('-rc', '--constant-resistance-current-limit', default=800.0e-3, type=float, help='Constant resistance current limit (A)') + parser.add_argument('-pl', '--constant-power-level', default=7.0, type=float, help='Constant power level (W)') + parser.add_argument('-pr', '--constant-power-level-range', default=300.0, type=float, help='Constant power level range (W)') + parser.add_argument('-pc', '--constant-power-current-limit', default=800.0e-3, type=float, help='Constant power current limit (A)') + parser.add_argument('-s', '--source-delay', default=1.0, type=float, help='Source delay (s)') + parser.add_argument('-op', '--option-string', default='', type=str, help='Option String') + args = parser.parse_args(argsv) + example( + resource_name=args.resource_name, + options=args.option_string, + output_function=getattr(nidcpower.OutputFunction, args.output_function), + constant_resistance_level=args.constant_resistance_level, + constant_resistance_level_range=args.constant_resistance_level_range, + constant_resistance_current_limit=args.constant_resistance_current_limit, + constant_power_level=args.constant_power_level, + constant_power_level_range=args.constant_power_level_range, + constant_power_current_limit=args.constant_power_current_limit, + source_delay=args.source_delay, + ) + + +def main(): + _main(sys.argv[1:]) + + +def test_example(): + example( + resource_name='PXI1Slot2/0', + options={'simulate': True, 'driver_setup': {'Model': '4051', 'BoardType': 'PXIe', }, }, + output_function=nidcpower.OutputFunction.CONSTANT_RESISTANCE, + constant_resistance_level=15.0, + constant_resistance_level_range=1.0e3, + constant_resistance_current_limit=800.0e-3, + constant_power_level=7.0, + constant_power_level_range=300.0, + constant_power_current_limit=800.0e-3, + source_delay=1.0, + ) + + +def test_main(): + cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4051; BoardType:PXIe', ] + _main(cmd_line) + + +if __name__ == '__main__': + main() diff --git a/src/nidcpower/examples/nidcpower_lcr_source_ac_voltage.py b/src/nidcpower/examples/nidcpower_lcr_source_ac_voltage.py index 525f339c2..c5226edd8 100644 --- a/src/nidcpower/examples/nidcpower_lcr_source_ac_voltage.py +++ b/src/nidcpower/examples/nidcpower_lcr_source_ac_voltage.py @@ -61,7 +61,7 @@ def _main(argsv): parser.add_argument('-ct', '--lcr-custom-measurement-time', default=10.0e-3, type=float, help='LCR custom measurement time (s)') parser.add_argument('-sm', '--lcr-source-delay-mode', default='AUTOMATIC', type=str, choices=tuple(nidcpower.LCRSourceDelayMode.__members__.keys()), help='LCR source delay mode') parser.add_argument('-s', '--source-delay', default=16.66e-3, type=float, help='Source delay (s)') - parser.add_argument('-op', '--option-string', default='', type=str, help='Option string') + parser.add_argument('-op', '--option-string', default='', type=str, help='Option String') args = parser.parse_args(argsv) example( resource_name=args.resource_name, diff --git a/src/nidcpower/examples/nidcpower_measure_record.py b/src/nidcpower/examples/nidcpower_measure_record.py index 838c88666..8ec3cfb4f 100644 --- a/src/nidcpower/examples/nidcpower_measure_record.py +++ b/src/nidcpower/examples/nidcpower_measure_record.py @@ -36,7 +36,7 @@ def _main(argsv): parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0, PXI1Slot3/0-1', help='Resource names of NI SMUs.') parser.add_argument('-l', '--length', default='20', type=int, help='Measure record length per channel') parser.add_argument('-v', '--voltage', default=5.0, type=float, help='Voltage level (V)') - parser.add_argument('-op', '--option-string', default='', type=str, help='Option string') + parser.add_argument('-op', '--option-string', default='', type=str, help='Option String') args = parser.parse_args(argsv) example(args.resource_name, args.option_string, args.voltage, args.length) diff --git a/src/nidcpower/examples/nidcpower_sink_dc_current_into_electronic_load.py b/src/nidcpower/examples/nidcpower_sink_dc_current_into_electronic_load.py new file mode 100644 index 000000000..adeb6d489 --- /dev/null +++ b/src/nidcpower/examples/nidcpower_sink_dc_current_into_electronic_load.py @@ -0,0 +1,144 @@ +#!/usr/bin/python + +import argparse +import nidcpower +import sys + + +def example( + resource_name, + options, + current_level, + current_level_range, + voltage_limit_range, + source_delay, + output_shorted, + conduction_voltage_mode, + conduction_voltage_on_threshold, + conduction_voltage_off_threshold, + current_level_rising_slew_rate, + current_level_falling_slew_rate, +): + with nidcpower.Session(resource_name=resource_name, options=options) as session: + # Configure the session. + session.source_mode = nidcpower.SourceMode.SINGLE_POINT + + session.output_function = nidcpower.OutputFunction.DC_CURRENT + session.current_level = current_level + session.current_level_range = current_level_range + session.voltage_limit_range = voltage_limit_range + # Note that the voltage_limit property is not applicable for electronic loads and is not + # configured in this example. If you change the output_function, configure the appropriate + # level, limit and range properties corresponding to your selected output_function. + + session.source_delay = source_delay + + # Configure the output_shorted property to specify whether to simulate a short circuit in + # the electronic load. + session.output_shorted = output_shorted + + # If you set the output_function property to nidcpower.OutputFunction.DC_CURRENT or + # nidcpower.OutputFunction.CONSTANT_POWER, set the conduction_voltage_mode to + # nidcpower.ConductionVoltageMode.AUTOMATIC or nidcpower.ConductionVoltageMode.ENABLED to + # enable Conduction Voltage. + # If you set the output_function property to nidcpower.OutputFunction.DC_VOLTAGE or + # nidcpower.OutputFunction.CONSTANT_RESISTANCE, set the conduction_voltage_mode to + # nidcpower.ConductionVoltageMode.AUTOMATIC or nidcpower.ConductionVoltageMode.DISABLED to + # disable Conduction Voltage. + # If Conduction Voltage is enabled, set the conduction_voltage_on_threshold to configure the + # electronic load to start sinking current when the input voltage exceeds the configured + # threshold, and set the conduction_voltage_off_threshold to configure the electronic load + # to stop sinking current when the input voltage falls below the threshold. + # If Conduction Voltage is disabled, the electronic load attempts to sink the desired level + # regardless of the input voltage. + session.conduction_voltage_mode = conduction_voltage_mode + session.conduction_voltage_on_threshold = conduction_voltage_on_threshold + session.conduction_voltage_off_threshold = conduction_voltage_off_threshold + + # If you set the output_function property to nidcpower.OutputFunction.DC_CURRENT, configure + # the current_level_rising_slew_rate and current_level_falling_slew_rate, in amps per + # microsecond, to control the rising and falling current slew rates of the electronic load + # while sinking current. + # When the output_function property is set to a value other than + # nidcpower.OutputFunction.DC_CURRENT, these properties have no effect. + session.current_level_rising_slew_rate = current_level_rising_slew_rate + session.current_level_falling_slew_rate = current_level_falling_slew_rate + + with session.initiate(): + session.wait_for_event(event_id=nidcpower.Event.SOURCE_COMPLETE) + measurement = session.measure_multiple()[0] + in_compliance = session.query_in_compliance() + print(f'Channel : {measurement.channel}') + print(f'Voltage Measurement : {measurement.voltage:f} V') + print(f'Current Measurement : {measurement.current:f} A') + print(f'Compliance / Limit Reached: {in_compliance}') + + session.reset() + + +def _main(argsv): + parser = argparse.ArgumentParser( + description=( + 'Demonstrates how to use the DC Current Output Function to force a current into the' + ' electronic load and how to configure the electronic load with the Output Shorted,' + ' Conduction Voltage and Current Level Slew Rate features.' + ), + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0', help='Resource names of NI electronic loads') + parser.add_argument('-cl', '--current-level', default=1.0, type=float, help='Current level (A)') + parser.add_argument('-cr', '--current-level-range', default=40.0, type=float, help='Current level range (A)') + parser.add_argument('-vr', '--voltage-limit-range', default=60.0, type=float, help='Voltage limit range (V)') + parser.add_argument('-s', '--source-delay', default=0.5, type=float, help='Source delay (s)') + parser.add_argument('-os', '--output-shorted', default=False, action='store_true', help='Output shorted') + parser.add_argument('-cv', '--conduction-voltage-mode', default='AUTOMATIC', type=str, choices=tuple(nidcpower.ConductionVoltageMode.__members__.keys()), help='Conduction voltage mode') + parser.add_argument('-nt', '--conduction-voltage-on-threshold', default=1.0, type=float, help='Conduction voltage on threshold (V)') + parser.add_argument('-ot', '--conduction-voltage-off-threshold', default=0.0, type=float, help='Conduction voltage off threshold (V)') + parser.add_argument('-rs', '--current-level-rising-slew-rate', default=24.0, type=float, help='Current level rising slew rate (A/µs)') + parser.add_argument('-fs', '--current-level-falling-slew-rate', default=24.0, type=float, help='Current level falling slew rate (A/µs)') + parser.add_argument('-op', '--option-string', default='', type=str, help='Option String') + args = parser.parse_args(argsv) + example( + resource_name=args.resource_name, + options=args.option_string, + current_level=args.current_level, + current_level_range=args.current_level_range, + voltage_limit_range=args.voltage_limit_range, + source_delay=args.source_delay, + output_shorted=args.output_shorted, + conduction_voltage_mode=getattr(nidcpower.ConductionVoltageMode, args.conduction_voltage_mode), + conduction_voltage_on_threshold=args.conduction_voltage_on_threshold, + conduction_voltage_off_threshold=args.conduction_voltage_off_threshold, + current_level_rising_slew_rate=args.current_level_rising_slew_rate, + current_level_falling_slew_rate=args.current_level_falling_slew_rate, + ) + + +def main(): + _main(sys.argv[1:]) + + +def test_example(): + example( + resource_name='PXI1Slot2/0', + options={'simulate': True, 'driver_setup': {'Model': '4051', 'BoardType': 'PXIe', }, }, + current_level=1.0, + current_level_range=40.0, + voltage_limit_range=60.0, + source_delay=0.5, + output_shorted=False, + conduction_voltage_mode=nidcpower.ConductionVoltageMode.AUTOMATIC, + conduction_voltage_on_threshold=1.0, + conduction_voltage_off_threshold=0.0, + current_level_rising_slew_rate=24.0, + current_level_falling_slew_rate=24.0, + ) + + +def test_main(): + cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4051; BoardType:PXIe', ] + _main(cmd_line) + + +if __name__ == '__main__': + main() diff --git a/src/nidcpower/examples/nidcpower_source_delay_measure.py b/src/nidcpower/examples/nidcpower_source_delay_measure.py index d4b796d7f..38d9324bb 100644 --- a/src/nidcpower/examples/nidcpower_source_delay_measure.py +++ b/src/nidcpower/examples/nidcpower_source_delay_measure.py @@ -47,7 +47,7 @@ def _main(argsv): parser.add_argument('-v1', '--voltage1', default=1.0, type=float, help='Voltage level 1 (V)') parser.add_argument('-v2', '--voltage2', default=2.0, type=float, help='Voltage level 2 (V)') parser.add_argument('-d', '--delay', default=0.05, type=float, help='Source delay (s)') - parser.add_argument('-op', '--option-string', default='', type=str, help='Option string') + parser.add_argument('-op', '--option-string', default='', type=str, help='Option String') args = parser.parse_args(argsv) example(args.resource_name, args.option_string, args.voltage1, args.voltage2, args.delay)