-
Notifications
You must be signed in to change notification settings - Fork 110
Adding example in NI-DC Power , NI-DMM , NI-Switch #2192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
7c29721
bab936b
ecda1b2
7a997bc
6de4b77
27b7081
9ad83fb
6005021
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| #!/usr/bin/env python3 | ||
| """NI-DCPower Hardware-Timed Single Point. | ||
|
|
||
| This example demonstrates how to set up a hardware-timed Single Point operation. | ||
|
|
||
| The hardware is configured to source a voltage, wait for a specified delay and | ||
| then take a measurement. | ||
|
|
||
| The example uses the default resource name, channel, current level, | ||
| and voltage limit. Modify these values as needed for your measurement setup | ||
|
|
||
| HOW TO RUN: | ||
| ----------- | ||
| i. From terminal (with default values): | ||
| python nidcpower_hardware_timed_single_point.py | ||
|
|
||
| ii. From terminal (with custom values): | ||
| python nidcpower_hardware_timed_single_point.py -n "PXI1Slot2" \ | ||
| -vl1 3.0 -vl2 5.0 -sd 0.1 | ||
|
|
||
| iii. To simulate without hardware: | ||
| PowerShell: python nidcpower_hardware_timed_single_point.py \ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Powershell and cmd instructions look the same to me. Do you need both? If you do, then you definitely need Linux. But I don't think we need both. |
||
| -op 'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe' | ||
| cmd.exe: python nidcpower_hardware_timed_single_point.py \ | ||
| -op "Simulate=1, DriverSetup=Model:4162; BoardType:PXIe" | ||
|
|
||
| """ | ||
|
|
||
| # Module imports | ||
| import argparse # For parsing command-line arguments | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are all these comments consistent with all other examples? If they are, ok. |
||
| import sys # For accessing command-line arguments via sys.argv | ||
|
|
||
| import nidcpower # NI-DCPower instrument driver | ||
|
|
||
|
|
||
| def example(resource_name, options, voltage_level_1, voltage_level_2, | ||
| voltage_level_range, current_limit, current_limit_range, | ||
| source_delay): | ||
| """Core measurement logic — sources two voltage levels sequentially and returns both measurements. | ||
|
|
||
| Args: | ||
| resource_name (str) : NI-MAX resource name, eg: "PXI1Slot2" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this consistent with all our other examples? I would imagine the documentation when setting up argparse would suffice. DRY. |
||
| options (str or dict) : Driver options, eg: "" for real HW or simulate dict for simulation | ||
| voltage_level_1 (float) : First voltage level to source (V) — must be <= voltage_level_range | ||
| voltage_level_2 (float) : Second voltage level to source (V) — must be <= voltage_level_range | ||
| voltage_level_range (float) : Voltage range — must be >= both voltage levels (V) | ||
| current_limit (float) : Current limit (A) — must be <= current_limit_range | ||
| current_limit_range (float) : Current range — must be >= current_limit (A) | ||
| source_delay (float) : Delay before Source Complete Event fires(s) | ||
| """ | ||
| # 'with' block ensures session.abort() + session.close() are called automatically on exit. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this with block only ensures session.close() is called. |
||
| # channels=0 targets channel 0; reset=True clears any previous session state. | ||
| with nidcpower.Session(resource_name=resource_name, reset=True, channels=0, options=options) as session: | ||
|
|
||
| # Configure source mode and output function. | ||
| # SINGLE_POINT: sources one value and holds; voltage_level can be changed mid-session. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instead of mid-session you should say it can be "set while in the running state" |
||
| # measure_when = AUTOMATICALLY_AFTER_SOURCE_COMPLETE: required for fetch_multiple(). | ||
| session.source_mode = nidcpower.SourceMode.SINGLE_POINT | ||
| session.output_function = nidcpower.OutputFunction.DC_VOLTAGE | ||
| session.voltage_level = voltage_level_1 | ||
| session.voltage_level_range = voltage_level_range | ||
| session.current_limit = current_limit | ||
| session.current_limit_range = current_limit_range | ||
| session.source_delay = source_delay | ||
| session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE | ||
|
|
||
| # Commit sends all settings to hardware before initiate. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in this case, there is no point in explicitly calling commit |
||
| session.commit() | ||
|
|
||
| # Initiate output, fetch at voltage_level_1, change to voltage_level_2, fetch again. | ||
| # timeout=1.0 s — adjust if source_delay is longer than 1 s. | ||
| with session.initiate(): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this context manager ensures abort() is closed |
||
| measurements1 = session.fetch_multiple(count=1, timeout=1.0) | ||
| session.voltage_level = voltage_level_2 | ||
| measurements2 = session.fetch_multiple(count=1, timeout=1.0) | ||
|
|
||
| print(f'Measurements 1: \n- Voltage: {measurements1[0][0]:f} V' | ||
| f'\n- Current: {measurements1[0][1]:f} A' | ||
| f'\n- In Compliance: {measurements1[0][2]}') | ||
| print(f'Measurements 2: \n- Voltage: {measurements2[0][0]:f} V' | ||
| f'\n- Current: {measurements2[0][1]:f} A' | ||
| f'\n- In Compliance: {measurements2[0][2]}') | ||
|
|
||
| return measurements1, measurements2 | ||
|
|
||
|
|
||
| def _main(argsv): | ||
| """Parses command-line arguments and calls example() with the parsed values.""" | ||
| parser = argparse.ArgumentParser( | ||
| description='Hardware-timed single point: source two voltage levels and measure.', | ||
| formatter_class=argparse.ArgumentDefaultsHelpFormatter | ||
| ) | ||
| parser.add_argument('-n', '--resource-name', default='PXI1Slot2/0', help='Resource name of NI SMU') | ||
| parser.add_argument('-vl1', '--voltage-level-1', default=2.0, type=float, help='First voltage level (V)') | ||
| parser.add_argument('-vl2', '--voltage-level-2', default=4.0, type=float, help='Second voltage level (V)') | ||
| parser.add_argument('-vr', '--voltage-level-range', default=10.0, type=float, help='Voltage level range — must be >= both voltage levels (V)') | ||
| parser.add_argument('-cl', '--current-limit', default=0.01, type=float, help='Current limit (A)') | ||
| parser.add_argument('-clr', '--current-limit-range', default=0.01, type=float, help='Current limit range — must be >= current-limit (A)') | ||
| parser.add_argument('-sd', '--source-delay', default=0.05, type=float, help='Source delay in seconds') | ||
| parser.add_argument('-op', '--option-string', default='', type=str, help='Driver option string, eg: "Simulate=1, DriverSetup=Model:4162; BoardType:PXIe"') | ||
| args = parser.parse_args(argsv) | ||
| example( | ||
| resource_name=args.resource_name, | ||
| options=args.option_string, | ||
| voltage_level_1=args.voltage_level_1, | ||
| voltage_level_2=args.voltage_level_2, | ||
| voltage_level_range=args.voltage_level_range, | ||
| current_limit=args.current_limit, | ||
| current_limit_range=args.current_limit_range, | ||
| source_delay=args.source_delay, | ||
| ) | ||
|
|
||
|
|
||
| def main(): | ||
| """Entry point — passes real CLI args to _main().""" | ||
| _main(sys.argv[1:]) | ||
|
|
||
|
|
||
| def test_example(): | ||
| """Simulated hardware test — runs example() with a virtual PXIe-4162 (no real HW needed).""" | ||
| options = {'simulate': True, 'driver_setup': {'Model': '4162', 'BoardType': 'PXIe'}} | ||
| example('PXI1Slot2/0', options, 2.0, 4.0, 10.0, 0.01, 0.01, 0.05) | ||
|
|
||
|
|
||
| def test_main(): | ||
| """Simulated CLI test — runs _main() with simulate option string.""" | ||
| cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'] | ||
| _main(cmd_line) | ||
|
|
||
|
|
||
| # ------------------------------------------------------------ | ||
| # Script execution starts here | ||
| # ------------------------------------------------------------ | ||
| if __name__ == '__main__': | ||
| main() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think it is wise to add scanning examples. This is a feature no longer supported by any of the switches developed in the last ~18 years.