diff --git a/CHANGELOG.md b/CHANGELOG.md index 86a8d9eb3..f73acd916 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_cont_acq_chart_multiple_samples.py` example. - (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies. - Changed - Removed diff --git a/build/templates/tox-system_tests.ini.mako b/build/templates/tox-system_tests.ini.mako index c2b3d9131..41e42c05b 100644 --- a/build/templates/tox-system_tests.ini.mako +++ b/build/templates/tox-system_tests.ini.mako @@ -76,6 +76,9 @@ deps = % endif % if module_name == 'nidigital': ${module_name}-system_tests: nisync +% endif +% if module_name == 'nidmm': + ${module_name}-system_tests: matplotlib; sys_platform != "win32" % endif ${module_name}-system_tests: pytest ${module_name}-system_tests: coverage diff --git a/docs/nidmm/examples.rst b/docs/nidmm/examples.rst index ec6b3ee3e..72dfbdebd 100644 --- a/docs/nidmm/examples.rst +++ b/docs/nidmm/examples.rst @@ -3,6 +3,15 @@ Examples `You can download all nidmm examples for latest version here `_ +nidmm_cont_acq_chart_multiple_samples.py +---------------------------------------- + +.. literalinclude:: ../../src/nidmm/examples/nidmm_cont_acq_chart_multiple_samples.py + :language: python + :linenos: + :encoding: utf8 + :caption: `(nidmm_cont_acq_chart_multiple_samples.py) `_ + nidmm_fetch_waveform.py ----------------------- diff --git a/generated/nidmm/tox-system_tests.ini b/generated/nidmm/tox-system_tests.ini index 7d155899a..807c05d20 100644 --- a/generated/nidmm/tox-system_tests.ini +++ b/generated/nidmm/tox-system_tests.ini @@ -32,6 +32,7 @@ commands = nidmm-coverage: coverage report --rcfile=../../tools/coverage_system_tests.rc deps = + nidmm-system_tests: matplotlib; sys_platform != "win32" nidmm-system_tests: pytest nidmm-system_tests: coverage nidmm-system_tests: numpy diff --git a/src/nidmm/examples/nidmm_cont_acq_chart_multiple_samples.py b/src/nidmm/examples/nidmm_cont_acq_chart_multiple_samples.py new file mode 100644 index 000000000..288307c03 --- /dev/null +++ b/src/nidmm/examples/nidmm_cont_acq_chart_multiple_samples.py @@ -0,0 +1,86 @@ +#!/usr/bin/python + +import argparse +import collections +import nidmm +import pytest +import sys + + +# Number of most recent measurements kept on the chart +CHART_HISTORY_SIZE = 250 + + +def example(resource_name, options, function, measurement_range, digits, samples_to_fetch, fetch_count): + # Imported lazily because matplotlib is unavailable on some platforms (e.g. 32-bit Python) + import matplotlib.pyplot as plt + + with nidmm.Session(resource_name=resource_name, options=options) as session: + session.configure_measurement_digits(measurement_function=nidmm.Function[function], range=measurement_range, resolution_digits=digits) + # A sample_count of 0 configures a continuous acquisition + session.configure_multi_point(trigger_count=1, sample_count=0) + + figure, axes = plt.subplots() + (line,) = axes.plot([]) + axes.set_title('Measurements') + axes.set_xlabel('Samples') + axes.set_ylabel('Measured value') + axes.grid(True) + + measurements = collections.deque(maxlen=CHART_HISTORY_SIZE) + total_samples = 0 + fetches = 0 + try: + with session.initiate(): + # A fetch_count of None runs until the chart window is closed or Ctrl+C is pressed + while plt.fignum_exists(figure.number) and ( + fetch_count is None or fetches < fetch_count + ): + new_samples = session.fetch_multi_point(array_size=samples_to_fetch) + measurements.extend(new_samples) + total_samples += len(new_samples) + first_sample = total_samples - len(measurements) + line.set_data(range(first_sample, total_samples), measurements) + axes.relim() + axes.autoscale_view() + plt.pause(0.001) + fetches += 1 + except KeyboardInterrupt: + pass + finally: + plt.close(figure) + + +def _main(argsv): + parser = argparse.ArgumentParser(description='Continuously acquires measurements and displays them on a chart 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='DC_VOLTS', choices=nidmm.Function.__members__.keys(), type=str.upper, help='Specifies the measurement_function used to acquire the measurement.') + parser.add_argument('-r', '--range', default=10, type=float, help='Specifies the range for the function specified in the Measurement_Function parameter.') + parser.add_argument('-d', '--digits', default=5.5, type=float, help='Specifies the resolution of the measurement in digits.') + parser.add_argument('-s', '--samples-to-fetch', default=4, type=int, help='Specifies the number of measurements to fetch at a time.') + parser.add_argument('--fetch-count', default=None, type=int, help='Stops after this many fetches; omit to run until the chart window is closed or Ctrl+C is pressed.') + 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.range, args.digits, args.samples_to_fetch, args.fetch_count) + + +def main(): + _main(sys.argv[1:]) + + +def test_example(): + plt = pytest.importorskip('matplotlib.pyplot') + plt.switch_backend('Agg') # Avoid opening a chart window during the test + options = {'simulate': True, 'driver_setup': {'Model': '4082', 'BoardType': 'PXIe', }, } + example('PXI1Slot2', options, 'DC_VOLTS', 10, 5.5, 4, 2) + + +def test_main(): + plt = pytest.importorskip('matplotlib.pyplot') + plt.switch_backend('Agg') # Avoid opening a chart window during the test + cmd_line = ['--option-string', 'Simulate=1, DriverSetup=Model:4082; BoardType:PXIe', '--fetch-count', '2', ] + _main(cmd_line) + + +if __name__ == '__main__': + main()