From f135c6ae19815e7ed169004b02a8d2b124f54a83 Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Thu, 15 Oct 2026 11:37:15 +0000 Subject: [PATCH 1/8] Adding Measure Frequency in NI-DMM --- CHANGELOG.md | 1 + docs/nidmm/examples.rst | 9 +++ src/nidmm/examples/nidmm_measure_frequency.py | 57 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/nidmm/examples/nidmm_measure_frequency.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 86a8d9eb3..5e0e083da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -799,6 +799,7 @@ #### [nidmm] Unreleased - Added - Added the `nidmm_measure_ac_volts.py` example. + - Added the `nidmm_measure_frequency.py` example. - (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies. - Changed - Removed diff --git a/docs/nidmm/examples.rst b/docs/nidmm/examples.rst index ec6b3ee3e..ac2c812f0 100644 --- a/docs/nidmm/examples.rst +++ b/docs/nidmm/examples.rst @@ -21,6 +21,15 @@ nidmm_measure_ac_volts.py :encoding: utf8 :caption: `(nidmm_measure_ac_volts.py) `_ +nidmm_measure_frequency.py +-------------------------- + +.. literalinclude:: ../../src/nidmm/examples/nidmm_measure_frequency.py + :language: python + :linenos: + :encoding: utf8 + :caption: `(nidmm_measure_frequency.py) `_ + nidmm_measurement.py -------------------- diff --git a/src/nidmm/examples/nidmm_measure_frequency.py b/src/nidmm/examples/nidmm_measure_frequency.py new file mode 100644 index 000000000..2e747ff94 --- /dev/null +++ b/src/nidmm/examples/nidmm_measure_frequency.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +import argparse +import nidmm +import sys +import warnings + +SIGNAL_NOT_DETECTED_WARNING_CODE = 0x3FFA4F80 + + +def example(resource_name, options, function, min_frequency, max_period, voltage_range, digits): + # Frequency mode takes the minimum frequency as its range; period mode takes the maximum period. + range = min_frequency if function == 'FREQUENCY' else max_period + units = 'Hz' if function == 'FREQUENCY' else 's' + with nidmm.Session(resource_name=resource_name, options=options) as session: + session.configure_measurement_digits(measurement_function=nidmm.Function[function], range=range, resolution_digits=digits) + session.freq_voltage_range = voltage_range + # The driver reports warnings through the warnings module, with the code in the message text. + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter('always') + measurement = session.read() + signal_not_detected = any(f'Warning {SIGNAL_NOT_DETECTED_WARNING_CODE} occurred' in str(word.message) for word in caught) + print(f'Measurement ({units}): {measurement}') + print(f'Signal not Detected: {signal_not_detected}') + + +def _main(argsv): + parser = argparse.ArgumentParser(description='Performs a single frequency or period measurement using the NI-DMM API.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('-n', '--resource-name', default='PXI1Slot2', help='Contains the resource_name of the device to initialize.') + parser.add_argument('-f', '--function', default='FREQUENCY', choices=['FREQUENCY', 'PERIOD'], type=str.upper, help='Specifies the measurement_function used to acquire the measurement.') + parser.add_argument('--min-frequency', default=100, type=float, help='Minimum frequency expected, in Hz. Used as the range in FREQ mode.') + parser.add_argument('--max-period', default=0.01, type=float, help='Maximum period expected, in seconds. Used as the range in PERIOD mode.') + parser.add_argument('--voltage-range', default=50, type=float, help='Specifies the voltage range of the input signal for frequency measurements.') + parser.add_argument('-d', '--digits', default=5.5, type=float, help='Specifies the resolution of the measurement in digits.') + parser.add_argument('-op', '--option-string', default='', type=str, help='Sets the initial value of certain attributes for the session.') + args = parser.parse_args(argsv) + example(args.resource_name, args.option_string, args.function, args.min_frequency, args.max_period, args.voltage_range, args.digits) + + +def main(): + _main(sys.argv[1:]) + + +def test_example(): + options = {'simulate': True, 'driver_setup': {'Model': '4082', 'BoardType': 'PXIe', }, } + example('PXI1Slot2', options, 'FREQ', 100, 0.01, 10, 5.5) + example('PXI1Slot2', options, 'PERIOD', 100, 0.01, 10, 5.5) + + +def test_main(): + cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4082; BoardType:PXIe', ] + _main(cmd_line) + _main(cmd_line + ['--function', 'period', '--max-period', '0.02']) + + +if __name__ == '__main__': + main() From c607911d70a0cab71930e9b8039e24656ead4ca0 Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Thu, 15 Oct 2026 13:25:45 +0000 Subject: [PATCH 2/8] Rename the function for frequency --- src/nidmm/examples/nidmm_measure_frequency.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nidmm/examples/nidmm_measure_frequency.py b/src/nidmm/examples/nidmm_measure_frequency.py index 2e747ff94..f22b635e0 100644 --- a/src/nidmm/examples/nidmm_measure_frequency.py +++ b/src/nidmm/examples/nidmm_measure_frequency.py @@ -10,8 +10,8 @@ def example(resource_name, options, function, min_frequency, max_period, voltage_range, digits): # Frequency mode takes the minimum frequency as its range; period mode takes the maximum period. - range = min_frequency if function == 'FREQUENCY' else max_period - units = 'Hz' if function == 'FREQUENCY' else 's' + range = min_frequency if function == 'FREQ' else max_period + units = 'Hz' if function == 'FREQ' else 's' with nidmm.Session(resource_name=resource_name, options=options) as session: session.configure_measurement_digits(measurement_function=nidmm.Function[function], range=range, resolution_digits=digits) session.freq_voltage_range = voltage_range @@ -27,7 +27,7 @@ def example(resource_name, options, function, min_frequency, max_period, voltage def _main(argsv): parser = argparse.ArgumentParser(description='Performs a single frequency or period measurement using the NI-DMM API.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-n', '--resource-name', default='PXI1Slot2', help='Contains the resource_name of the device to initialize.') - parser.add_argument('-f', '--function', default='FREQUENCY', choices=['FREQUENCY', 'PERIOD'], type=str.upper, help='Specifies the measurement_function used to acquire the measurement.') + parser.add_argument('-f', '--function', default='FREQ', choices=['FREQ', 'PERIOD'], type=str.upper, help='Specifies the measurement_function used to acquire the measurement.') parser.add_argument('--min-frequency', default=100, type=float, help='Minimum frequency expected, in Hz. Used as the range in FREQ mode.') parser.add_argument('--max-period', default=0.01, type=float, help='Maximum period expected, in seconds. Used as the range in PERIOD mode.') parser.add_argument('--voltage-range', default=50, type=float, help='Specifies the voltage range of the input signal for frequency measurements.') From 65f13308195e902448d7b7795201dd6307b8984b Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Tue, 20 Oct 2026 13:24:37 +0000 Subject: [PATCH 3/8] updating the CLI parms --- src/nidmm/examples/nidmm_measure_frequency.py | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/nidmm/examples/nidmm_measure_frequency.py b/src/nidmm/examples/nidmm_measure_frequency.py index f22b635e0..ceaed521a 100644 --- a/src/nidmm/examples/nidmm_measure_frequency.py +++ b/src/nidmm/examples/nidmm_measure_frequency.py @@ -6,15 +6,15 @@ import warnings SIGNAL_NOT_DETECTED_WARNING_CODE = 0x3FFA4F80 +# Required by the API; not used for frequency or period measurements. +RESOLUTION_DIGITS = 5.5 -def example(resource_name, options, function, min_frequency, max_period, voltage_range, digits): - # Frequency mode takes the minimum frequency as its range; period mode takes the maximum period. - range = min_frequency if function == 'FREQ' else max_period +def example(resource_name, options, function, range, max_amplitude): units = 'Hz' if function == 'FREQ' else 's' with nidmm.Session(resource_name=resource_name, options=options) as session: - session.configure_measurement_digits(measurement_function=nidmm.Function[function], range=range, resolution_digits=digits) - session.freq_voltage_range = voltage_range + session.configure_measurement_digits(measurement_function=nidmm.Function[function], range=range, resolution_digits=RESOLUTION_DIGITS) + session.freq_voltage_range = max_amplitude # The driver reports warnings through the warnings module, with the code in the message text. with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('always') @@ -28,13 +28,11 @@ def _main(argsv): parser = argparse.ArgumentParser(description='Performs a single frequency or period measurement using the NI-DMM API.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-n', '--resource-name', default='PXI1Slot2', help='Contains the resource_name of the device to initialize.') parser.add_argument('-f', '--function', default='FREQ', choices=['FREQ', 'PERIOD'], type=str.upper, help='Specifies the measurement_function used to acquire the measurement.') - parser.add_argument('--min-frequency', default=100, type=float, help='Minimum frequency expected, in Hz. Used as the range in FREQ mode.') - parser.add_argument('--max-period', default=0.01, type=float, help='Maximum period expected, in seconds. Used as the range in PERIOD mode.') - parser.add_argument('--voltage-range', default=50, type=float, help='Specifies the voltage range of the input signal for frequency measurements.') - parser.add_argument('-d', '--digits', default=5.5, type=float, help='Specifies the resolution of the measurement in digits.') + parser.add_argument('-r', '--range', default=20, type=float, help='Specifies the range for the measurement function. For FREQ, the minimum frequency expected in Hz; for PERIOD, the maximum period expected in seconds.') + parser.add_argument('--max-amplitude', default=50, type=float, help='Specifies the maximum amplitude of the input signal for frequency measurements.') parser.add_argument('-op', '--option-string', default='', type=str, help='Sets the initial value of certain attributes for the session.') args = parser.parse_args(argsv) - example(args.resource_name, args.option_string, args.function, args.min_frequency, args.max_period, args.voltage_range, args.digits) + example(args.resource_name, args.option_string, args.function, args.range, args.max_amplitude) def main(): @@ -43,14 +41,14 @@ def main(): def test_example(): options = {'simulate': True, 'driver_setup': {'Model': '4082', 'BoardType': 'PXIe', }, } - example('PXI1Slot2', options, 'FREQ', 100, 0.01, 10, 5.5) - example('PXI1Slot2', options, 'PERIOD', 100, 0.01, 10, 5.5) + example('PXI1Slot2', options, 'FREQ', 100, 10) + example('PXI1Slot2', options, 'PERIOD', 0.01, 10) def test_main(): cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4082; BoardType:PXIe', ] _main(cmd_line) - _main(cmd_line + ['--function', 'period', '--max-period', '0.02']) + _main(cmd_line + ['--function', 'period', '--range', '0.02']) if __name__ == '__main__': From d6f79b50130b1d19053a27d706a629f5e8354aae Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Tue, 20 Oct 2026 15:00:01 +0000 Subject: [PATCH 4/8] Fixing the PR comments --- src/nidmm/examples/nidmm_measure_frequency.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nidmm/examples/nidmm_measure_frequency.py b/src/nidmm/examples/nidmm_measure_frequency.py index ceaed521a..ab8f0da5f 100644 --- a/src/nidmm/examples/nidmm_measure_frequency.py +++ b/src/nidmm/examples/nidmm_measure_frequency.py @@ -5,8 +5,9 @@ import sys import warnings +# NIDMM_WARN_UNDERRANGE; reported by read() when the input is under range, used here as "signal not detected" SIGNAL_NOT_DETECTED_WARNING_CODE = 0x3FFA4F80 -# Required by the API; not used for frequency or period measurements. +# Required by configure_measurement_digits(); 5.5 is the driver's documented default RESOLUTION_DIGITS = 5.5 From ac5b7685928b0d8b364834640263e6194a87da34 Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Tue, 20 Oct 2026 15:16:45 +0000 Subject: [PATCH 5/8] Trigger CI build From c9c70cbd9bcdd43fd852784ee44ee36cbcf895f3 Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Tue, 20 Oct 2026 15:30:11 +0000 Subject: [PATCH 6/8] Trigger CI build From d841f3e85630d20dc6fcf931d6609d984bd26c17 Mon Sep 17 00:00:00 2001 From: "Selvam, Divakar" Date: Wed, 21 Oct 2026 18:48:56 +0530 Subject: [PATCH 7/8] Apply nits to frequency example --- src/nidmm/examples/nidmm_measure_frequency.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nidmm/examples/nidmm_measure_frequency.py b/src/nidmm/examples/nidmm_measure_frequency.py index ab8f0da5f..a1070958e 100644 --- a/src/nidmm/examples/nidmm_measure_frequency.py +++ b/src/nidmm/examples/nidmm_measure_frequency.py @@ -5,22 +5,22 @@ import sys import warnings -# NIDMM_WARN_UNDERRANGE; reported by read() when the input is under range, used here as "signal not detected" +# NIDMM_WARN_UNDERRANGE; reported by read() when the input is under range and used here to indicate "signal not detected" SIGNAL_NOT_DETECTED_WARNING_CODE = 0x3FFA4F80 # Required by configure_measurement_digits(); 5.5 is the driver's documented default RESOLUTION_DIGITS = 5.5 def example(resource_name, options, function, range, max_amplitude): - units = 'Hz' if function == 'FREQ' else 's' with nidmm.Session(resource_name=resource_name, options=options) as session: session.configure_measurement_digits(measurement_function=nidmm.Function[function], range=range, resolution_digits=RESOLUTION_DIGITS) session.freq_voltage_range = max_amplitude - # The driver reports warnings through the warnings module, with the code in the message text. + # The driver reports warnings through Python's warnings module; the warning code is included in the message. with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('always') measurement = session.read() signal_not_detected = any(f'Warning {SIGNAL_NOT_DETECTED_WARNING_CODE} occurred' in str(word.message) for word in caught) + units = 'Hz' if function == 'FREQ' else 's' print(f'Measurement ({units}): {measurement}') print(f'Signal not Detected: {signal_not_detected}') From 4ae565a37e6e78a14c64c8c1d4f9bb384f17e028 Mon Sep 17 00:00:00 2001 From: NI-velmurugan Date: Thu, 22 Oct 2026 06:48:41 +0000 Subject: [PATCH 8/8] Trigger CI build