From 4183bfa8386431218f0c3f912cc2e2547778f487 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 5 Mar 2026 17:34:50 -0800 Subject: [PATCH 01/14] PMPS implemented. Test and finalize to come. --- .../dmm/dmm_scan_pmps_16v_15c.py | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py diff --git a/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py b/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py new file mode 100644 index 0000000..0499d04 --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py @@ -0,0 +1,228 @@ +# pylint: disable=C0200 + +"""This module interacts with the NI-DMM and NI-SWITCH drivers to control NI-DMM instruments +and provide a corresponding instrument handle according to the topology selected""" + +import time + +from nipcbatt import switch +from nipcbatt import dmm +from nipcbatt.pcbatt_library.dmm.common.common_data_types import ResolutionInDigits + +#edit this list to define the configurations to use during the scan +#each entry should be a list in the format [channel, range & function, resolution] +scan_configuration = [ + [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.DC_10V, ResolutionInDigits.DIGITS_4_5], + [16, dmm.VoltageRangeAndFunctions.AC_200mV, ResolutionInDigits.DIGITS_6_5], + [17, dmm.VoltageRangeAndFunctions.AC_2V, ResolutionInDigits.DIGITS_5_5], + [18, dmm.VoltageRangeAndFunctions.AC_20V, ResolutionInDigits.DIGITS_4_5] +] + +# Data structures for output +raw_measurements = [] +formatted_measurements = [] +execution_settings = [] + + +################## INTIIALIZATION ################################################################# + +#Generate switch objects for scan +mux_generation = switch.StaticDigitalPathGeneration() +shunt_generation = switch.StaticDigitalPathGeneration() +dmm_generation = dmm.DcRmsVoltageMeasurement() + +#Close shunts to run scan +close_all_shunts = True + +#Declare constants for initialization +mux_resource_name = "Sim_MUX" +shunt_resource_name = "Sim_SHUNT" +dmm_resource_name = "Sim_DMM" + +mux_topology_name = "2527/2-Wire Dual 16x1 Mux" +shunt_topology_name = "2568/31-SPST" + +max_wait = 5000 +powerline_freq = 50 + +#Initialize objects +mux_generation.close() +shunt_generation.close() +dmm_generation.close() + +mux_generation.initialize(mux_resource_name, mux_topology_name, reset_device=True, simulate=False) +shunt_generation.initialize(shunt_resource_name, shunt_topology_name, reset_device=True, simulate=False) +dmm_generation.initialize(dmm_resource_name, powerline_freq) + +# Close all shunt relays from 16 to 30 (NI 2568) in a fixed +# channel topology mapping - option to open shunts only for 2-wire resistance measuerments +if close_all_shunts: + + #cycle across all 16 channel pairs + for i in range(15): + + #adjust channel index + idx = i + 16 + + #declare channels + ch1 = f'ch{idx}' + ch2 = f'com{idx}' + + #create channel parameters and state objects + channel_params = switch.StaticDigitalPathGenerationChannelParameters(ch1, ch2) + state = switch.StaticDigitalPathGenerationStateParameters(True) + + #configure terminal and timing settings + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) + config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + #configure and generate + shunt_generation.configure_and_generate(config) + + +############################### MEASUREMENT SCAN ########################################################## + +# extract range & function, resolution in digits and channel from scan configuration +function_range_resolution = [] +channel_list = [] +for cfg in scan_configuration: + channel_list.append(cfg[0]) + function_range_resolution.append((cfg[1], cfg[2])) + +# pair channels with respective com -- ch 0-15 -> com0, ch 16-30 -> com1 +channel_pairs = [] +for ch in channel_list: + if ch < 16: + pair = (ch, 'com0') + else: + pair = (ch, 'com1') + channel_pairs.append(pair) + +# previous function, range, resolution for comparison +prev = None + +# start wall time counter +start_time = time.perf_counter() + +# Main Scan Loop +for i in range(len(scan_configuration)): + + #extract ch (int) and com (string) + ch, com = channel_pairs[i][0], channel_pairs[i][1] + channel_name = 'ch' + str(ch) + + # MUX handling -- close MUX channel for respective ch#, com# + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(True) # Use TRUE value to CLOSE mux channel + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) + mux_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for max channel pair + mux_generation.configure_and_generate(mux_config) + + + # SHUNT handling -- if channel is a current channel, open SHUNT + if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 + com = 'com' + str(ch) + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(False) # False state to OPEN shunt + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) + shunt_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for shunt channel pair + shunt_generation.configure_and_generate(shunt_config) + + + # DMM handling -- configure and acquire measurement + function_and_range = function_range_resolution[i][0] + resolution = function_range_resolution[i][1] + + # if previous function, range, and resolution are the same skip dmm configuration, otherwise configure + if prev != function_range_resolution[i]: + + # instantiate parameters object + params = dmm.DcRmsCurrentMeasurementFunctionParameters(function_and_range, resolution) + dmm_generation.configure_measurement_function(params) + + # measure only + dmm_read = dmm_generation.session.read() + + # SHUNT handling -- close current shunt if opened + if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 + com = 'com' + str(ch) + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(True) # True state to CLOSE shunt + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) + shunt_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for shunt channel pair + shunt_generation.configure_and_generate(shunt_config) + + # MUX handling -- open MUX channel to release it + ch, com = channel_pairs[i][0], channel_pairs[i][1] + channel_name = 'ch' + str(ch) + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(False) # Use FALSE value to OPEN mux channel + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) + mux_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for max channel pair + mux_generation.configure_and_generate(mux_config) + + #measure elapsed time + switch_time = time.perf_counter() - start_time + + #store raw output + meas_type = params.measurement_function.value[0].name + value = dmm_read + raw_data = (channel_name, f'{value:.4f}', meas_type) + raw_measurements.append(raw_data) + + #store formatted measurement output + data = dmm_generation.acquire_measurement(resolution.value, dmm_read) + meas = data.measurement + formatted_meaurement = (channel_name, meas['Formatted_Measurement'], switch_time) + formatted_measurements.append(formatted_meaurement) + + #store execution ettings + exec_settings = data.dmm_execution_settings + execution_settings.append(exec_settings) + + #store current function/range/resolution settings for comparison in next loop + prev = function_range_resolution[i] + +total_time_elapsed = time.perf_counter() - start_time + +print() +print('Total Scan Time (s):', f'{total_time_elapsed: .2f}') +print() + +print(' Formatted Measurements') +print('Channel Measurement Time') +for measurement in formatted_measurements: + print(measurement) +print('\n') + +print('Execution Settings') +for setting in execution_settings: + print(setting) +print('\n') + +print(' Raw Measurements') +print('Channel Value Units') +for measurement in raw_measurements: + print(measurement) +print('\n') + + +#close and release all resources +mux_generation.close() +shunt_generation.close() +dmm_generation.close() From 72ca0313b53308e79e92b4f04558b5e1f38abb57 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 10 Mar 2026 16:52:00 -0700 Subject: [PATCH 02/14] 1) Changed range_in_digits -> resolution_in_digits in acquire_measurement( ) 2) Incorporated mixed measurement library 3) Cleaned up output formatting --- .../dmm/dmm_scan_pmps_16v_15c.py | 80 +++++++++++++------ 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py b/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py index 0499d04..37944df 100644 --- a/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py +++ b/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py @@ -1,4 +1,4 @@ -# pylint: disable=C0200 +# pylint: disable=C0200, C0103, C0301 """This module interacts with the NI-DMM and NI-SWITCH drivers to control NI-DMM instruments and provide a corresponding instrument handle according to the topology selected""" @@ -12,12 +12,13 @@ #edit this list to define the configurations to use during the scan #each entry should be a list in the format [channel, range & function, resolution] scan_configuration = [ - [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.DC_10V, ResolutionInDigits.DIGITS_4_5], - [16, dmm.VoltageRangeAndFunctions.AC_200mV, ResolutionInDigits.DIGITS_6_5], - [17, dmm.VoltageRangeAndFunctions.AC_2V, ResolutionInDigits.DIGITS_5_5], - [18, dmm.VoltageRangeAndFunctions.AC_20V, ResolutionInDigits.DIGITS_4_5] + [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.AC_2V, ResolutionInDigits.DIGITS_4_5], + [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, ResolutionInDigits.DIGITS_4_5], + [16, dmm.CurrentRangeAndFunctions.DC_100mA, ResolutionInDigits.DIGITS_6_5], + [17, dmm.CurrentRangeAndFunctions.DC_10mA, ResolutionInDigits.DIGITS_5_5], + [18, dmm.CurrentRangeAndFunctions.AC_10mA, ResolutionInDigits.DIGITS_4_5] ] # Data structures for output @@ -31,7 +32,9 @@ #Generate switch objects for scan mux_generation = switch.StaticDigitalPathGeneration() shunt_generation = switch.StaticDigitalPathGeneration() -dmm_generation = dmm.DcRmsVoltageMeasurement() + +# Generate dmm object for mixed measurements +dmm_generation = dmm.MixedMeasurement() #Close shunts to run scan close_all_shunts = True @@ -146,11 +149,11 @@ if prev != function_range_resolution[i]: # instantiate parameters object - params = dmm.DcRmsCurrentMeasurementFunctionParameters(function_and_range, resolution) + params = dmm.MixedMeasurementFunctionParameters(function_and_range, resolution) dmm_generation.configure_measurement_function(params) # measure only - dmm_read = dmm_generation.session.read() + dmm_read = dmm_generation.acquire_measurement(resolution.value) # SHUNT handling -- close current shunt if opened if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 @@ -181,12 +184,12 @@ #store raw output meas_type = params.measurement_function.value[0].name - value = dmm_read - raw_data = (channel_name, f'{value:.4f}', meas_type) + value = dmm_read.measurement + raw_data = (channel_name, value, meas_type) raw_measurements.append(raw_data) #store formatted measurement output - data = dmm_generation.acquire_measurement(resolution.value, dmm_read) + data = dmm_generation.acquire_measurement(resolution.value) meas = data.measurement formatted_meaurement = (channel_name, meas['Formatted_Measurement'], switch_time) formatted_measurements.append(formatted_meaurement) @@ -201,24 +204,53 @@ total_time_elapsed = time.perf_counter() - start_time print() +print('------------- SCAN TIME --------------') print('Total Scan Time (s):', f'{total_time_elapsed: .2f}') -print() +print('\n') + +print('------- FORMATTED MEASUREMENTS -------') +print(f'{"Channel":<10} {"Measurement":<18} {"Time":>8}') + +for i in range(len(formatted_measurements)): + measurement = formatted_measurements[i] + full_unit = raw_measurements[i][2] + + if 'DC' in full_unit: + unit = '(dc)' + elif 'AC' in full_unit: + unit = '(ac)' + else: + unit = '(ohm)' -print(' Formatted Measurements') -print('Channel Measurement Time') -for measurement in formatted_measurements: - print(measurement) + channel = measurement[0] + value = f'{measurement[1]} {unit}' + time = measurement[2] + + print(f'{channel:<10} {value:<18} {time:>8.3f}') print('\n') -print('Execution Settings') +print('--------- EXECUTION SETTINGS ---------') for setting in execution_settings: - print(setting) + for key, value in setting.items(): + print(str(key) + ': ' + str(value)) + print() print('\n') -print(' Raw Measurements') -print('Channel Value Units') -for measurement in raw_measurements: - print(measurement) + +#prepare raw measurements for output -- get largest width +values_as_str = [ + f"{m[1]['Measured_Value']:.16g}" for m in raw_measurements +] +value_width = max(len(v) for v in values_as_str) + +print('----------- RAW MEASUREMENTS -------------') +print(f'{"Channel":<10} {"Value":^23} {"Units":^8}') + +for measurement, value_str in zip(raw_measurements, values_as_str): + channel = measurement[0] + unit = measurement[1]['Unit'] + + print(f'{channel:<10} {value_str:<{value_width}} {unit:>8}') print('\n') From 1db27e1eafea5f1dc41d838e5aed0b9110d86577 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 10 Mar 2026 16:57:47 -0700 Subject: [PATCH 03/14] Changed range to resolution --- .../dmm/mixed_measurements/mixed_measurement.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py index 56ea230..e76e6b8 100644 --- a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py +++ b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py @@ -136,11 +136,11 @@ def configure_timing(self, parameters: TimingParameters): self.session.aperture_time = parameters.aperture_time_seconds self.session.settle_time = parameters.settle_time_seconds - def acquire_measurement(self, range_in_digits: float) -> MixedMeasurementResultData: + def acquire_measurement(self, resolution_in_digits: float) -> MixedMeasurementResultData: """Acquires and formats the measurement result data. Args: - range_in_digits (float): + resolution_in_digits (float): The resolution in digits used for formatting the measured value. Returns: @@ -155,7 +155,7 @@ def acquire_measurement(self, range_in_digits: float) -> MixedMeasurementResultD """ measured_value = self.session.read() measurement = FormatMeasurement.measurement( - range_in_digits=range_in_digits, + range_in_digits=resolution_in_digits, measured_value=measured_value, measurement_function=self.session.function, ) From 5f698516d97f3d0e9a1a3a017ec365c50fc986dc Mon Sep 17 00:00:00 2001 From: John Date: Thu, 12 Mar 2026 11:17:29 -0700 Subject: [PATCH 04/14] Decompositon finished. Creating DMM Scan example --- .../dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py | 50 +++ .../dmm/DMM Examples/__init__.py | 0 .../DMM_Scan_PMPS_16V_15C.py | 363 ++++++++++++++++++ .../__init__.py | 0 .../full_scan_script.py} | 3 +- .../pcbatt_library/dmm/DMM_SCAN/__init__.py | 0 .../mixed_measurements/__init__.py | 0 .../mixed_measurements/mixed_measurement.py | 0 .../mixed_measurement_constants.py | 0 .../mixed_measurement_data_types.py | 0 src/nipcbatt/pcbatt_library/dmm/__init__.py | 8 +- .../static_digital_path_data_types.py | 2 +- 12 files changed, 423 insertions(+), 3 deletions(-) create mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py create mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM Examples/__init__.py create mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py create mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/__init__.py rename src/nipcbatt/pcbatt_library/dmm/{dmm_scan_pmps_16v_15c.py => DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py} (98%) create mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/__init__.py rename src/nipcbatt/pcbatt_library/dmm/{ => DMM_SCAN}/mixed_measurements/__init__.py (100%) rename src/nipcbatt/pcbatt_library/dmm/{ => DMM_SCAN}/mixed_measurements/mixed_measurement.py (100%) rename src/nipcbatt/pcbatt_library/dmm/{ => DMM_SCAN}/mixed_measurements/mixed_measurement_constants.py (100%) rename src/nipcbatt/pcbatt_library/dmm/{ => DMM_SCAN}/mixed_measurements/mixed_measurement_data_types.py (100%) diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py b/src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py new file mode 100644 index 0000000..d1a8280 --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py @@ -0,0 +1,50 @@ +# pylint: disable=C0200, C0103, C0301 + +"""This example executes a DMM Scan to obtain 3 voltage, 3 current, + and one resistance measurement. It returns both the formatted and + the raw measurements.""" + +from nipcbatt import dmm +from nipcbatt.pcbatt_library.dmm.common.common_data_types import ResolutionInDigits + +#edit this list to define the configurations to use during the scan +#each entry should be a list in the format: +# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +scan_configuration = [ + [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.AC_2V, ResolutionInDigits.DIGITS_4_5], + [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, ResolutionInDigits.DIGITS_4_5], + [16, dmm.CurrentRangeAndFunctions.DC_100mA, ResolutionInDigits.DIGITS_6_5], + [17, dmm.CurrentRangeAndFunctions.DC_10mA, ResolutionInDigits.DIGITS_5_5], + [18, dmm.CurrentRangeAndFunctions.AC_10mA, ResolutionInDigits.DIGITS_4_5] +] + +#Declare constants for initialization +mux_resource_name = "Sim_MUX" +shunt_resource_name = "Sim_SHUNT" +dmm_resource_name = "Sim_DMM" + +mux_topology_name = "2527/2-Wire Dual 16x1 Mux" +shunt_topology_name = "2568/31-SPST" + +max_wait = 5000 +powerline_freq = 50 +close_all_shunts = True + +# Create scan object +scan = dmm.DmmScanPMPS + +#initialize scan object +resources = scan.initialize( + mux_resource_name, + mux_topology_name, + shunt_resource_name, + shunt_topology_name, + dmm_resource_name, + powerline_freq, + close_all_shunts +) + +# disconnect and close +scan.close(resources) \ No newline at end of file diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM Examples/__init__.py b/src/nipcbatt/pcbatt_library/dmm/DMM Examples/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py new file mode 100644 index 0000000..0452d3e --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py @@ -0,0 +1,363 @@ +# pylint: disable=C0200, C0103, C0301 + +"""" Defines class used for DMM Scan using PXI Mux and PXI Shunt """ + +import time +from typing import NamedTuple + +from nipcbatt import switch +from nipcbatt import dmm +from nipcbatt.pcbatt_library_core.daq.pcbatt_building_blocks import BuildingBlockUsingNISWITCH +from nipcbatt.pcbatt_library_core.daq.pcbatt_building_blocks import BuildingBlockUsingNIDMM + + +class ScanResources(NamedTuple): + """This class exists to be the return type of the initialize method of DmmScanPMPS. + It contains 2 intialized switch sessions and an intitalized dmm session + + Args: + NamedTuple: Built-in datatype to hold abstract tuples + """ + mux_generation: switch.StaticDigitalPathGeneration + shunt_generation: switch.StaticDigitalPathGeneration + dmm_generation: dmm.MixedMeasurement + +class MeasurementResult(NamedTuple): + """This class is the return type of the configure_and_measure method of DmmScanPMPS. + It contains: + sessions: The references to the switch and dmm sessions used in the measurement + scan_time: The total elapsed time of the scan + formatted_measurements: The list of all completed DMM measurments + execution_settings: The list of execution settings used in each measurement + raw_measurements: The list of raw measurements captured during the scan + + Args: + + """ + sessions: ScanResources + scan_time: float + formatted_measurements: list + execution_settings: list + raw_measurements: list + + + +class DmmScanPMPS(BuildingBlockUsingNIDMM, BuildingBlockUsingNISWITCH): + """This class represents the set of properties and methods needed + to complete a scan of different measurements using a DMM + and various switch configurations + + Args: + BuildingBlockUsingNISWITCH: The NI-SWITCH building block + BuildingBlockUsingNIDMM: The NI-DMM building block + """ + + def initialize( + self, + mux_resource_name = "Sim_MUX", + mux_topology_name = "2527/2-Wire Dual 16x1 Mux", + shunt_resource_name = "Sim_SHUNT", + shunt_topology_name = "2568/31-SPST", + dmm_resource_name = "Sim_DMM", + powerline_freq = 50, + close_all_shunts = True + ) -> ScanResources: + + """Initializes the switch and dmm objects to be used in the dmm scan + + Args: + mux_resource_name (str): The name of the mux resource. Defaults to "Sim_MUX". + mux_topology_name (str): The name of the mux topology. Defaults to "2527/2-Wire Dual 16x1 Mux". + shunt_resource_name (str): The name of the shunt resource. Defaults to "Sim_SHUNT". + shunt_topology_name (str): The name of the shunt topology. Defaults to "2568/31-SPST". + dmm_resource_name (str=): The name of the dmm resource. Defaults to "Sim_DMM". + powerline_freq (int): The power grid frequency. Defaults to 50. + close_all_shunts (bool): If true, all shunt paths will be closed. Defaults to True. + + Returns: + ScanResources: A tuple of two initialized switch sessions and one initalized dmm session + """ + + #Generate switch sessions for scan + mux_generation = switch.StaticDigitalPathGeneration() + shunt_generation = switch.StaticDigitalPathGeneration() + + # Generate dmm session for mixed measurements + dmm_generation = dmm.MixedMeasurement() + + #Initialize sessions + mux_generation.close() + shunt_generation.close() + dmm_generation.close() + + mux_generation.initialize(mux_resource_name, mux_topology_name, reset_device=True, simulate=False) + shunt_generation.initialize(shunt_resource_name, shunt_topology_name, reset_device=True, simulate=False) + dmm_generation.initialize(dmm_resource_name, powerline_freq) + + # Close all shunt relays from 16 to 30 (NI 2568) in a fixed + # channel topology mapping - option to open shunts only for 2-wire resistance measuerments + if close_all_shunts: + + #cycle across all 16 channel pairs + for i in range(15): + + #adjust channel index + idx = i + 16 + + #declare channels + ch1 = f'ch{idx}' + ch2 = f'com{idx}' + + #create channel parameters and state objects + channel_params = switch.StaticDigitalPathGenerationChannelParameters(ch1, ch2) + state = switch.StaticDigitalPathGenerationStateParameters(True) + + #configure terminal and timing settings + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters() + config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + #configure and generate + shunt_generation.configure_and_generate(config) + + #return initialized objects + return ScanResources(mux_generation, shunt_generation, dmm_generation) + + + def configure_and_measure( + self, + resource_handles: ScanResources, + scan_configuration: list, + close_all_shunts: bool = True, + verbose=True + ) -> MeasurementResult: + + """This method executes a complete scan across every measurement which is + provided in the scan_configuration input parameter + + Args: + resource_handles (ScanResources): The two switch sessions and dmm session to use + scan_configuration (list): Populate this list with every measurement you + wish to make during the scan + close_all_shunts: Set to True if all shunts were closed during initialize() + verbose(bool): If True, this will print out all of the measurement results + from the scan. Pass False if you do not wish to print results to console + + Returns: + MeasurementResult: The results of all measurements + ScanResources: Handles to each session used + """ + # extract individual resource handles from resource_handles input + mux_generation = resource_handles.mux_generation + shunt_generation = resource_handles.shunt_generation + dmm_generation = resource_handles.dmm_generation + + # extract range & function, resolution in digits and channel from scan configuration + function_range_resolution = [] + channel_list = [] + for cfg in scan_configuration: + channel_list.append(cfg[0]) + function_range_resolution.append((cfg[1], cfg[2])) + + # pair channels with respective com -- ch 0-15 -> com0, ch 16-30 -> com1 + channel_pairs = [] + for ch in channel_list: + if ch < 16: + pair = (ch, 'com0') + else: + pair = (ch, 'com1') + channel_pairs.append(pair) + + # Data structures for output + raw_measurements = [] + formatted_measurements = [] + execution_settings = [] + + # previous function, range, resolution for comparison + prev = None + + # start wall time counter + start_time = time.perf_counter() + + # Main Scan Loop + for i in range(len(scan_configuration)): + + #extract ch (int) and com (string) + ch, com = channel_pairs[i][0], channel_pairs[i][1] + channel_name = 'ch' + str(ch) + + # MUX handling -- close MUX channel for respective ch#, com# + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(True) # Use TRUE value to CLOSE mux channel + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters() + mux_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for max channel pair + mux_generation.configure_and_generate(mux_config) + + + # SHUNT handling -- if channel is a current channel, open SHUNT + if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 + com = 'com' + str(ch) + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(False) # False state to OPEN shunt + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters() + shunt_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for shunt channel pair + shunt_generation.configure_and_generate(shunt_config) + + + # DMM handling -- configure and acquire measurement + function_and_range = function_range_resolution[i][0] + resolution = function_range_resolution[i][1] + + # if previous function, range, and resolution are the same skip dmm configuration, otherwise configure + if prev != function_range_resolution[i]: + + # instantiate parameters object + params = dmm.MixedMeasurementFunctionParameters(function_and_range, resolution) + dmm_generation.configure_measurement_function(params) + + # measure only + dmm_read = dmm_generation.acquire_measurement(resolution.value) + + # SHUNT handling -- close current shunt if opened + if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 + com = 'com' + str(ch) + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(True) # True state to CLOSE shunt + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters() + shunt_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for shunt channel pair + shunt_generation.configure_and_generate(shunt_config) + + # MUX handling -- open MUX channel to release it + ch, com = channel_pairs[i][0], channel_pairs[i][1] + channel_name = 'ch' + str(ch) + channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) + state = switch.StaticDigitalPathGenerationStateParameters(False) # Use FALSE value to OPEN mux channel + ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) + timing_settings = switch.StaticDigitalPathGenerationTimingParameters() + mux_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) + + # execute configure and generate for max channel pair + mux_generation.configure_and_generate(mux_config) + + #measure elapsed time + switch_time = time.perf_counter() - start_time + + #store raw output + meas_type = params.measurement_function.value[0].name + value = dmm_read.measurement + raw_data = (channel_name, value, meas_type) + raw_measurements.append(raw_data) + + #store formatted measurement output + data = dmm_generation.acquire_measurement(resolution.value) + meas = data.measurement + formatted_meaurement = (channel_name, meas['Formatted_Measurement'], switch_time) + formatted_measurements.append(formatted_meaurement) + + #store execution ettings + exec_settings = data.dmm_execution_settings + execution_settings.append(exec_settings) + + #store current function/range/resolution settings for comparison in next loop + prev = function_range_resolution[i] + + ######### END MAIN LOOP ##################### + + #capture total scan time + total_time_elapsed = time.perf_counter() - start_time + + #if verbose = True, print results to console + if verbose: + print() + print('------------- SCAN TIME --------------') + print('Total Scan Time (s):', f'{total_time_elapsed: .2f}') + print('\n') + + print('------- FORMATTED MEASUREMENTS -------') + print(f'{"Channel":<10} {"Measurement":<18} {"Time":>8}') + + for i in range(len(formatted_measurements)): + measurement = formatted_measurements[i] + full_unit = raw_measurements[i][2] + + if 'DC' in full_unit: + unit = '(dc)' + elif 'AC' in full_unit: + unit = '(ac)' + else: + unit = '(ohm)' + + channel = measurement[0] + value = f'{measurement[1]} {unit}' + switch_time = measurement[2] + + print(f'{channel:<10} {value:<18} {switch_time:>8.3f}') + print('\n') + + print('--------- EXECUTION SETTINGS ---------') + for setting in execution_settings: + for key, value in setting.items(): + print(str(key) + ': ' + str(value)) + print() + print('\n') + + + #prepare raw measurements for output -- get largest width + values_as_str = [ + f"{m[1]['Measured_Value']:.16g}" for m in raw_measurements + ] + value_width = max(len(v) for v in values_as_str) + + print('----------- RAW MEASUREMENTS -------------') + print(f'{"Channel":<10} {"Value":^23} {"Units":^8}') + + for measurement, value_str in zip(raw_measurements, values_as_str): + channel = measurement[0] + unit = measurement[1]['Unit'] + + print(f'{channel:<10} {value_str:<{value_width}} {unit:>8}') + print('\n') + + # prepare output + output = MeasurementResult( + ScanResources(mux_generation, shunt_generation, dmm_generation), + total_time_elapsed, + formatted_measurements, + execution_settings, + raw_measurements + ) + + #return measurement result + return output + + + def close(self, resource_handles: ScanResources) -> None: + """This method disconnects, closes, and releases the resources + + Args: + resource_handles (ScanResources): Contains the sessions handles used in the scan + """ + mux_generation = resource_handles.mux_generation + shunt_generation = resource_handles.shunt_generation + dmm_generation = resource_handles.dmm_generation + + #close and release all resources + mux_generation.close() + shunt_generation.close() + dmm_generation.close() + + + + + + + diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/__init__.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py similarity index 98% rename from src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py rename to src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py index 37944df..345b29a 100644 --- a/src/nipcbatt/pcbatt_library/dmm/dmm_scan_pmps_16v_15c.py +++ b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py @@ -10,7 +10,8 @@ from nipcbatt.pcbatt_library.dmm.common.common_data_types import ResolutionInDigits #edit this list to define the configurations to use during the scan -#each entry should be a list in the format [channel, range & function, resolution] +#each entry should be a list in the format: +# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] scan_configuration = [ [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/__init__.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/__init__.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/__init__.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/mixed_measurements/__init__.py rename to src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/__init__.py diff --git a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py rename to src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement.py diff --git a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_constants.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_constants.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_constants.py rename to src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_constants.py diff --git a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_data_types.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_data_types.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_data_types.py rename to src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_data_types.py diff --git a/src/nipcbatt/pcbatt_library/dmm/__init__.py b/src/nipcbatt/pcbatt_library/dmm/__init__.py index 04977a7..17d7d7e 100644 --- a/src/nipcbatt/pcbatt_library/dmm/__init__.py +++ b/src/nipcbatt/pcbatt_library/dmm/__init__.py @@ -51,7 +51,7 @@ from nipcbatt.pcbatt_library.dmm.dc_rms_voltage_measurements.dc_rms_voltage_measurement import ( DcRmsVoltageMeasurement, ) -from nipcbatt.pcbatt_library.dmm.mixed_measurements.mixed_measurement import ( +from nipcbatt.pcbatt_library.dmm.mixed_measurements import ( MixedMeasurement, ) from nipcbatt.pcbatt_library.dmm.mixed_measurements.mixed_measurement_constants import ( @@ -87,3 +87,9 @@ from nipcbatt.pcbatt_library.dmm.resistance_measurements.resistance_measurement import ( DcRmsResistanceMeasurement, ) + +from nipcbatt.pcbatt_library.dmm.DMM_SCAN.DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C.DMM_Scan_PMPS_16V_15C import ( + ScanResources, + MeasurementResult, + DmmScanPMPS +) \ No newline at end of file diff --git a/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py b/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py index c494040..aa2124a 100644 --- a/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py +++ b/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py @@ -67,7 +67,7 @@ def connect(self) -> bool: class StaticDigitalPathGenerationTimingParameters(PCBATestToolkitData): """ Creates an instance of StaticDigitalPathGenerationTimingParameters """ - def __init__(self, max_debounce_wait: int): + def __init__(self, max_debounce_wait: int = 5000): """Defines the maximum wait for debounce time Args: From 25de86b6bc0b58e24f15115c7d89c98cd3786123 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 12 Mar 2026 16:20:28 -0700 Subject: [PATCH 05/14] Finished dmm_scan library and dmm example code --- src/nipcbatt/__init__.py | 1 + .../dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py | 50 ---- .../__init__.py | 0 .../full_scan_script.py | 261 ------------------ .../pcbatt_library/dmm/DMM_SCAN/__init__.py | 0 src/nipcbatt/pcbatt_library/dmm/__init__.py | 7 +- .../mixed_measurements/__init__.py | 0 .../mixed_measurements/mixed_measurement.py | 0 .../mixed_measurement_constants.py | 0 .../mixed_measurement_data_types.py | 0 .../DMM Examples => dmm_examples}/__init__.py | 0 .../dmm_examples/dmm_scan_pmps.py | 59 ++++ .../pcbatt_library/dmm_scan/__init__.py | 9 + .../dmm_scan_pmps_16V_15C.py} | 5 +- 14 files changed, 72 insertions(+), 320 deletions(-) delete mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py delete mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/__init__.py delete mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py delete mode 100644 src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/__init__.py rename src/nipcbatt/pcbatt_library/dmm/{DMM_SCAN => }/mixed_measurements/__init__.py (100%) rename src/nipcbatt/pcbatt_library/dmm/{DMM_SCAN => }/mixed_measurements/mixed_measurement.py (100%) rename src/nipcbatt/pcbatt_library/dmm/{DMM_SCAN => }/mixed_measurements/mixed_measurement_constants.py (100%) rename src/nipcbatt/pcbatt_library/dmm/{DMM_SCAN => }/mixed_measurements/mixed_measurement_data_types.py (100%) rename src/nipcbatt/pcbatt_library/{dmm/DMM Examples => dmm_examples}/__init__.py (100%) create mode 100644 src/nipcbatt/pcbatt_library/dmm_examples/dmm_scan_pmps.py create mode 100644 src/nipcbatt/pcbatt_library/dmm_scan/__init__.py rename src/nipcbatt/pcbatt_library/{dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py => dmm_scan/dmm_scan_pmps_16V_15C.py} (99%) diff --git a/src/nipcbatt/__init__.py b/src/nipcbatt/__init__.py index 1726d1a..5bd5bad 100644 --- a/src/nipcbatt/__init__.py +++ b/src/nipcbatt/__init__.py @@ -18,6 +18,7 @@ from nipcbatt.pcbatt_library import dmm from nipcbatt.pcbatt_library import communications from nipcbatt.pcbatt_library import switch +from nipcbatt.pcbatt_library import dmm_scan from nipcbatt.pcbatt_analysis.analysis_library_exceptions import ( PCBATTAnalysisCallNativeLibraryFailedException, diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py b/src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py deleted file mode 100644 index d1a8280..0000000 --- a/src/nipcbatt/pcbatt_library/dmm/DMM Examples/DMM SCAN PMPS 16V_15C.py +++ /dev/null @@ -1,50 +0,0 @@ -# pylint: disable=C0200, C0103, C0301 - -"""This example executes a DMM Scan to obtain 3 voltage, 3 current, - and one resistance measurement. It returns both the formatted and - the raw measurements.""" - -from nipcbatt import dmm -from nipcbatt.pcbatt_library.dmm.common.common_data_types import ResolutionInDigits - -#edit this list to define the configurations to use during the scan -#each entry should be a list in the format: -# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] -scan_configuration = [ - [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.AC_2V, ResolutionInDigits.DIGITS_4_5], - [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, ResolutionInDigits.DIGITS_4_5], - [16, dmm.CurrentRangeAndFunctions.DC_100mA, ResolutionInDigits.DIGITS_6_5], - [17, dmm.CurrentRangeAndFunctions.DC_10mA, ResolutionInDigits.DIGITS_5_5], - [18, dmm.CurrentRangeAndFunctions.AC_10mA, ResolutionInDigits.DIGITS_4_5] -] - -#Declare constants for initialization -mux_resource_name = "Sim_MUX" -shunt_resource_name = "Sim_SHUNT" -dmm_resource_name = "Sim_DMM" - -mux_topology_name = "2527/2-Wire Dual 16x1 Mux" -shunt_topology_name = "2568/31-SPST" - -max_wait = 5000 -powerline_freq = 50 -close_all_shunts = True - -# Create scan object -scan = dmm.DmmScanPMPS - -#initialize scan object -resources = scan.initialize( - mux_resource_name, - mux_topology_name, - shunt_resource_name, - shunt_topology_name, - dmm_resource_name, - powerline_freq, - close_all_shunts -) - -# disconnect and close -scan.close(resources) \ No newline at end of file diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/__init__.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py deleted file mode 100644 index 345b29a..0000000 --- a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/full_scan_script.py +++ /dev/null @@ -1,261 +0,0 @@ -# pylint: disable=C0200, C0103, C0301 - -"""This module interacts with the NI-DMM and NI-SWITCH drivers to control NI-DMM instruments -and provide a corresponding instrument handle according to the topology selected""" - -import time - -from nipcbatt import switch -from nipcbatt import dmm -from nipcbatt.pcbatt_library.dmm.common.common_data_types import ResolutionInDigits - -#edit this list to define the configurations to use during the scan -#each entry should be a list in the format: -# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] -scan_configuration = [ - [0, dmm.VoltageRangeAndFunctions.DC_100mV, ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_1V, ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.AC_2V, ResolutionInDigits.DIGITS_4_5], - [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, ResolutionInDigits.DIGITS_4_5], - [16, dmm.CurrentRangeAndFunctions.DC_100mA, ResolutionInDigits.DIGITS_6_5], - [17, dmm.CurrentRangeAndFunctions.DC_10mA, ResolutionInDigits.DIGITS_5_5], - [18, dmm.CurrentRangeAndFunctions.AC_10mA, ResolutionInDigits.DIGITS_4_5] -] - -# Data structures for output -raw_measurements = [] -formatted_measurements = [] -execution_settings = [] - - -################## INTIIALIZATION ################################################################# - -#Generate switch objects for scan -mux_generation = switch.StaticDigitalPathGeneration() -shunt_generation = switch.StaticDigitalPathGeneration() - -# Generate dmm object for mixed measurements -dmm_generation = dmm.MixedMeasurement() - -#Close shunts to run scan -close_all_shunts = True - -#Declare constants for initialization -mux_resource_name = "Sim_MUX" -shunt_resource_name = "Sim_SHUNT" -dmm_resource_name = "Sim_DMM" - -mux_topology_name = "2527/2-Wire Dual 16x1 Mux" -shunt_topology_name = "2568/31-SPST" - -max_wait = 5000 -powerline_freq = 50 - -#Initialize objects -mux_generation.close() -shunt_generation.close() -dmm_generation.close() - -mux_generation.initialize(mux_resource_name, mux_topology_name, reset_device=True, simulate=False) -shunt_generation.initialize(shunt_resource_name, shunt_topology_name, reset_device=True, simulate=False) -dmm_generation.initialize(dmm_resource_name, powerline_freq) - -# Close all shunt relays from 16 to 30 (NI 2568) in a fixed -# channel topology mapping - option to open shunts only for 2-wire resistance measuerments -if close_all_shunts: - - #cycle across all 16 channel pairs - for i in range(15): - - #adjust channel index - idx = i + 16 - - #declare channels - ch1 = f'ch{idx}' - ch2 = f'com{idx}' - - #create channel parameters and state objects - channel_params = switch.StaticDigitalPathGenerationChannelParameters(ch1, ch2) - state = switch.StaticDigitalPathGenerationStateParameters(True) - - #configure terminal and timing settings - ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) - timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) - config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) - - #configure and generate - shunt_generation.configure_and_generate(config) - - -############################### MEASUREMENT SCAN ########################################################## - -# extract range & function, resolution in digits and channel from scan configuration -function_range_resolution = [] -channel_list = [] -for cfg in scan_configuration: - channel_list.append(cfg[0]) - function_range_resolution.append((cfg[1], cfg[2])) - -# pair channels with respective com -- ch 0-15 -> com0, ch 16-30 -> com1 -channel_pairs = [] -for ch in channel_list: - if ch < 16: - pair = (ch, 'com0') - else: - pair = (ch, 'com1') - channel_pairs.append(pair) - -# previous function, range, resolution for comparison -prev = None - -# start wall time counter -start_time = time.perf_counter() - -# Main Scan Loop -for i in range(len(scan_configuration)): - - #extract ch (int) and com (string) - ch, com = channel_pairs[i][0], channel_pairs[i][1] - channel_name = 'ch' + str(ch) - - # MUX handling -- close MUX channel for respective ch#, com# - channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) - state = switch.StaticDigitalPathGenerationStateParameters(True) # Use TRUE value to CLOSE mux channel - ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) - timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) - mux_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) - - # execute configure and generate for max channel pair - mux_generation.configure_and_generate(mux_config) - - - # SHUNT handling -- if channel is a current channel, open SHUNT - if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 - com = 'com' + str(ch) - channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) - state = switch.StaticDigitalPathGenerationStateParameters(False) # False state to OPEN shunt - ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) - timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) - shunt_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) - - # execute configure and generate for shunt channel pair - shunt_generation.configure_and_generate(shunt_config) - - - # DMM handling -- configure and acquire measurement - function_and_range = function_range_resolution[i][0] - resolution = function_range_resolution[i][1] - - # if previous function, range, and resolution are the same skip dmm configuration, otherwise configure - if prev != function_range_resolution[i]: - - # instantiate parameters object - params = dmm.MixedMeasurementFunctionParameters(function_and_range, resolution) - dmm_generation.configure_measurement_function(params) - - # measure only - dmm_read = dmm_generation.acquire_measurement(resolution.value) - - # SHUNT handling -- close current shunt if opened - if ch >= 16 and close_all_shunts: # current channels are ch16 - ch30 - com = 'com' + str(ch) - channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) - state = switch.StaticDigitalPathGenerationStateParameters(True) # True state to CLOSE shunt - ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) - timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) - shunt_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) - - # execute configure and generate for shunt channel pair - shunt_generation.configure_and_generate(shunt_config) - - # MUX handling -- open MUX channel to release it - ch, com = channel_pairs[i][0], channel_pairs[i][1] - channel_name = 'ch' + str(ch) - channel_params = switch.StaticDigitalPathGenerationChannelParameters(channel_name, com) - state = switch.StaticDigitalPathGenerationStateParameters(False) # Use FALSE value to OPEN mux channel - ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) - timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait) - mux_config = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) - - # execute configure and generate for max channel pair - mux_generation.configure_and_generate(mux_config) - - #measure elapsed time - switch_time = time.perf_counter() - start_time - - #store raw output - meas_type = params.measurement_function.value[0].name - value = dmm_read.measurement - raw_data = (channel_name, value, meas_type) - raw_measurements.append(raw_data) - - #store formatted measurement output - data = dmm_generation.acquire_measurement(resolution.value) - meas = data.measurement - formatted_meaurement = (channel_name, meas['Formatted_Measurement'], switch_time) - formatted_measurements.append(formatted_meaurement) - - #store execution ettings - exec_settings = data.dmm_execution_settings - execution_settings.append(exec_settings) - - #store current function/range/resolution settings for comparison in next loop - prev = function_range_resolution[i] - -total_time_elapsed = time.perf_counter() - start_time - -print() -print('------------- SCAN TIME --------------') -print('Total Scan Time (s):', f'{total_time_elapsed: .2f}') -print('\n') - -print('------- FORMATTED MEASUREMENTS -------') -print(f'{"Channel":<10} {"Measurement":<18} {"Time":>8}') - -for i in range(len(formatted_measurements)): - measurement = formatted_measurements[i] - full_unit = raw_measurements[i][2] - - if 'DC' in full_unit: - unit = '(dc)' - elif 'AC' in full_unit: - unit = '(ac)' - else: - unit = '(ohm)' - - channel = measurement[0] - value = f'{measurement[1]} {unit}' - time = measurement[2] - - print(f'{channel:<10} {value:<18} {time:>8.3f}') -print('\n') - -print('--------- EXECUTION SETTINGS ---------') -for setting in execution_settings: - for key, value in setting.items(): - print(str(key) + ': ' + str(value)) - print() -print('\n') - - -#prepare raw measurements for output -- get largest width -values_as_str = [ - f"{m[1]['Measured_Value']:.16g}" for m in raw_measurements -] -value_width = max(len(v) for v in values_as_str) - -print('----------- RAW MEASUREMENTS -------------') -print(f'{"Channel":<10} {"Value":^23} {"Units":^8}') - -for measurement, value_str in zip(raw_measurements, values_as_str): - channel = measurement[0] - unit = measurement[1]['Unit'] - - print(f'{channel:<10} {value_str:<{value_width}} {unit:>8}') -print('\n') - - -#close and release all resources -mux_generation.close() -shunt_generation.close() -dmm_generation.close() diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/__init__.py b/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/nipcbatt/pcbatt_library/dmm/__init__.py b/src/nipcbatt/pcbatt_library/dmm/__init__.py index 17d7d7e..55b6bd7 100644 --- a/src/nipcbatt/pcbatt_library/dmm/__init__.py +++ b/src/nipcbatt/pcbatt_library/dmm/__init__.py @@ -51,7 +51,7 @@ from nipcbatt.pcbatt_library.dmm.dc_rms_voltage_measurements.dc_rms_voltage_measurement import ( DcRmsVoltageMeasurement, ) -from nipcbatt.pcbatt_library.dmm.mixed_measurements import ( +from nipcbatt.pcbatt_library.dmm.mixed_measurements.mixed_measurement import ( MixedMeasurement, ) from nipcbatt.pcbatt_library.dmm.mixed_measurements.mixed_measurement_constants import ( @@ -88,8 +88,3 @@ DcRmsResistanceMeasurement, ) -from nipcbatt.pcbatt_library.dmm.DMM_SCAN.DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C.DMM_Scan_PMPS_16V_15C import ( - ScanResources, - MeasurementResult, - DmmScanPMPS -) \ No newline at end of file diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/__init__.py b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/__init__.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/__init__.py rename to src/nipcbatt/pcbatt_library/dmm/mixed_measurements/__init__.py diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement.py b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement.py rename to src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_constants.py b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_constants.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_constants.py rename to src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_constants.py diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_data_types.py b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_data_types.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/mixed_measurements/mixed_measurement_data_types.py rename to src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement_data_types.py diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM Examples/__init__.py b/src/nipcbatt/pcbatt_library/dmm_examples/__init__.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm/DMM Examples/__init__.py rename to src/nipcbatt/pcbatt_library/dmm_examples/__init__.py diff --git a/src/nipcbatt/pcbatt_library/dmm_examples/dmm_scan_pmps.py b/src/nipcbatt/pcbatt_library/dmm_examples/dmm_scan_pmps.py new file mode 100644 index 0000000..28103e0 --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm_examples/dmm_scan_pmps.py @@ -0,0 +1,59 @@ +# pylint: disable=C0200, C0103, C0301 + +"""This example executes a DMM Scan to obtain 3 voltage, 3 current, + and one resistance measurement. It returns both the formatted and + the raw measurements.""" + +from nipcbatt import dmm +from nipcbatt import dmm_scan + +############### DECLARE INPUT VALUES ######################################################## + +# edit this list to define the configurations to use during the scan +# each entry should be a list in the format below: +# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +scan_configuration = [ + [0, dmm.VoltageRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.CurrentRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.CurrentRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] +] + +#Declare constants for initialization +mux_resource_name = "Sim_MUX" +shunt_resource_name = "Sim_SHUNT" +dmm_resource_name = "Sim_DMM" + +mux_topology_name = "2527/2-Wire Dual 16x1 Mux" +shunt_topology_name = "2568/31-SPST" + +max_wait = 5000 +powerline_freq = 50 +close_all_shunts = True +verbose = True # Set to False to not print measurements to console + + +############ EXECUTE SCAN #################################################################### + +# Create scan object +scan = dmm_scan.DmmScanPMPS() + +# Initialize scan object +resources = scan.initialize( + mux_resource_name, + mux_topology_name, + shunt_resource_name, + shunt_topology_name, + dmm_resource_name, + powerline_freq, + close_all_shunts +) + +# Execute scan +results = scan.configure_and_measure(resources, scan_configuration, close_all_shunts, verbose) + +# Disconnect and close resources +scan.close(resources) diff --git a/src/nipcbatt/pcbatt_library/dmm_scan/__init__.py b/src/nipcbatt/pcbatt_library/dmm_scan/__init__.py new file mode 100644 index 0000000..fc7ee9e --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm_scan/__init__.py @@ -0,0 +1,9 @@ +# pylint: disable=C0200, C0103, C0301 + +""" Contains classes used in dmm scan""" + +from nipcbatt.pcbatt_library.dmm_scan.dmm_scan_pmps_16V_15C import ( + ScanResources, + MeasurementResult, + DmmScanPMPS +) \ No newline at end of file diff --git a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py similarity index 99% rename from src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py rename to src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py index 0452d3e..e09d0e6 100644 --- a/src/nipcbatt/pcbatt_library/dmm/DMM_SCAN/DMM_Scan_PXI_Mux_PXI_Shunt_16V_15C/DMM_Scan_PMPS_16V_15C.py +++ b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py @@ -39,7 +39,6 @@ class MeasurementResult(NamedTuple): formatted_measurements: list execution_settings: list raw_measurements: list - class DmmScanPMPS(BuildingBlockUsingNIDMM, BuildingBlockUsingNISWITCH): @@ -77,14 +76,14 @@ def initialize( Returns: ScanResources: A tuple of two initialized switch sessions and one initalized dmm session """ - + #Generate switch sessions for scan mux_generation = switch.StaticDigitalPathGeneration() shunt_generation = switch.StaticDigitalPathGeneration() # Generate dmm session for mixed measurements dmm_generation = dmm.MixedMeasurement() - + #Initialize sessions mux_generation.close() shunt_generation.close() From 50f387bd8f0dbfa2f0caef7d7da952462dbd9947 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 12 Mar 2026 16:55:54 -0700 Subject: [PATCH 06/14] Renamed dmm scan examples folder --- .../{dmm_examples => dmm_scan_examples}/__init__.py | 0 .../{dmm_examples => dmm_scan_examples}/dmm_scan_pmps.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/nipcbatt/pcbatt_library/{dmm_examples => dmm_scan_examples}/__init__.py (100%) rename src/nipcbatt/pcbatt_library/{dmm_examples => dmm_scan_examples}/dmm_scan_pmps.py (100%) diff --git a/src/nipcbatt/pcbatt_library/dmm_examples/__init__.py b/src/nipcbatt/pcbatt_library/dmm_scan_examples/__init__.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm_examples/__init__.py rename to src/nipcbatt/pcbatt_library/dmm_scan_examples/__init__.py diff --git a/src/nipcbatt/pcbatt_library/dmm_examples/dmm_scan_pmps.py b/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm_examples/dmm_scan_pmps.py rename to src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps.py From 45f29c0c803a842ff855bdeed3d3c9bb991e2e08 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 12 Mar 2026 17:04:23 -0700 Subject: [PATCH 07/14] Filename change --- .../{dmm_scan_pmps.py => dmm_scan_pmps_example.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/nipcbatt/pcbatt_library/dmm_scan_examples/{dmm_scan_pmps.py => dmm_scan_pmps_example.py} (100%) diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps.py b/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps_example.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps.py rename to src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps_example.py From dd8b3e03bdb4304372a3b1a17dd76f5ea256b06a Mon Sep 17 00:00:00 2001 From: John Date: Mon, 16 Mar 2026 11:18:35 -0700 Subject: [PATCH 08/14] Fixed resolution_in_digits to match main lib Fixed comments for clarity Added params = None before main loop for code robustness Fixed dmm_read so it only happens once instead of twice Fixed typos --- .../dmm/common/helper_functions.py | 6 +++--- .../mixed_measurements/mixed_measurement.py | 2 +- .../dmm_scan/dmm_scan_pmps_16V_15C.py | 20 ++++++++++--------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py b/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py index 6e05138..010632c 100644 --- a/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py +++ b/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py @@ -116,12 +116,12 @@ def format_with_si_prefix(measured_value: float, total_digits: int) -> tuple[str @staticmethod def measurement( - range_in_digits: float, measured_value: float, measurement_function: nidmm.Function = None + resolution_in_digits: float, measured_value: float, measurement_function: nidmm.Function = None ) -> dict: """Formats the measurement value according to the specified resolution. Args: - range_in_digits: Resolution in digits (e.g., 6.5 for 6.5 digit resolution) + resolution_in_digits: Resolution in digits (e.g., 6.5 for 6.5 digit resolution) measured_value: The measured value to format measurement_function: Optional nidmm.Function to append appropriate unit @@ -154,7 +154,7 @@ def measurement( "Unit": unit, } - total_digits = int(range_in_digits) + 1 + total_digits = int(resolution_in_digits) + 1 formatted_number, prefix = FormatMeasurement.format_with_si_prefix( measured_value, total_digits ) diff --git a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py index e76e6b8..891eaf9 100644 --- a/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py +++ b/src/nipcbatt/pcbatt_library/dmm/mixed_measurements/mixed_measurement.py @@ -155,7 +155,7 @@ def acquire_measurement(self, resolution_in_digits: float) -> MixedMeasurementRe """ measured_value = self.session.read() measurement = FormatMeasurement.measurement( - range_in_digits=resolution_in_digits, + resolution_in_digits=resolution_in_digits, measured_value=measured_value, measurement_function=self.session.function, ) diff --git a/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py index e09d0e6..2f64391 100644 --- a/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py +++ b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py @@ -1,6 +1,6 @@ # pylint: disable=C0200, C0103, C0301 -"""" Defines class used for DMM Scan using PXI Mux and PXI Shunt """ +""" Defines class used for DMM Scan using PXI Mux and PXI Shunt """ import time from typing import NamedTuple @@ -32,6 +32,7 @@ class MeasurementResult(NamedTuple): raw_measurements: The list of raw measurements captured during the scan Args: + NamedTuple: Built-in datatype to hold abstract tuples """ sessions: ScanResources @@ -40,7 +41,6 @@ class MeasurementResult(NamedTuple): execution_settings: list raw_measurements: list - class DmmScanPMPS(BuildingBlockUsingNIDMM, BuildingBlockUsingNISWITCH): """This class represents the set of properties and methods needed to complete a scan of different measurements using a DMM @@ -83,12 +83,13 @@ def initialize( # Generate dmm session for mixed measurements dmm_generation = dmm.MixedMeasurement() - - #Initialize sessions + + # Ensure sessions are cleared before use mux_generation.close() shunt_generation.close() dmm_generation.close() - + + #Initialize sessions mux_generation.initialize(mux_resource_name, mux_topology_name, reset_device=True, simulate=False) shunt_generation.initialize(shunt_resource_name, shunt_topology_name, reset_device=True, simulate=False) dmm_generation.initialize(dmm_resource_name, powerline_freq) @@ -174,6 +175,7 @@ def configure_and_measure( # previous function, range, resolution for comparison prev = None + params = None # start wall time counter start_time = time.perf_counter() @@ -257,12 +259,12 @@ def configure_and_measure( raw_measurements.append(raw_data) #store formatted measurement output - data = dmm_generation.acquire_measurement(resolution.value) + data = dmm_read meas = data.measurement - formatted_meaurement = (channel_name, meas['Formatted_Measurement'], switch_time) - formatted_measurements.append(formatted_meaurement) + formatted_measurement = (channel_name, meas['Formatted_Measurement'], switch_time) + formatted_measurements.append(formatted_measurement) - #store execution ettings + #store execution settings exec_settings = data.dmm_execution_settings execution_settings.append(exec_settings) From 26be54499dc1d877a8f18cb202df25630fe3044b Mon Sep 17 00:00:00 2001 From: John Date: Mon, 16 Mar 2026 14:36:38 -0700 Subject: [PATCH 09/14] Artifact bug from merging in main --- src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py b/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py index 6ba6024..e94f722 100644 --- a/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py +++ b/src/nipcbatt/pcbatt_library/dmm/common/helper_functions.py @@ -116,13 +116,9 @@ def format_with_si_prefix(measured_value: float, total_digits: int) -> tuple[str @staticmethod def measurement( -<<<<<<< HEAD - resolution_in_digits: float, measured_value: float, measurement_function: nidmm.Function = None -======= resolution_in_digits: float, measured_value: float, measurement_function: nidmm.Function = None, ->>>>>>> main ) -> dict: """Formats the measurement value according to the specified resolution. From 01920e7a65a2d3ab1d110aed9d38d143ef421ba6 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 16 Mar 2026 15:20:19 -0700 Subject: [PATCH 10/14] no message --- .../pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py index 2f64391..3f81350 100644 --- a/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py +++ b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py @@ -76,7 +76,7 @@ def initialize( Returns: ScanResources: A tuple of two initialized switch sessions and one initalized dmm session """ - + #Generate switch sessions for scan mux_generation = switch.StaticDigitalPathGeneration() shunt_generation = switch.StaticDigitalPathGeneration() @@ -88,7 +88,7 @@ def initialize( mux_generation.close() shunt_generation.close() dmm_generation.close() - + #Initialize sessions mux_generation.initialize(mux_resource_name, mux_topology_name, reset_device=True, simulate=False) shunt_generation.initialize(shunt_resource_name, shunt_topology_name, reset_device=True, simulate=False) @@ -348,7 +348,7 @@ def close(self, resource_handles: ScanResources) -> None: resource_handles (ScanResources): Contains the sessions handles used in the scan """ mux_generation = resource_handles.mux_generation - shunt_generation = resource_handles.shunt_generation + shunt_generation = resource_handles.shunt_generation dmm_generation = resource_handles.dmm_generation #close and release all resources From f5fef08dedda3a3fa15f3d61949a0058878abc99 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 16 Mar 2026 16:09:43 -0700 Subject: [PATCH 11/14] Created two scan and loop scan examples --- .../dmm_loop_scan_pmps_example.py | 68 ++++++++++++++++ .../dmm_two_scan_pmps_example.py | 77 +++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_loop_scan_pmps_example.py create mode 100644 src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_two_scan_pmps_example.py diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_loop_scan_pmps_example.py b/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_loop_scan_pmps_example.py new file mode 100644 index 0000000..d8f4460 --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_loop_scan_pmps_example.py @@ -0,0 +1,68 @@ +# pylint: disable=C0200, C0103, C0301 + +"""This example executes a DMM Scan to obtain 3 voltage, 3 current, + and one resistance measurement. It returns both the formatted and + the raw measurements.""" + +from nipcbatt import dmm +from nipcbatt import dmm_scan + +############### DECLARE INPUT VALUES ######################################################## + +# edit this list to define the configurations to use during the scan +# each entry should be a list in the format below: +# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +scan_configuration = [ + [0, dmm.VoltageRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.CurrentRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.CurrentRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] +] + +#Declare constants for initialization +mux_resource_name = "Sim_MUX" +shunt_resource_name = "Sim_SHUNT" +dmm_resource_name = "Sim_DMM" + +mux_topology_name = "2527/2-Wire Dual 16x1 Mux" +shunt_topology_name = "2568/31-SPST" + +max_wait = 5000 +powerline_freq = 50 +close_all_shunts = True +verbose = True # Set to False to not print measurements to console + +############ EXECUTE SCAN #################################################################### + +# Create scan object +scan = dmm_scan.DmmScanPMPS() + +# Initialize scan object +resources = scan.initialize( + mux_resource_name, + mux_topology_name, + shunt_resource_name, + shunt_topology_name, + dmm_resource_name, + powerline_freq, + close_all_shunts +) + +print('\n') + +# Execute scan loop +for i in range(len(scan_configuration)): + + print(f"########################### LOOP {i + 1} #######################################") + + #convert single element to list for compatibility inside configure_and_measure + cfg = [scan_configuration[i]] + + #execute measurement + results = scan.configure_and_measure(resources, cfg, close_all_shunts, verbose) + +# Disconnect and close resources +scan.close(resources) diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_two_scan_pmps_example.py b/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_two_scan_pmps_example.py new file mode 100644 index 0000000..031a793 --- /dev/null +++ b/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_two_scan_pmps_example.py @@ -0,0 +1,77 @@ +# pylint: disable=C0200, C0103, C0301 + +"""This example executes a DMM Scan to obtain 3 voltage, 3 current, + and one resistance measurement. It returns both the formatted and + the raw measurements.""" + +from nipcbatt import dmm +from nipcbatt import dmm_scan + +############### DECLARE INPUT VALUES ######################################################## + +# edit these lists to define the configurations to use during the scan +# each entry should be a list in the format below: +# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +scan_configuration1 = [ + [0, dmm.VoltageRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.CurrentRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.CurrentRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] +] + +scan_configuration2 = [ + [0, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.VoltageRangeAndFunctions.DC_10V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.VoltageRangeAndFunctions.DC_100V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.ResistanceRangeAndFunctions.FOUR_W_RES_1k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.CurrentRangeAndFunctions.DC_100uA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.CurrentRangeAndFunctions.DC_1mA, dmm.ResolutionInDigits.DIGITS_4_5] +] + +#Declare constants for initialization +mux_resource_name = "Sim_MUX" +shunt_resource_name = "Sim_SHUNT" +dmm_resource_name = "Sim_DMM" + +mux_topology_name = "2527/2-Wire Dual 16x1 Mux" +shunt_topology_name = "2568/31-SPST" + +max_wait = 5000 +powerline_freq = 50 +close_all_shunts = True +verbose = True # Set to False to not print measurements to console + +############ EXECUTE SCANS #################################################################### + +# Create scan object +scan = dmm_scan.DmmScanPMPS() + +# Initialize scan object +resources = scan.initialize( + mux_resource_name, + mux_topology_name, + shunt_resource_name, + shunt_topology_name, + dmm_resource_name, + powerline_freq, + close_all_shunts +) + +# Execute first scan +print('\n\n\n') +print('############################ SCAN 1 ##################################################') + +results = scan.configure_and_measure(resources, scan_configuration1, close_all_shunts, verbose) + +# Execute second scan +print('\n\n\n') +print('############################ SCAN 2 ##################################################') + +results = scan.configure_and_measure(resources, scan_configuration2, close_all_shunts, verbose) + +# Disconnect and close resources +scan.close(resources) \ No newline at end of file From a669238e00933660f61cbae2037485af8d461138 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 17 Mar 2026 17:43:44 -0700 Subject: [PATCH 12/14] 1) Implemented Emmanuel's suggestions from word doc 2) Re-factored switch code and integration tests to factor in PathCapability 3) switch configured_and_generate now returns a Module Characteristics object 4) Moved dmm_scan examples to validation examples folder and deleted existing folder 5) --- .../dmm_scan/dmm_scan_pmps_16V_15C.py | 8 +- .../dmm_scan_examples/__init__.py | 0 .../static_digital_path_data_types.py | 16 ++ .../static_digital_path_generation.py | 76 +++++++++- .../dmm_loop_scan_pmps_example.py | 0 .../dmm_scan_pmps_example.py | 0 .../dmm_two_scan_pmps_example.py | 0 .../default_ni_switch_generation.py | 19 ++- .../switch_validate_path_status.py | 63 ++++++++ ...egration_static_digital_path_generation.py | 139 ++++++------------ 10 files changed, 212 insertions(+), 109 deletions(-) delete mode 100644 src/nipcbatt/pcbatt_library/dmm_scan_examples/__init__.py rename src/nipcbatt/{pcbatt_library/dmm_scan_examples => pcbatt_validation_examples/DMM_SCAN_examples}/dmm_loop_scan_pmps_example.py (100%) rename src/nipcbatt/{pcbatt_library/dmm_scan_examples => pcbatt_validation_examples/DMM_SCAN_examples}/dmm_scan_pmps_example.py (100%) rename src/nipcbatt/{pcbatt_library/dmm_scan_examples => pcbatt_validation_examples/DMM_SCAN_examples}/dmm_two_scan_pmps_example.py (100%) create mode 100644 src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py diff --git a/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py index 3f81350..07909b0 100644 --- a/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py +++ b/src/nipcbatt/pcbatt_library/dmm_scan/dmm_scan_pmps_16V_15C.py @@ -319,13 +319,17 @@ def configure_and_measure( value_width = max(len(v) for v in values_as_str) print('----------- RAW MEASUREMENTS -------------') - print(f'{"Channel":<10} {"Value":^23} {"Units":^8}') + print(f'{"Channel":<10} {"Value":^23} {"Units":^6}') for measurement, value_str in zip(raw_measurements, values_as_str): channel = measurement[0] unit = measurement[1]['Unit'] + if 'DC' in measurement[2]: + unit += ' (dc)' + elif 'AC' in measurement[2]: + unit += ' (ac)' - print(f'{channel:<10} {value_str:<{value_width}} {unit:>8}') + print(f'{channel:<10} {value_str:<{value_width}} {unit:^11}') print('\n') # prepare output diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/__init__.py b/src/nipcbatt/pcbatt_library/dmm_scan_examples/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py b/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py index aa2124a..c5b174f 100644 --- a/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py +++ b/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_data_types.py @@ -172,6 +172,21 @@ def max_ac_voltage(self) -> float: """ return self._max_ac_voltage + @property + def max_switching_dc_current(self) -> float: + """ + :type:'float': Returns the max dc switching current + """ + return self._max_switching_dc_current + + @property + def max_switching_ac_current(self) -> float: + """ + :type:'float': Returns the max ac switching current + """ + return self._max_switching_ac_current + + class StaticDigitalPathGenerationConfiguration(PCBATestToolkitData): """ Contains the ultimate configuration used in path generation """ @@ -235,3 +250,4 @@ def path_status(self) -> niswitch.PathCapability: """ return self._path_status + diff --git a/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_generation.py b/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_generation.py index 4f0ae44..da4218c 100644 --- a/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_generation.py +++ b/src/nipcbatt/pcbatt_library/switch/static_digital_path_generations/static_digital_path_generation.py @@ -45,7 +45,7 @@ def initialize(self, topology_name: str, reset_device: bool = True, simulate: bool = False - ) -> None: + ) -> StaticDigitalPathGenerationModuleCharacteristics: """Initializes the session to prepare for path generation Args: @@ -81,6 +81,17 @@ def initialize(self, #assign session self._instrument = session + # populate module characteristics + module_characteristics = StaticDigitalPathGenerationModuleCharacteristics( + self.session.max_dc_voltage, + self.session.max_ac_voltage, + self.session.max_switching_dc_current, + self.session.max_switching_ac_current + ) + + #return the utilized moduel characteristics + return module_characteristics + def close(self): """Disconnects all channels, closes the session and returns the resource""" if not self.is_session_initialized: @@ -102,6 +113,8 @@ def configure_and_generate( Args: terminal_and_state_settings: Contains both the channel and state to employ + + Returns: A StaticDigitalPathGenerationPathStatus object containing the path status """ #extract channels and state to employ @@ -115,9 +128,9 @@ def configure_and_generate( #verify channels can be connected path_capability = self.session.can_connect(channel_one, channel_two) - #connect/disconnect/ignore depending on path capability - if path_capability.PATH_AVAILABLE or path_capability.PATH_EXISTS: - + #connect depending on path capability + if path_capability == niswitch.PathCapability.PATH_AVAILABLE: + #if connecting make connection, else disconnect if connect: self.session.connect(channel_one, channel_two) @@ -127,12 +140,59 @@ def configure_and_generate( #wait for maximum debounce time self.session.wait_for_debounce(max_wait) - #if the path is not available or doesn't exist, do nothing - else: - pass + #if the path is connected and connect is False + elif connect is False and path_capability == niswitch.PathCapability.PATH_EXISTS: + + # disconnect + self.session.disconnect(channel_one, channel_two) + + # populate path status object + path_status = StaticDigitalPathGenerationPathStatus(path_capability) #return path capbility inside path status object - return StaticDigitalPathGenerationPathStatus(path_capability) + return path_status + + + + def display_status(self, status: StaticDigitalPathGenerationPathStatus) -> None: + """Takes in a StaticDigitalPathGenerationPathStatus object and + prints the contents in human-readable format based on the status + + Args: + path_status (StaticDigitalPathGenerationPathStatus): A populated + StaticDigitalPathGenerationPathStatus object + """ + + # define a set of message strings to display for a given path status + messages = { + niswitch.PathCapability.PATH_AVAILABLE: 'Path Available', + niswitch.PathCapability.PATH_EXISTS: 'Path Exists', + niswitch.PathCapability.PATH_UNSUPPORTED: 'Path Unsupported', + niswitch.PathCapability.RESOURCE_IN_USE: 'Resource in use', + niswitch.PathCapability.SOURCE_CONFLICT: 'Source conflict', + niswitch.PathCapability.CHANNEL_NOT_AVAILABLE: 'Channel not available' + } + + print('Path Status:', messages[status.path_status]) + + + def display_module_characteristics( + self, + chararteristics: StaticDigitalPathGenerationModuleCharacteristics + ) -> None: + """Takes in a StaticDigitalPathGenerationModuleCharacteristics object + and prints the contents in human-readble format + + Args: + chararteristics (StaticDigitalPathGenerationModuleCharacteristics): A + populated StaticDigitalPathGenerationModuleCharacteristics object + """ + + print('----- MODULE CHARACTERISTICS -------') + print('Max. DC Voltage (V):', chararteristics.max_dc_voltage) + print('Max. AC Voltage (V):', chararteristics.max_ac_voltage) + print('Max. Switching DC Current (A):', chararteristics.max_switching_dc_current) + print('Max. Switching AC Current (A):', chararteristics.max_switching_ac_current) diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_loop_scan_pmps_example.py b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_loop_scan_pmps_example.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_loop_scan_pmps_example.py rename to src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_loop_scan_pmps_example.py diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps_example.py b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_scan_pmps_example.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_scan_pmps_example.py rename to src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_scan_pmps_example.py diff --git a/src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_two_scan_pmps_example.py b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_two_scan_pmps_example.py similarity index 100% rename from src/nipcbatt/pcbatt_library/dmm_scan_examples/dmm_two_scan_pmps_example.py rename to src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_two_scan_pmps_example.py diff --git a/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/default_ni_switch_generation.py b/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/default_ni_switch_generation.py index 0c24988..ccc640a 100644 --- a/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/default_ni_switch_generation.py +++ b/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/default_ni_switch_generation.py @@ -17,7 +17,6 @@ def main(): p1, p2 = "ch0", "com0" max_wait_debounce = 100 connect = True - simulate = False #Change to True to simulate # instantiate parameters and settings objects channel_params = switch.StaticDigitalPathGenerationChannelParameters(p1, p2) @@ -25,18 +24,26 @@ def main(): ts_settings = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params, state) timing_settings = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) - + + # print desired connection to user + print('\nConnecting ' + p1 + ' to ' + p2) # ======================= Initialize the Switch ============================ # - generation.initialize(resource_name, topology, connect, simulate) + module_characteristics = generation.initialize(resource_name, topology) # =============== Configure and generate nominal configuration ============= # - generation.configure_and_generate(configuration) + path_status = generation.configure_and_generate(configuration) - # ======================== Close the DMM Session =========================== # + # ======================== Close the Switch Session =========================== # generation.close() - print('SUCCESS: Connected ' + p1 + ' to ' + p2) + + # print path status + generation.display_status(path_status) + + #print module characteristics + generation.display_module_characteristics(module_characteristics) + print('\n') if __name__ == "__main__": main() diff --git a/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py b/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py new file mode 100644 index 0000000..0510f20 --- /dev/null +++ b/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py @@ -0,0 +1,63 @@ +""" Validates that the path capability between points is detected and reported correctly """ + +import niswitch +from nipcbatt import switch +generation = switch.StaticDigitalPathGeneration() + +resource_name = "Sim_MUX" +topology = "2527/2-Wire Dual 16x1 Mux" +max_wait_debounce = 100 + +#initialize session +module_characteristics = generation.initialize(resource_name, topology, reset_device=True, simulate=True) + +################## ch0 to ch1 connection ######################################################## +channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("ch0", "ch1") +state1 = switch.StaticDigitalPathGenerationStateParameters(True) +ts_settings1 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params1, state1) +timing_settings1 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) +configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) + +path_status1 = generation.configure_and_generate(configuration1) +assert path_status1.path_status == niswitch.PathCapability.PATH_UNSUPPORTED + +print() +print('ch0 to ch1') +generation.display_status(path_status1) + +################# ch0 to com0 connection ######################################################### +channel_params2 = switch.StaticDigitalPathGenerationChannelParameters("ch0", "com0") +state2 = switch.StaticDigitalPathGenerationStateParameters(True) +ts_settings2 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params2, state2) +timing_settings2 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) +configuration2 = switch.StaticDigitalPathGenerationConfiguration(ts_settings2, timing_settings2) + +path_status2 = generation.configure_and_generate(configuration2) +assert path_status2.path_status == niswitch.PathCapability.PATH_AVAILABLE + +print() +print('ch0 to ch0') +generation.display_status(path_status2) + +################ ch1 to com0 connection ########################################################## +channel_params3 = switch.StaticDigitalPathGenerationChannelParameters("ch1", "com0") +state3 = switch.StaticDigitalPathGenerationStateParameters(True) +ts_settings3 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params3, state3) +timing_settings3 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) +configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) + +path_status3 = generation.configure_and_generate(configuration3) +assert path_status3.path_status == niswitch.PathCapability.RESOURCE_IN_USE + +print() +print('ch1 to com0') +generation.display_status(path_status3) + +#close switch session +generation.close() + +#print module characteristics +print() +generation.display_module_characteristics(module_characteristics) + +print('\n') \ No newline at end of file diff --git a/tests/nipcbatt_tests/pcbatt_library_integration_tests/static_digital_path_generations/test_integration_static_digital_path_generation.py b/tests/nipcbatt_tests/pcbatt_library_integration_tests/static_digital_path_generations/test_integration_static_digital_path_generation.py index 3d7dbf8..4835b15 100644 --- a/tests/nipcbatt_tests/pcbatt_library_integration_tests/static_digital_path_generations/test_integration_static_digital_path_generation.py +++ b/tests/nipcbatt_tests/pcbatt_library_integration_tests/static_digital_path_generations/test_integration_static_digital_path_generation.py @@ -101,7 +101,7 @@ def test_bank1_ch20_to_com1_connect_disconnect(self): return status.path_status def test_reject_channel_to_channel(self): - """Mux cannot short two inputs: ch0 <-> ch1 should raise a DriverError.""" + """Mux cannot short two inputs: ch0 <-> ch1 should result in PATH_UNSUPPORTED.""" generation = switch.StaticDigitalPathGeneration() resource_name = "Sim_MUX" @@ -117,13 +117,14 @@ def test_reject_channel_to_channel(self): configuration = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) generation.initialize(resource_name, topology, reset_device=True, simulate=True) - with self.assertRaises(niswitch_errors.DriverError): - generation.configure_and_generate(configuration) + status = generation.configure_and_generate(configuration) + + self.assertEqual(status.path_status.name, 'PATH_UNSUPPORTED') generation.close() def test_reject_cross_bank_common_mismatch(self): - """Channel must route to its bank common: ch3 <-> com1 should raise a DriverError.""" + """Channel must route to its bank common: ch3 <-> com1 should be unsupported.""" generation = switch.StaticDigitalPathGeneration() resource_name = "Sim_MUX" @@ -139,8 +140,10 @@ def test_reject_cross_bank_common_mismatch(self): configuration = switch.StaticDigitalPathGenerationConfiguration(ts_settings, timing_settings) generation.initialize(resource_name, topology, reset_device=True, simulate=True) - with self.assertRaises(niswitch_errors.DriverError): - generation.configure_and_generate(configuration) + + status = generation.configure_and_generate(configuration) + + self.assertEqual(status.path_status.name, 'PATH_UNSUPPORTED') generation.close() @@ -351,14 +354,15 @@ def test_sdpg_case1(self): topology = "2527/2-Wire Dual 16x1 Mux" max_wait_debounce = 100 + generation.initialize(resource_name, topology, reset_device=True, simulate=True) + #ch2 to com0 connection channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("ch2", "com0") state1 = switch.StaticDigitalPathGenerationStateParameters(True) ts_settings1 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params1, state1) timing_settings1 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) - - generation.initialize(resource_name, topology, reset_device=True, simulate=True) + path_status1 = generation.configure_and_generate(configuration1) #ch16 to com1 connection @@ -368,7 +372,6 @@ def test_sdpg_case1(self): timing_settings2 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration2 = switch.StaticDigitalPathGenerationConfiguration(ts_settings2, timing_settings2) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) path_status2 = generation.configure_and_generate(configuration2) #ch2 to com0 connection @@ -378,15 +381,8 @@ def test_sdpg_case1(self): timing_settings3 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - #expect an error due to the connection already existing - with self.assertRaises(niswitch_errors.DriverError) as error: - #since this path already exists this should throw an error - path_status3 = generation.configure_and_generate(configuration3) - - #check that error code is NISWITCH_ERROR_EXPLICIT_CONNECTION_EXISTS - self.assertEqual(error.exception.code, -1074126836) + path_status3 = generation.configure_and_generate(configuration3) + self.assertEqual(path_status3.path_status.name, 'PATH_EXISTS') generation.close() @@ -398,6 +394,8 @@ def test_sdpg_case2(self): topology = "2527/2-Wire Dual 16x1 Mux" max_wait_debounce = 100 + generation.initialize(resource_name, topology, reset_device=True, simulate=True) + #ch2 to com0 connection channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("ch1", "com0") state1 = switch.StaticDigitalPathGenerationStateParameters(True) @@ -405,7 +403,6 @@ def test_sdpg_case2(self): timing_settings1 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) path_status1 = generation.configure_and_generate(configuration1) #ch16 to com1 connection @@ -414,8 +411,7 @@ def test_sdpg_case2(self): ts_settings2 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params2, state2) timing_settings2 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration2 = switch.StaticDigitalPathGenerationConfiguration(ts_settings2, timing_settings2) - - generation.initialize(resource_name, topology, reset_device=True, simulate=True) + path_status2 = generation.configure_and_generate(configuration2) #ch2 to com0 connection @@ -424,15 +420,9 @@ def test_sdpg_case2(self): ts_settings3 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params3, state3) timing_settings3 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) - - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #com0 resource is already in use- throw error - path_status3 = generation.configure_and_generate(configuration3) - - #verfiy that error is NISWITCH_ERROR_RSRC_IN_USE - self.assertEqual(error.exception.code, -1074126845) + + path_status3 = generation.configure_and_generate(configuration3) + self.assertEqual(path_status3.path_status.name, 'RESOURCE_IN_USE') generation.close() @@ -445,14 +435,15 @@ def test_sdpg_case3(self): topology = "2527/2-Wire Dual 16x1 Mux" max_wait_debounce = 100 + generation.initialize(resource_name, topology, reset_device=True, simulate=True) + #ch2 to com0 connection channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("ch1", "com0") state1 = switch.StaticDigitalPathGenerationStateParameters(True) ts_settings1 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params1, state1) timing_settings1 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) - - generation.initialize(resource_name, topology, reset_device=True, simulate=True) + path_status1 = generation.configure_and_generate(configuration1) #ch16 to com1 connection @@ -461,15 +452,9 @@ def test_sdpg_case3(self): ts_settings2 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params2, state2) timing_settings2 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration2 = switch.StaticDigitalPathGenerationConfiguration(ts_settings2, timing_settings2) - - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #path is unsupported - path_status2 = generation.configure_and_generate(configuration2) - - #check that error code is NISWITCH_ERROR_PATH_NOT_FOUND - self.assertEqual(error.exception.code, -1074126831) + + path_status2 = generation.configure_and_generate(configuration2) + self.assertEqual(path_status2.path_status.name, 'PATH_UNSUPPORTED') #ch2 to com0 connection channel_params3 = switch.StaticDigitalPathGenerationChannelParameters("ch0", "com0") @@ -478,15 +463,8 @@ def test_sdpg_case3(self): timing_settings3 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #com0 resource is already in use- throw error - path_status3 = generation.configure_and_generate(configuration3) - - #verify that error is NISWITCH_ERROR_RSRC_IN_USE - self.assertEqual(error.exception.code, -1074126845) - + path_status3 = generation.configure_and_generate(configuration3) + self.assertEqual(path_status3.path_status.name, 'RESOURCE_IN_USE') generation.close() @@ -499,14 +477,15 @@ def test_sdpg_case4(self): topology = "2527/2-Wire Dual 16x1 Mux" max_wait_debounce = 100 + generation.initialize(resource_name, topology, reset_device=True, simulate=True) + #ch2 to com0 connection channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("ch1", "com0") state1 = switch.StaticDigitalPathGenerationStateParameters(True) ts_settings1 = switch.StaticDigitalPathGenerationTerminalAndStateSettings(channel_params1, state1) timing_settings1 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) - - generation.initialize(resource_name, topology, reset_device=True, simulate=True) + path_status1 = generation.configure_and_generate(configuration1) #ch16 to com1 connection @@ -516,14 +495,8 @@ def test_sdpg_case4(self): timing_settings2 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration2 = switch.StaticDigitalPathGenerationConfiguration(ts_settings2, timing_settings2) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #path already exists - path_status2 = generation.configure_and_generate(configuration2) - - #check that error code is NISWITCH_ERROR_EXPLICIT_CONNECTION_EXISTS - self.assertEqual(error.exception.code, -1074126836) + path_status2 = generation.configure_and_generate(configuration2) + self.assertEqual(path_status2.path_status.name, 'PATH_EXISTS') #ch2 to com0 connection channel_params3 = switch.StaticDigitalPathGenerationChannelParameters("ch0", "com0") @@ -532,14 +505,8 @@ def test_sdpg_case4(self): timing_settings3 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #com0 resource is already in use- throw error - path_status3 = generation.configure_and_generate(configuration3) - - #verify that error is NISWITCH_ERROR_RSRC_IN_USE - self.assertEqual(error.exception.code, -1074126845) + path_status3 = generation.configure_and_generate(configuration3) + self.assertEqual(path_status3.path_status.name, 'RESOURCE_IN_USE') generation.close() @@ -553,6 +520,8 @@ def test_sdpg_case5(self): topology = "2527/2-Wire Dual 16x1 Mux" max_wait_debounce = 100 + generation.initialize(resource_name, topology, reset_device=True, simulate=True) + #ch2 to com0 connection channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("com0", "ch1") state1 = switch.StaticDigitalPathGenerationStateParameters(True) @@ -560,7 +529,6 @@ def test_sdpg_case5(self): timing_settings1 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) path_status1 = generation.configure_and_generate(configuration1) #ch16 to com1 connection @@ -570,14 +538,8 @@ def test_sdpg_case5(self): timing_settings2 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration2 = switch.StaticDigitalPathGenerationConfiguration(ts_settings2, timing_settings2) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #path is unsupported - path_status2 = generation.configure_and_generate(configuration2) - - #check that error code is NISWITCH_ERROR_PATH_NOT_FOUND - self.assertEqual(error.exception.code, -1074126831) + path_status2 = generation.configure_and_generate(configuration2) + self.assertEqual(path_status2.path_status.name, 'PATH_UNSUPPORTED') #ch2 to com0 connection channel_params3 = switch.StaticDigitalPathGenerationChannelParameters("ch1", "com0") @@ -586,21 +548,14 @@ def test_sdpg_case5(self): timing_settings3 = switch.StaticDigitalPathGenerationTimingParameters(max_wait_debounce) configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) - generation.initialize(resource_name, topology, reset_device=True, simulate=True) - - with self.assertRaises(niswitch_errors.DriverError) as error: - #path already exists - path_status3 = generation.configure_and_generate(configuration3) - - #check that error code is NISWITCH_ERROR_EXPLICIT_CONNECTION_EXISTS - self.assertEqual(error.exception.code, -1074126836) - + path_status3 = generation.configure_and_generate(configuration3) + self.assertEqual(path_status3.path_status.name, 'PATH_EXISTS') generation.close() def test_sdpg_case6(self): - """Executes the fifth test defined in the SDPG Cases Individual Test Plan""" + """Executes the sixth test defined in the SDPG Cases Individual Test Plan""" generation = switch.StaticDigitalPathGeneration() resource_name = "Sim_MUX" @@ -615,13 +570,10 @@ def test_sdpg_case6(self): configuration1 = switch.StaticDigitalPathGenerationConfiguration(ts_settings1, timing_settings1) generation.initialize(resource_name, topology, reset_device=True, simulate=True) + + path_status1 = generation.configure_and_generate(configuration1) - with self.assertRaises(niswitch_errors.DriverError) as error: - #path unsupported - path_status1 = generation.configure_and_generate(configuration1) - - #check that error code is NISWITCH_ERROR_PATH_NOT_FOUND - self.assertEqual(error.exception.code, -1074126831) + self.assertEqual(path_status1.path_status.name, 'PATH_UNSUPPORTED') #ch16 to com1 connection channel_params2 = switch.StaticDigitalPathGenerationChannelParameters("ch16", "com1") @@ -641,6 +593,7 @@ def test_sdpg_case6(self): configuration3 = switch.StaticDigitalPathGenerationConfiguration(ts_settings3, timing_settings3) generation.initialize(resource_name, topology, reset_device=True, simulate=True) + #path_status3 = generation.configure_and_generate(configuration3) with self.assertRaises(niswitch_errors.DriverError) as error: #unknown channel or repeated capability name From 12c07f92c4c31564e280f634332ac25d6c102dbb Mon Sep 17 00:00:00 2001 From: John Date: Wed, 18 Mar 2026 09:03:54 -0700 Subject: [PATCH 13/14] Fixed typo and reduced initialize( ) arguments to 2 --- .../SWITCH_examples/switch_validate_path_status.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py b/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py index 0510f20..12f625e 100644 --- a/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py +++ b/src/nipcbatt/pcbatt_validation_examples/SWITCH_examples/switch_validate_path_status.py @@ -9,7 +9,7 @@ max_wait_debounce = 100 #initialize session -module_characteristics = generation.initialize(resource_name, topology, reset_device=True, simulate=True) +module_characteristics = generation.initialize(resource_name, topology) ################## ch0 to ch1 connection ######################################################## channel_params1 = switch.StaticDigitalPathGenerationChannelParameters("ch0", "ch1") @@ -36,7 +36,7 @@ assert path_status2.path_status == niswitch.PathCapability.PATH_AVAILABLE print() -print('ch0 to ch0') +print('ch0 to com0') generation.display_status(path_status2) ################ ch1 to com0 connection ########################################################## From 010a1a1844c8f88ecbb81ad0d36b525e98cf19df Mon Sep 17 00:00:00 2001 From: John Date: Wed, 18 Mar 2026 17:38:07 -0700 Subject: [PATCH 14/14] Changed all RangeAndFunctions to MixedRangeAndFunctions in scan configurations per our discussion --- .../dmm_loop_scan_pmps_example.py | 16 +++++----- .../dmm_scan_pmps_example.py | 16 +++++----- .../dmm_two_scan_pmps_example.py | 31 ++++++++++--------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_loop_scan_pmps_example.py b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_loop_scan_pmps_example.py index d8f4460..f49411c 100644 --- a/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_loop_scan_pmps_example.py +++ b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_loop_scan_pmps_example.py @@ -11,15 +11,15 @@ # edit this list to define the configurations to use during the scan # each entry should be a list in the format below: -# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +# [channel (int), range & function (MixedRangeAndFunctions), resolution (ResolutionInDigits)] scan_configuration = [ - [0, dmm.VoltageRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], - [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], - [16, dmm.CurrentRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], - [17, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], - [18, dmm.CurrentRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] + [0, dmm.MixedRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.MixedRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.MixedRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.MixedRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.MixedRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.MixedRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.MixedRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] ] #Declare constants for initialization diff --git a/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_scan_pmps_example.py b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_scan_pmps_example.py index 28103e0..94f8a0c 100644 --- a/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_scan_pmps_example.py +++ b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_scan_pmps_example.py @@ -11,15 +11,15 @@ # edit this list to define the configurations to use during the scan # each entry should be a list in the format below: -# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +# [channel (int), range & function (MixedRangeAndFunctions), resolution (ResolutionInDigits)] scan_configuration = [ - [0, dmm.VoltageRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], - [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], - [16, dmm.CurrentRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], - [17, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], - [18, dmm.CurrentRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] + [0, dmm.MixedRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.MixedRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.MixedRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.MixedRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.MixedRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.MixedRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.MixedRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] ] #Declare constants for initialization diff --git a/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_two_scan_pmps_example.py b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_two_scan_pmps_example.py index 031a793..ce88003 100644 --- a/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_two_scan_pmps_example.py +++ b/src/nipcbatt/pcbatt_validation_examples/DMM_SCAN_examples/dmm_two_scan_pmps_example.py @@ -11,27 +11,28 @@ # edit these lists to define the configurations to use during the scan # each entry should be a list in the format below: -# [channel (int), range & function (RangeAndFunctions), resolution (ResolutionInDigits)] +# [channel (int), range & function (MixedRangeAndFunctions), resolution (ResolutionInDigits)] scan_configuration1 = [ - [0, dmm.VoltageRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], - [3, dmm.ResistanceRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], - [16, dmm.CurrentRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], - [17, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], - [18, dmm.CurrentRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] + [0, dmm.MixedRangeAndFunctions.DC_100mV, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.MixedRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.MixedRangeAndFunctions.AC_2V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.MixedRangeAndFunctions.TWO_W_RES_10k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.MixedRangeAndFunctions.DC_100mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.MixedRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.MixedRangeAndFunctions.AC_10mA, dmm.ResolutionInDigits.DIGITS_4_5] ] scan_configuration2 = [ - [0, dmm.VoltageRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_6_5], - [1, dmm.VoltageRangeAndFunctions.DC_10V, dmm.ResolutionInDigits.DIGITS_5_5], - [2, dmm.VoltageRangeAndFunctions.DC_100V, dmm.ResolutionInDigits.DIGITS_4_5], - [3, dmm.ResistanceRangeAndFunctions.FOUR_W_RES_1k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], - [16, dmm.CurrentRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_6_5], - [17, dmm.CurrentRangeAndFunctions.DC_100uA, dmm.ResolutionInDigits.DIGITS_5_5], - [18, dmm.CurrentRangeAndFunctions.DC_1mA, dmm.ResolutionInDigits.DIGITS_4_5] + [0, dmm.MixedRangeAndFunctions.DC_1V, dmm.ResolutionInDigits.DIGITS_6_5], + [1, dmm.MixedRangeAndFunctions.DC_10V, dmm.ResolutionInDigits.DIGITS_5_5], + [2, dmm.MixedRangeAndFunctions.DC_100V, dmm.ResolutionInDigits.DIGITS_4_5], + [3, dmm.MixedRangeAndFunctions.FOUR_W_RES_1k_Ohm, dmm.ResolutionInDigits.DIGITS_4_5], + [16, dmm.MixedRangeAndFunctions.DC_10mA, dmm.ResolutionInDigits.DIGITS_6_5], + [17, dmm.MixedRangeAndFunctions.DC_100uA, dmm.ResolutionInDigits.DIGITS_5_5], + [18, dmm.MixedRangeAndFunctions.AC_1mA, dmm.ResolutionInDigits.DIGITS_4_5] ] + #Declare constants for initialization mux_resource_name = "Sim_MUX" shunt_resource_name = "Sim_SHUNT"