Skip to content

Commit 473d86f

Browse files
authored
NI-DCPower: Add examples for electronic loads (#2103)
* NI-DCPower: Add examples for electronic loads - Add `nidcpower_constant_resistance_and_constant_power.py` and `nidcpower_sink_dc_current_into_electronic_load.py` - Regenerate `docs/nidcpower/examples.rst` - Update CHANGELOG.md to call out the new examples * Use exact symbol names for assertion message * Address review comments
1 parent 5ca52d6 commit 473d86f

8 files changed

+283
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
- `output_shorted`
6767
- Enum values:
6868
- `CONSTANT_RESISTANCE` and `CONSTANT_POWER` added to enum `OutputFunction`
69+
- `nidcpower_constant_resistance_and_constant_power.py` and `nidcpower_sink_dc_current_into_electronic_load.py` examples
6970
- Changed
7071
- Removed
7172

docs/nidcpower/examples.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ nidcpower_advanced_sequence.py
1212
:encoding: utf8
1313
:caption: `(nidcpower_advanced_sequence.py) <https://github.com/ni/nimi-python/blob/master/src/nidcpower/examples/nidcpower_advanced_sequence.py>`_
1414

15+
nidcpower_constant_resistance_and_constant_power.py
16+
---------------------------------------------------
17+
18+
.. literalinclude:: ../../src/nidcpower/examples/nidcpower_constant_resistance_and_constant_power.py
19+
:language: python
20+
:linenos:
21+
:encoding: utf8
22+
:caption: `(nidcpower_constant_resistance_and_constant_power.py) <https://github.com/ni/nimi-python/blob/master/src/nidcpower/examples/nidcpower_constant_resistance_and_constant_power.py>`_
23+
1524
nidcpower_lcr_source_ac_voltage.py
1625
----------------------------------
1726

@@ -30,6 +39,15 @@ nidcpower_measure_record.py
3039
:encoding: utf8
3140
:caption: `(nidcpower_measure_record.py) <https://github.com/ni/nimi-python/blob/master/src/nidcpower/examples/nidcpower_measure_record.py>`_
3241

42+
nidcpower_sink_dc_current_into_electronic_load.py
43+
-------------------------------------------------
44+
45+
.. literalinclude:: ../../src/nidcpower/examples/nidcpower_sink_dc_current_into_electronic_load.py
46+
:language: python
47+
:linenos:
48+
:encoding: utf8
49+
:caption: `(nidcpower_sink_dc_current_into_electronic_load.py) <https://github.com/ni/nimi-python/blob/master/src/nidcpower/examples/nidcpower_sink_dc_current_into_electronic_load.py>`_
50+
3351
nidcpower_source_delay_measure.py
3452
---------------------------------
3553

src/nidcpower/examples/nidcpower_advanced_sequence.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def _main(argsv):
5656
parser.add_argument('-v', '--voltage-max', default=1.0, type=float, help='Maximum voltage (V)')
5757
parser.add_argument('-i', '--current-max', default=0.001, type=float, help='Maximum Current (I)')
5858
parser.add_argument('-d', '--delay', default=0.05, type=float, help='Source delay (s)')
59-
parser.add_argument('-op', '--option-string', default='', type=str, help='Option string')
59+
parser.add_argument('-op', '--option-string', default='', type=str, help='Option String')
6060
args = parser.parse_args(argsv)
6161
example(args.resource_name, args.option_string, args.voltage_max, args.current_max, args.number_steps, args.delay)
6262

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/python
2+
3+
import argparse
4+
import nidcpower
5+
import sys
6+
7+
8+
def example(
9+
resource_name,
10+
options,
11+
output_function,
12+
constant_resistance_level,
13+
constant_resistance_level_range,
14+
constant_resistance_current_limit,
15+
constant_power_level,
16+
constant_power_level_range,
17+
constant_power_current_limit,
18+
source_delay,
19+
):
20+
assert output_function in (
21+
nidcpower.OutputFunction.CONSTANT_RESISTANCE, nidcpower.OutputFunction.CONSTANT_POWER
22+
), 'This example only supports CONSTANT_RESISTANCE and CONSTANT_POWER output functions.'
23+
24+
with nidcpower.Session(resource_name=resource_name, options=options) as session:
25+
# Configure the session.
26+
session.source_mode = nidcpower.SourceMode.SINGLE_POINT
27+
session.output_function = output_function
28+
if output_function == nidcpower.OutputFunction.CONSTANT_RESISTANCE:
29+
session.constant_resistance_level = constant_resistance_level
30+
session.constant_resistance_level_range = constant_resistance_level_range
31+
session.constant_resistance_current_limit = constant_resistance_current_limit
32+
else:
33+
session.constant_power_level = constant_power_level
34+
session.constant_power_level_range = constant_power_level_range
35+
session.constant_power_current_limit = constant_power_current_limit
36+
# Configure the source_delay to allow for sufficient startup delay for the input to sink to
37+
# the desired level. When starting from a 0 A or Off state, the electronic load requires
38+
# additional startup delay before the input begins to sink the desired level. The default
39+
# source_delay in this example takes this startup delay into account. In cases where
40+
# the electronic load is already sinking, less settling time may be needed.
41+
session.source_delay = source_delay
42+
43+
with session.initiate():
44+
session.wait_for_event(event_id=nidcpower.Event.SOURCE_COMPLETE)
45+
measurement = session.measure_multiple()[0]
46+
in_compliance = session.query_in_compliance()
47+
print(f'Channel : {measurement.channel}')
48+
print(f'Voltage Measurement : {measurement.voltage:f} V')
49+
print(f'Current Measurement : {measurement.current:f} A')
50+
print(f'Compliance / Limit Reached: {in_compliance}')
51+
print(f'Resistance Measurement : {measurement.voltage / measurement.current:f} Ω')
52+
print(f'Power Measurement : {measurement.voltage * measurement.current:f} W')
53+
54+
session.reset()
55+
56+
57+
def _main(argsv):
58+
parser = argparse.ArgumentParser(
59+
description=(
60+
'Demonstrates how to use the Constant Resistance Output Function to force a resistance'
61+
' level on the electronic load and how to use the Constant Power Output Function to'
62+
' force a power level on the electronic load.'
63+
),
64+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
65+
)
66+
parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0', help='Resource names of NI electronic loads')
67+
parser.add_argument('-o', '--output-function', default='CONSTANT_RESISTANCE', type=str, choices=('CONSTANT_RESISTANCE', 'CONSTANT_POWER'), help='Output function')
68+
parser.add_argument('-rl', '--constant-resistance-level', default=15.0, type=float, help='Constant resistance level (Ω)')
69+
parser.add_argument('-rr', '--constant-resistance-level-range', default=1.0e3, type=float, help='Constant resistance level range (Ω)')
70+
parser.add_argument('-rc', '--constant-resistance-current-limit', default=800.0e-3, type=float, help='Constant resistance current limit (A)')
71+
parser.add_argument('-pl', '--constant-power-level', default=7.0, type=float, help='Constant power level (W)')
72+
parser.add_argument('-pr', '--constant-power-level-range', default=300.0, type=float, help='Constant power level range (W)')
73+
parser.add_argument('-pc', '--constant-power-current-limit', default=800.0e-3, type=float, help='Constant power current limit (A)')
74+
parser.add_argument('-s', '--source-delay', default=1.0, type=float, help='Source delay (s)')
75+
parser.add_argument('-op', '--option-string', default='', type=str, help='Option String')
76+
args = parser.parse_args(argsv)
77+
example(
78+
resource_name=args.resource_name,
79+
options=args.option_string,
80+
output_function=getattr(nidcpower.OutputFunction, args.output_function),
81+
constant_resistance_level=args.constant_resistance_level,
82+
constant_resistance_level_range=args.constant_resistance_level_range,
83+
constant_resistance_current_limit=args.constant_resistance_current_limit,
84+
constant_power_level=args.constant_power_level,
85+
constant_power_level_range=args.constant_power_level_range,
86+
constant_power_current_limit=args.constant_power_current_limit,
87+
source_delay=args.source_delay,
88+
)
89+
90+
91+
def main():
92+
_main(sys.argv[1:])
93+
94+
95+
def test_example():
96+
example(
97+
resource_name='PXI1Slot2/0',
98+
options={'simulate': True, 'driver_setup': {'Model': '4051', 'BoardType': 'PXIe', }, },
99+
output_function=nidcpower.OutputFunction.CONSTANT_RESISTANCE,
100+
constant_resistance_level=15.0,
101+
constant_resistance_level_range=1.0e3,
102+
constant_resistance_current_limit=800.0e-3,
103+
constant_power_level=7.0,
104+
constant_power_level_range=300.0,
105+
constant_power_current_limit=800.0e-3,
106+
source_delay=1.0,
107+
)
108+
109+
110+
def test_main():
111+
cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4051; BoardType:PXIe', ]
112+
_main(cmd_line)
113+
114+
115+
if __name__ == '__main__':
116+
main()

src/nidcpower/examples/nidcpower_lcr_source_ac_voltage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def _main(argsv):
6161
parser.add_argument('-ct', '--lcr-custom-measurement-time', default=10.0e-3, type=float, help='LCR custom measurement time (s)')
6262
parser.add_argument('-sm', '--lcr-source-delay-mode', default='AUTOMATIC', type=str, choices=tuple(nidcpower.LCRSourceDelayMode.__members__.keys()), help='LCR source delay mode')
6363
parser.add_argument('-s', '--source-delay', default=16.66e-3, type=float, help='Source delay (s)')
64-
parser.add_argument('-op', '--option-string', default='', type=str, help='Option string')
64+
parser.add_argument('-op', '--option-string', default='', type=str, help='Option String')
6565
args = parser.parse_args(argsv)
6666
example(
6767
resource_name=args.resource_name,

src/nidcpower/examples/nidcpower_measure_record.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def _main(argsv):
3636
parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0, PXI1Slot3/0-1', help='Resource names of NI SMUs.')
3737
parser.add_argument('-l', '--length', default='20', type=int, help='Measure record length per channel')
3838
parser.add_argument('-v', '--voltage', default=5.0, type=float, help='Voltage level (V)')
39-
parser.add_argument('-op', '--option-string', default='', type=str, help='Option string')
39+
parser.add_argument('-op', '--option-string', default='', type=str, help='Option String')
4040
args = parser.parse_args(argsv)
4141
example(args.resource_name, args.option_string, args.voltage, args.length)
4242

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#!/usr/bin/python
2+
3+
import argparse
4+
import nidcpower
5+
import sys
6+
7+
8+
def example(
9+
resource_name,
10+
options,
11+
current_level,
12+
current_level_range,
13+
voltage_limit_range,
14+
source_delay,
15+
output_shorted,
16+
conduction_voltage_mode,
17+
conduction_voltage_on_threshold,
18+
conduction_voltage_off_threshold,
19+
current_level_rising_slew_rate,
20+
current_level_falling_slew_rate,
21+
):
22+
with nidcpower.Session(resource_name=resource_name, options=options) as session:
23+
# Configure the session.
24+
session.source_mode = nidcpower.SourceMode.SINGLE_POINT
25+
26+
session.output_function = nidcpower.OutputFunction.DC_CURRENT
27+
session.current_level = current_level
28+
session.current_level_range = current_level_range
29+
session.voltage_limit_range = voltage_limit_range
30+
# Note that the voltage_limit property is not applicable for electronic loads and is not
31+
# configured in this example. If you change the output_function, configure the appropriate
32+
# level, limit and range properties corresponding to your selected output_function.
33+
34+
session.source_delay = source_delay
35+
36+
# Configure the output_shorted property to specify whether to simulate a short circuit in
37+
# the electronic load.
38+
session.output_shorted = output_shorted
39+
40+
# If you set the output_function property to nidcpower.OutputFunction.DC_CURRENT or
41+
# nidcpower.OutputFunction.CONSTANT_POWER, set the conduction_voltage_mode to
42+
# nidcpower.ConductionVoltageMode.AUTOMATIC or nidcpower.ConductionVoltageMode.ENABLED to
43+
# enable Conduction Voltage.
44+
# If you set the output_function property to nidcpower.OutputFunction.DC_VOLTAGE or
45+
# nidcpower.OutputFunction.CONSTANT_RESISTANCE, set the conduction_voltage_mode to
46+
# nidcpower.ConductionVoltageMode.AUTOMATIC or nidcpower.ConductionVoltageMode.DISABLED to
47+
# disable Conduction Voltage.
48+
# If Conduction Voltage is enabled, set the conduction_voltage_on_threshold to configure the
49+
# electronic load to start sinking current when the input voltage exceeds the configured
50+
# threshold, and set the conduction_voltage_off_threshold to configure the electronic load
51+
# to stop sinking current when the input voltage falls below the threshold.
52+
# If Conduction Voltage is disabled, the electronic load attempts to sink the desired level
53+
# regardless of the input voltage.
54+
session.conduction_voltage_mode = conduction_voltage_mode
55+
session.conduction_voltage_on_threshold = conduction_voltage_on_threshold
56+
session.conduction_voltage_off_threshold = conduction_voltage_off_threshold
57+
58+
# If you set the output_function property to nidcpower.OutputFunction.DC_CURRENT, configure
59+
# the current_level_rising_slew_rate and current_level_falling_slew_rate, in amps per
60+
# microsecond, to control the rising and falling current slew rates of the electronic load
61+
# while sinking current.
62+
# When the output_function property is set to a value other than
63+
# nidcpower.OutputFunction.DC_CURRENT, these properties have no effect.
64+
session.current_level_rising_slew_rate = current_level_rising_slew_rate
65+
session.current_level_falling_slew_rate = current_level_falling_slew_rate
66+
67+
with session.initiate():
68+
session.wait_for_event(event_id=nidcpower.Event.SOURCE_COMPLETE)
69+
measurement = session.measure_multiple()[0]
70+
in_compliance = session.query_in_compliance()
71+
print(f'Channel : {measurement.channel}')
72+
print(f'Voltage Measurement : {measurement.voltage:f} V')
73+
print(f'Current Measurement : {measurement.current:f} A')
74+
print(f'Compliance / Limit Reached: {in_compliance}')
75+
76+
session.reset()
77+
78+
79+
def _main(argsv):
80+
parser = argparse.ArgumentParser(
81+
description=(
82+
'Demonstrates how to use the DC Current Output Function to force a current into the'
83+
' electronic load and how to configure the electronic load with the Output Shorted,'
84+
' Conduction Voltage and Current Level Slew Rate features.'
85+
),
86+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
87+
)
88+
parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0', help='Resource names of NI electronic loads')
89+
parser.add_argument('-cl', '--current-level', default=1.0, type=float, help='Current level (A)')
90+
parser.add_argument('-cr', '--current-level-range', default=40.0, type=float, help='Current level range (A)')
91+
parser.add_argument('-vr', '--voltage-limit-range', default=60.0, type=float, help='Voltage limit range (V)')
92+
parser.add_argument('-s', '--source-delay', default=0.5, type=float, help='Source delay (s)')
93+
parser.add_argument('-os', '--output-shorted', default=False, action='store_true', help='Output shorted')
94+
parser.add_argument('-cv', '--conduction-voltage-mode', default='AUTOMATIC', type=str, choices=tuple(nidcpower.ConductionVoltageMode.__members__.keys()), help='Conduction voltage mode')
95+
parser.add_argument('-nt', '--conduction-voltage-on-threshold', default=1.0, type=float, help='Conduction voltage on threshold (V)')
96+
parser.add_argument('-ot', '--conduction-voltage-off-threshold', default=0.0, type=float, help='Conduction voltage off threshold (V)')
97+
parser.add_argument('-rs', '--current-level-rising-slew-rate', default=24.0, type=float, help='Current level rising slew rate (A/µs)')
98+
parser.add_argument('-fs', '--current-level-falling-slew-rate', default=24.0, type=float, help='Current level falling slew rate (A/µs)')
99+
parser.add_argument('-op', '--option-string', default='', type=str, help='Option String')
100+
args = parser.parse_args(argsv)
101+
example(
102+
resource_name=args.resource_name,
103+
options=args.option_string,
104+
current_level=args.current_level,
105+
current_level_range=args.current_level_range,
106+
voltage_limit_range=args.voltage_limit_range,
107+
source_delay=args.source_delay,
108+
output_shorted=args.output_shorted,
109+
conduction_voltage_mode=getattr(nidcpower.ConductionVoltageMode, args.conduction_voltage_mode),
110+
conduction_voltage_on_threshold=args.conduction_voltage_on_threshold,
111+
conduction_voltage_off_threshold=args.conduction_voltage_off_threshold,
112+
current_level_rising_slew_rate=args.current_level_rising_slew_rate,
113+
current_level_falling_slew_rate=args.current_level_falling_slew_rate,
114+
)
115+
116+
117+
def main():
118+
_main(sys.argv[1:])
119+
120+
121+
def test_example():
122+
example(
123+
resource_name='PXI1Slot2/0',
124+
options={'simulate': True, 'driver_setup': {'Model': '4051', 'BoardType': 'PXIe', }, },
125+
current_level=1.0,
126+
current_level_range=40.0,
127+
voltage_limit_range=60.0,
128+
source_delay=0.5,
129+
output_shorted=False,
130+
conduction_voltage_mode=nidcpower.ConductionVoltageMode.AUTOMATIC,
131+
conduction_voltage_on_threshold=1.0,
132+
conduction_voltage_off_threshold=0.0,
133+
current_level_rising_slew_rate=24.0,
134+
current_level_falling_slew_rate=24.0,
135+
)
136+
137+
138+
def test_main():
139+
cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4051; BoardType:PXIe', ]
140+
_main(cmd_line)
141+
142+
143+
if __name__ == '__main__':
144+
main()

src/nidcpower/examples/nidcpower_source_delay_measure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def _main(argsv):
4747
parser.add_argument('-v1', '--voltage1', default=1.0, type=float, help='Voltage level 1 (V)')
4848
parser.add_argument('-v2', '--voltage2', default=2.0, type=float, help='Voltage level 2 (V)')
4949
parser.add_argument('-d', '--delay', default=0.05, type=float, help='Source delay (s)')
50-
parser.add_argument('-op', '--option-string', default='', type=str, help='Option string')
50+
parser.add_argument('-op', '--option-string', default='', type=str, help='Option String')
5151
args = parser.parse_args(argsv)
5252
example(args.resource_name, args.option_string, args.voltage1, args.voltage2, args.delay)
5353

0 commit comments

Comments
 (0)