class TestUtils(object): """ Contains a collection of pytest tests that validate the utilities functionality in the NI-DAQmx Python API. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_flatten_channel_string(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) channels = ['Dev1/ai0', 'Dev1/ai1', 'Dev1/ai3', 'Dev2/ai0'] flattened_channels = 'Dev1/ai0:1,Dev1/ai3,Dev2/ai0' assert flatten_channel_string(channels) == flattened_channels assert flatten_channel_string([]) == '' @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_unflatten_channel_string(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) channels = ['Dev1/ai0', 'Dev1/ai1', 'Dev1/ai3', 'Dev2/ai0'] flattened_channels = 'Dev1/ai0:1,Dev1/ai3,Dev2/ai0' assert unflatten_channel_string(flattened_channels) == channels assert unflatten_channel_string('') == []
class TestPropertyListDataTypes(object): """ Contains a collection of pytest tests that validate the property getter setter, and deleter methods for list data types. There are almost no setter and deleter methods for properties that have list data types. """ def test_list_of_strings_property(self, x_series_device): terminals = x_series_device.terminals assert isinstance(terminals, list) assert isinstance(terminals[0], six.string_types) def test_list_of_enums_property(self, x_series_device): terminals = x_series_device.ai_meas_types assert isinstance(terminals, list) assert isinstance(terminals[0], UsageTypeAI) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_list_of_floats_property(self, bridge_device, seed): if bridge_device is None: pytest.skip("requires bridge device") # Reset the pseudorandom number generator with seed. random.seed(seed) with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_bridge_chan( bridge_device.ai_physical_chans[0].name) # Test default property value. assert isinstance(ai_channel.ai_bridge_poly_forward_coeff, list) assert len(ai_channel.ai_bridge_poly_forward_coeff) == 0 # Test property setter and getter. value_to_test = [ random.randint(-10, 10) for _ in range(random.randint(2, 5)) ] ai_channel.ai_bridge_poly_forward_coeff = value_to_test assert ai_channel.ai_bridge_poly_forward_coeff == value_to_test # Test property deleter. del ai_channel.ai_bridge_poly_forward_coeff assert isinstance(ai_channel.ai_bridge_poly_forward_coeff, list) assert len(ai_channel.ai_bridge_poly_forward_coeff) == 0
class TestExportSignals(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the export signals functionality in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_export_signals(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_chan = random.choice(x_series_device.ai_physical_chans) pfi_line = random.choice(self._get_device_pfi_lines(x_series_device)) with nidaqmx.Task() as task: task.ai_channels.add_ai_voltage_chan(ai_chan.name) task.timing.cfg_samp_clk_timing(1000) task.export_signals.export_signal(Signal.SAMPLE_CLOCK, pfi_line) assert task.export_signals.samp_clk_output_term == pfi_line
class TestTEDS(object): """ Contains a collection of pytest tests that validate the TEDS functionality in the NI-DAQmx Python API. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_teds_ai_voltage_chan(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans) # Generate path to a virtual TEDS file. teds_file_path = os.path.join(os.path.dirname(__file__), 'teds', 'Voltage.ted') ai_phys_chan.configure_teds(teds_file_path) assert ai_phys_chan.teds_mfg_id == 17 assert ai_phys_chan.teds_model_num == 1 assert ai_phys_chan.teds_version_letter == 'A' assert ai_phys_chan.teds_version_num == 1 assert ai_phys_chan.teds_template_ids == [30] with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_teds_ai_voltage_chan( ai_phys_chan.name, name_to_assign_to_channel="TEDSVoltageChannel", terminal_config=TerminalConfiguration.DEFAULT, min_val=-300.0, max_val=100.0, units=TEDSUnits.FROM_TEDS) assert ai_channel.ai_teds_is_teds assert ai_channel.ai_teds_units == 'Kelvin' assert ai_channel.ai_min == -300.0 assert ai_channel.ai_max == 100.0
class TestDigitalReadWrite(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the digital Read and Write functions in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_bool_1_chan_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) do_line = random.choice(x_series_device.do_lines).name with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_line, line_grouping=LineGrouping.CHAN_PER_LINE) # Generate random values to test. values_to_test = [bool(random.getrandbits(1)) for _ in range(10)] values_read = [] for value_to_test in values_to_test: task.write(value_to_test) time.sleep(0.001) values_read.append(task.read()) assert values_read == values_to_test # Verify setting number_of_samples_per_channel (even to 1) # returns a list. value_read = task.read(number_of_samples_per_channel=1) assert isinstance(value_read, list) assert len(value_read) == 1 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_bool_n_chan_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_channels = random.randint(2, len(x_series_device.do_lines)) do_lines = random.sample(x_series_device.do_lines, number_of_channels) with nidaqmx.Task() as task: task.do_channels.add_do_chan( flatten_channel_string([d.name for d in do_lines]), line_grouping=LineGrouping.CHAN_PER_LINE) # Generate random values to test. values_to_test = [ bool(random.getrandbits(1)) for _ in range(number_of_channels) ] task.write(values_to_test) time.sleep(0.001) values_read = task.read() assert values_read == values_to_test # Verify setting number_of_samples_per_channel (even to 1) # returns a list of lists. value_read = task.read(number_of_samples_per_channel=1) assert isinstance(value_read, list) assert isinstance(value_read[0], list) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_uint_1_chan_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) do_port = random.choice(x_series_device.do_ports) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = [ int(random.getrandbits(do_port.do_port_width)) for _ in range(10) ] values_read = [] for value_to_test in values_to_test: task.write(value_to_test) time.sleep(0.001) values_read.append(task.read()) assert values_read == values_to_test # Verify setting number_of_samples_per_channel (even to 1) # returns a list. value_read = task.read(number_of_samples_per_channel=1) assert isinstance(value_read, list) assert len(value_read) == 1 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_uint_multi_port(self, x_series_device, seed): if len([d.do_port_width <= 16 for d in x_series_device.do_ports]) < 2: pytest.skip( 'task.read() accepts max of 32 bits for digital uint reads.') # Reset the pseudorandom number generator with seed. random.seed(seed) do_ports = random.sample( [d for d in x_series_device.do_ports if d.do_port_width <= 16], 2) total_port_width = sum([d.do_port_width for d in do_ports]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( flatten_channel_string([d.name for d in do_ports]), line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = [ int(random.getrandbits(total_port_width)) for _ in range(10) ] values_read = [] for value_to_test in values_to_test: task.write(value_to_test) time.sleep(0.001) values_read.append(task.read()) assert values_read == values_to_test
class TestTriggers(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the triggers functionality in the NI-DAQmx Python API. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_arm_start_trigger(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) counter = random.choice(self._get_device_counters(x_series_device)) with nidaqmx.Task() as task: task.co_channels.add_co_pulse_chan_freq(counter) task.triggers.arm_start_trigger.trig_type = ( TriggerType.DIGITAL_EDGE) assert (task.triggers.arm_start_trigger.trig_type == TriggerType.DIGITAL_EDGE) task.triggers.arm_start_trigger.trig_type = ( TriggerType.NONE) assert (task.triggers.arm_start_trigger.trig_type == TriggerType.NONE) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_handshake_trigger(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) counter = random.choice(self._get_device_counters(x_series_device)) with nidaqmx.Task() as task: task.co_channels.add_co_pulse_chan_freq(counter) with pytest.raises(DaqError) as e: task.triggers.handshake_trigger.trig_type = ( TriggerType.INTERLOCKED) assert e.value.error_code == -200452 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_pause_trigger(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) counter = random.choice(self._get_device_counters(x_series_device)) with nidaqmx.Task() as task: task.co_channels.add_co_pulse_chan_freq(counter) task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) task.triggers.pause_trigger.trig_type = ( TriggerType.DIGITAL_LEVEL) assert (task.triggers.pause_trigger.trig_type == TriggerType.DIGITAL_LEVEL) task.triggers.pause_trigger.trig_type = ( TriggerType.NONE) assert (task.triggers.pause_trigger.trig_type == TriggerType.NONE) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_reference_trigger(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) counter = random.choice(self._get_device_counters(x_series_device)) with nidaqmx.Task() as task: task.co_channels.add_co_pulse_chan_freq(counter) with pytest.raises(DaqError) as e: task.triggers.reference_trigger.trig_type = ( TriggerType.NONE) assert e.value.error_code == -200452 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_start_trigger(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) counter = random.choice(self._get_device_counters(x_series_device)) pfi_line = random.choice(self._get_device_pfi_lines(x_series_device)) with nidaqmx.Task() as task: task.co_channels.add_co_pulse_chan_freq(counter) task.triggers.start_trigger.cfg_dig_edge_start_trig( pfi_line, trigger_edge=Edge.FALLING) assert (task.triggers.start_trigger.trig_type == TriggerType.DIGITAL_EDGE) assert task.triggers.start_trigger.dig_edge_edge == Edge.FALLING
class TestCounterReaderWriter(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the counter Read and Write functions in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_uint32(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_pulses = random.randint(2, 50) frequency = random.uniform(1000, 10000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq(counters[0], freq=frequency) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_pulses) read_task.ci_channels.add_ci_count_edges_chan(counters[1]) read_task.ci_channels.all.ci_count_edges_term = ( '/{0}InternalOutput'.format(counters[0])) reader = CounterReader(read_task.in_stream) read_task.start() write_task.start() write_task.wait_until_done(timeout=2) value_read = reader.read_one_sample_uint32() assert value_read == number_of_pulses @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_multi_sample_uint32(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 50) frequency = random.uniform(1000, 10000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 3) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task, \ nidaqmx.Task() as sample_clk_task: # Create a finite pulse train task that acts as the sample clock # for the read task and the arm start trigger for the write task. sample_clk_task.co_channels.add_co_pulse_chan_freq(counters[0], freq=frequency) actual_frequency = sample_clk_task.co_channels.all.co_pulse_freq sample_clk_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) samp_clk_terminal = '/{0}InternalOutput'.format(counters[0]) write_task.co_channels.add_co_pulse_chan_freq( counters[1], freq=actual_frequency) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) write_task.triggers.arm_start_trigger.trig_type = ( TriggerType.DIGITAL_EDGE) write_task.triggers.arm_start_trigger.dig_edge_edge = (Edge.RISING) write_task.triggers.arm_start_trigger.dig_edge_src = ( samp_clk_terminal) read_task.ci_channels.add_ci_count_edges_chan(counters[2], edge=Edge.RISING) read_task.ci_channels.all.ci_count_edges_term = ( '/{0}InternalOutput'.format(counters[1])) read_task.timing.cfg_samp_clk_timing( actual_frequency, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=number_of_samples) read_task.start() write_task.start() sample_clk_task.start() sample_clk_task.wait_until_done(timeout=2) reader = CounterReader(read_task.in_stream) values_read = numpy.zeros(number_of_samples, dtype=numpy.uint32) reader.read_many_sample_uint32( values_read, number_of_samples_per_channel=number_of_samples, timeout=2) expected_values = [i + 1 for i in range(number_of_samples)] assert values_read.tolist() == expected_values @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_double(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) frequency = random.uniform(1000, 10000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq(counters[0], freq=frequency) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) actual_frequency = write_task.co_channels.all.co_pulse_freq read_task.ci_channels.add_ci_freq_chan(counters[1], min_val=1000, max_val=10000) read_task.ci_channels.all.ci_freq_term = ( '/{0}InternalOutput'.format(counters[0])) reader = CounterReader(read_task.in_stream) read_task.start() write_task.start() value_read = reader.read_one_sample_double() numpy.testing.assert_allclose([value_read], [actual_frequency], rtol=0.05) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_multi_sample_double(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 50) frequency = random.uniform(1000, 10000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 3) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq(counters[1], freq=frequency) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples + 1) read_task.ci_channels.add_ci_freq_chan(counters[2], min_val=1000, max_val=10000, edge=Edge.RISING) read_task.ci_channels.all.ci_freq_term = ( '/{0}InternalOutput'.format(counters[1])) read_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) read_task.start() write_task.start() write_task.wait_until_done(timeout=2) reader = CounterReader(read_task.in_stream) values_read = numpy.zeros(number_of_samples, dtype=numpy.float64) reader.read_many_sample_double( values_read, number_of_samples_per_channel=number_of_samples, timeout=2) expected_values = [frequency for _ in range(number_of_samples)] numpy.testing.assert_allclose(values_read, expected_values, rtol=0.05) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_pulse_freq(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) frequency = random.uniform(1000, 10000) duty_cycle = random.uniform(0.2, 0.8) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq( counters[0], freq=frequency, duty_cycle=duty_cycle) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) read_task.ci_channels.add_ci_pulse_chan_freq(counters[1], min_val=1000, max_val=10000) read_task.ci_channels.all.ci_pulse_freq_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.start() write_task.start() reader = CounterReader(read_task.in_stream) value_read = reader.read_one_sample_pulse_frequency() write_task.stop() assert numpy.isclose(value_read.freq, frequency, rtol=0.05) assert numpy.isclose(value_read.duty_cycle, duty_cycle, rtol=0.05) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_pulse_freq(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 50) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq( counters[0], idle_state=Level.HIGH) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples + 1) write_task.control(TaskMode.TASK_COMMIT) read_task.ci_channels.add_ci_pulse_chan_freq(counters[1], min_val=1000, max_val=10000) read_task.ci_channels.all.ci_pulse_freq_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) frequencies_to_test = numpy.array([ random.uniform(1000, 10000) for _ in range(number_of_samples + 1) ], dtype=numpy.float64) duty_cycles_to_test = numpy.array([ random.uniform(0.2, 0.8) for _ in range(number_of_samples + 1) ], dtype=numpy.float64) writer = CounterWriter(write_task.out_stream) reader = CounterReader(read_task.in_stream) writer.write_many_sample_pulse_frequency(frequencies_to_test, duty_cycles_to_test) read_task.start() write_task.start() frequencies_read = numpy.zeros(number_of_samples, dtype=numpy.float64) duty_cycles_read = numpy.zeros(number_of_samples, dtype=numpy.float64) reader.read_many_sample_pulse_frequency( frequencies_read, duty_cycles_read, number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose(frequencies_read, frequencies_to_test[1:], rtol=0.05) numpy.testing.assert_allclose(duty_cycles_read, duty_cycles_to_test[1:], rtol=0.05) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_pulse_time(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) high_time = random.uniform(0.0001, 0.001) low_time = random.uniform(0.0001, 0.001) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_time(counters[0], high_time=high_time, low_time=low_time) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) read_task.ci_channels.add_ci_pulse_chan_time(counters[1], min_val=0.0001, max_val=0.001) read_task.ci_channels.all.ci_pulse_time_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.start() write_task.start() reader = CounterReader(read_task.in_stream) value_read = reader.read_one_sample_pulse_time() write_task.stop() assert numpy.isclose(value_read.high_time, high_time, rtol=0.05) assert numpy.isclose(value_read.low_time, low_time, rtol=0.05) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_pulse_time(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 50) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_time( counters[0], idle_state=Level.HIGH) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples + 1) write_task.control(TaskMode.TASK_COMMIT) read_task.ci_channels.add_ci_pulse_chan_time(counters[1], min_val=0.0001, max_val=0.001) read_task.ci_channels.all.ci_pulse_time_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) high_times_to_test = numpy.array([ random.uniform(0.0001, 0.001) for _ in range(number_of_samples + 1) ], dtype=numpy.float64) low_times_to_test = numpy.array([ random.uniform(0.0001, 0.001) for _ in range(number_of_samples + 1) ], dtype=numpy.float64) writer = CounterWriter(write_task.out_stream) reader = CounterReader(read_task.in_stream) writer.write_many_sample_pulse_time(high_times_to_test, low_times_to_test) read_task.start() write_task.start() high_times_read = numpy.zeros(number_of_samples, dtype=numpy.float64) low_times_read = numpy.zeros(number_of_samples, dtype=numpy.float64) reader.read_many_sample_pulse_time( high_times_read, low_times_read, number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose(high_times_read, high_times_to_test[1:], rtol=0.05) numpy.testing.assert_allclose(low_times_read, low_times_to_test[1:], rtol=0.05) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_pulse_ticks_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) high_ticks = random.randint(100, 1000) low_ticks = random.randint(100, 1000) starting_edge = random.choice([Edge.RISING, Edge.FALLING]) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_ticks( counters[0], '/{0}/100kHzTimebase'.format(x_series_device.name), high_ticks=high_ticks, low_ticks=low_ticks) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) read_task.ci_channels.add_ci_pulse_chan_ticks( counters[1], source_terminal='/{0}/100kHzTimebase'.format( x_series_device.name), min_val=100, max_val=1000) read_task.ci_channels.all.ci_pulse_ticks_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.ci_channels.all.ci_pulse_ticks_starting_edge = ( starting_edge) read_task.start() write_task.start() reader = CounterReader(read_task.in_stream) value_read = reader.read_one_sample_pulse_ticks() write_task.stop() assert numpy.isclose(value_read.high_tick, high_ticks, rtol=0.05, atol=1) assert numpy.isclose(value_read.low_tick, low_ticks, rtol=0.05, atol=1) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_pulse_ticks(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 50) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_ticks( counters[0], '/{0}/100kHzTimebase'.format(x_series_device.name), idle_state=Level.HIGH) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples + 1) write_task.control(TaskMode.TASK_COMMIT) read_task.ci_channels.add_ci_pulse_chan_ticks( counters[1], source_terminal='/{0}/100kHzTimebase'.format( x_series_device.name), min_val=100, max_val=1000) read_task.ci_channels.all.ci_pulse_ticks_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) high_ticks_to_test = numpy.array([ random.randint(100, 1000) for _ in range(number_of_samples + 1) ], dtype=numpy.uint32) low_ticks_to_test = numpy.array([ random.randint(100, 1000) for _ in range(number_of_samples + 1) ], dtype=numpy.uint32) writer = CounterWriter(write_task.out_stream) reader = CounterReader(read_task.in_stream) writer.write_many_sample_pulse_ticks(high_ticks_to_test, low_ticks_to_test) read_task.start() write_task.start() high_ticks_read = numpy.zeros(number_of_samples, dtype=numpy.uint32) low_ticks_read = numpy.zeros(number_of_samples, dtype=numpy.uint32) reader.read_many_sample_pulse_ticks( high_ticks_read, low_ticks_read, number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose(high_ticks_read, high_ticks_to_test[1:], rtol=0.05, atol=1) numpy.testing.assert_allclose(low_ticks_read, low_ticks_to_test[1:], rtol=0.05, atol=1)
class TestDigitalMultiChannelReaderWriter(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the digital multi channel readers and writers in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_one_line(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_channels = random.randint(2, len(x_series_device.do_lines)) do_lines = random.sample(x_series_device.do_lines, number_of_channels) with nidaqmx.Task() as task: task.do_channels.add_do_chan( flatten_channel_string([d.name for d in do_lines]), line_grouping=LineGrouping.CHAN_PER_LINE) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) # Generate random values to test. values_to_test = numpy.array([ bool(random.getrandbits(1)) for _ in range(number_of_channels) ]) writer.write_one_sample_one_line(values_to_test) time.sleep(0.001) values_read = numpy.zeros(number_of_channels, dtype=bool) reader.read_one_sample_one_line(values_read) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_multi_line(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) num_lines = random.randint(2, 4) number_of_channels = random.randint( 2, int(numpy.floor(len(x_series_device.do_lines) / float(num_lines)))) all_lines = random.sample(x_series_device.do_lines, num_lines * number_of_channels) with nidaqmx.Task() as task: for i in range(number_of_channels): do_lines = all_lines[i * num_lines:(i + 1) * num_lines] task.do_channels.add_do_chan( flatten_channel_string([d.name for d in do_lines]), line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) # Generate random values to test. values_to_test = numpy.array( [[bool(random.getrandbits(1)) for _ in range(num_lines)] for _ in range(number_of_channels)]) writer.write_one_sample_multi_line(values_to_test) time.sleep(0.001) values_read = numpy.zeros((number_of_channels, num_lines), dtype=bool) reader.read_one_sample_multi_line(values_read) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_port_byte(self, x_series_device, seed): if len([d.do_port_width <= 8 for d in x_series_device.do_ports]) < 2: pytest.skip("Requires 2 digital ports with at most 8 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) all_ports = [ d for d in x_series_device.do_ports if d.do_port_width <= 8 ] number_of_channels = random.randint(2, len(all_ports)) do_ports = random.sample(all_ports, number_of_channels) with nidaqmx.Task() as task: for do_port in do_ports: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array( [int(random.getrandbits(d.do_port_width)) for d in do_ports], dtype=numpy.uint8) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) writer.write_one_sample_port_byte(values_to_test) time.sleep(0.001) values_read = numpy.zeros(number_of_channels, dtype=numpy.uint8) reader.read_one_sample_port_byte(values_read) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_port_uint16(self, x_series_device, seed): if len([d.do_port_width <= 16 for d in x_series_device.do_ports]) < 2: pytest.skip("Requires 2 digital ports with at most 16 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) all_ports = [ d for d in x_series_device.do_ports if d.do_port_width <= 16 ] number_of_channels = random.randint(2, len(all_ports)) do_ports = random.sample(all_ports, number_of_channels) with nidaqmx.Task() as task: for do_port in do_ports: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array( [int(random.getrandbits(d.do_port_width)) for d in do_ports], dtype=numpy.uint16) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) writer.write_one_sample_port_uint16(values_to_test) time.sleep(0.001) values_read = numpy.zeros(number_of_channels, dtype=numpy.uint16) reader.read_one_sample_port_uint16(values_read) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_port_uint32(self, x_series_device, seed): if len([d.do_port_width <= 32 for d in x_series_device.do_ports]) < 2: pytest.skip("Requires 2 digital ports with at most 32 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) all_ports = [ d for d in x_series_device.do_ports if d.do_port_width <= 32 ] number_of_channels = random.randint(2, len(all_ports)) do_ports = random.sample(all_ports, number_of_channels) with nidaqmx.Task() as task: for do_port in do_ports: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array( [int(random.getrandbits(d.do_port_width)) for d in do_ports], dtype=numpy.uint32) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) writer.write_one_sample_port_uint32(values_to_test) time.sleep(0.001) values_read = numpy.zeros(number_of_channels, dtype=numpy.uint32) reader.read_one_sample_port_uint32(values_read) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_port_byte(self, x_series_device, seed): if len([d.do_port_width <= 8 for d in x_series_device.do_ports]) < 2: pytest.skip("Requires 2 digital ports with at most 8 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 20) all_ports = [ d for d in x_series_device.do_ports if d.do_port_width <= 8 ] number_of_channels = random.randint(2, len(all_ports)) do_ports = random.sample(all_ports, number_of_channels) with nidaqmx.Task() as task: for do_port in do_ports: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array([[ int(random.getrandbits(do_port.do_port_width)) for _ in range(number_of_samples) ] for do_port in do_ports], dtype=numpy.uint8) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) task.start() writer.write_many_sample_port_byte(values_to_test) time.sleep(0.001) # Since we're writing to and reading from ONLY the digital # output lines, we can't use sample clocks to correlate the # read and write sampling times. Thus, we essentially read # the last value written multiple times. values_read = numpy.zeros((number_of_channels, number_of_samples), dtype=numpy.uint8) reader.read_many_sample_port_byte( values_read, number_of_samples_per_channel=number_of_samples) expected_values = [[ values_to_test[i, -1] for _ in range(number_of_samples) ] for i in range(number_of_channels)] numpy.testing.assert_array_equal(values_read, expected_values) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_port_uint16(self, x_series_device, seed): if len([d.do_port_width <= 16 for d in x_series_device.do_ports]) < 2: pytest.skip("Requires 2 digital ports with at most 16 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 20) all_ports = [ d for d in x_series_device.do_ports if d.do_port_width <= 16 ] number_of_channels = random.randint(2, len(all_ports)) do_ports = random.sample(all_ports, number_of_channels) with nidaqmx.Task() as task: for do_port in do_ports: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array([[ int(random.getrandbits(do_port.do_port_width)) for _ in range(number_of_samples) ] for do_port in do_ports], dtype=numpy.uint16) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) task.start() writer.write_many_sample_port_uint16(values_to_test) time.sleep(0.001) # Since we're writing to and reading from ONLY the digital # output lines, we can't use sample clocks to correlate the # read and write sampling times. Thus, we essentially read # the last value written multiple times. values_read = numpy.zeros((number_of_channels, number_of_samples), dtype=numpy.uint16) reader.read_many_sample_port_uint16( values_read, number_of_samples_per_channel=number_of_samples) expected_values = [[ values_to_test[i, -1] for _ in range(number_of_samples) ] for i in range(number_of_channels)] numpy.testing.assert_array_equal(values_read, expected_values) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_port_uint32(self, x_series_device, seed): if len([d.do_port_width <= 32 for d in x_series_device.do_ports]) < 2: pytest.skip("Requires 2 digital ports with at most 32 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 20) all_ports = [ d for d in x_series_device.do_ports if d.do_port_width <= 32 ] number_of_channels = random.randint(2, len(all_ports)) do_ports = random.sample(all_ports, number_of_channels) with nidaqmx.Task() as task: for do_port in do_ports: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array([[ int(random.getrandbits(do_port.do_port_width)) for _ in range(number_of_samples) ] for do_port in do_ports], dtype=numpy.uint32) writer = DigitalMultiChannelWriter(task.out_stream) reader = DigitalMultiChannelReader(task.in_stream) task.start() writer.write_many_sample_port_uint32(values_to_test) time.sleep(0.001) # Since we're writing to and reading from ONLY the digital # output lines, we can't use sample clocks to correlate the # read and write sampling times. Thus, we essentially read # the last value written multiple times. values_read = numpy.zeros((number_of_channels, number_of_samples), dtype=numpy.uint32) reader.read_many_sample_port_uint32( values_read, number_of_samples_per_channel=number_of_samples) expected_values = [[ values_to_test[i, -1] for _ in range(number_of_samples) ] for i in range(number_of_channels)] numpy.testing.assert_array_equal(values_read, expected_values)
class TestEvents(object): """ Contains a collection of pytest tests that validate the NI-DAQmx events functionality in the Python NI-DAQmx API. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_every_n_samples_event(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) samples_chunk = 100 sample_rate = 5000 with nidaqmx.Task() as task: task.ai_channels.add_ai_voltage_chan( x_series_device.ai_physical_chans[0].name) samples_multiple = random.randint(2, 5) num_samples = samples_chunk * samples_multiple task.timing.cfg_samp_clk_timing(sample_rate, sample_mode=AcquisitionType.FINITE, samps_per_chan=num_samples) # Python 2.X does not have nonlocal keyword. non_local_var = {'samples_read': 0} def callback(task_handle, every_n_samples_event_type, number_of_samples, callback_data): samples = task.read( number_of_samples_per_channel=samples_chunk, timeout=2.0) non_local_var['samples_read'] += len(samples) return 0 task.register_every_n_samples_acquired_into_buffer_event( samples_chunk, callback) task.start() task.wait_until_done(timeout=2) # Wait until done doesn't wait for all callbacks to be processed. time.sleep(1) task.stop() assert non_local_var['samples_read'] == num_samples samples_multiple = random.randint(2, 5) num_samples = samples_chunk * samples_multiple task.timing.cfg_samp_clk_timing(sample_rate, sample_mode=AcquisitionType.FINITE, samps_per_chan=num_samples) non_local_var = {'samples_read': 0} # Unregister event callback function by passing None. task.register_every_n_samples_acquired_into_buffer_event( samples_chunk, None) task.start() task.wait_until_done(timeout=2) # Wait until done doesn't wait for all callbacks to be processed. time.sleep(1) task.stop() assert non_local_var['samples_read'] == 0
class TestInvalidWrites(object): @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_insufficient_write_data(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Randomly select physical channels to test. number_of_channels = random.randint( 2, len(x_series_device.ao_physical_chans)) channels_to_test = random.sample(x_series_device.ao_physical_chans, number_of_channels) with nidaqmx.Task() as task: task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.name for c in channels_to_test]), max_val=10, min_val=-10) with pytest.raises(DaqError) as e: task.write(random.uniform(-10, 10)) assert e.value.error_code == -200524 number_of_samples = random.randint(1, number_of_channels - 1) values_to_test = [ random.uniform(-10, 10) for _ in range(number_of_samples) ] with pytest.raises(DaqError) as e: task.write(values_to_test, auto_start=True) assert e.value.error_code == -200524 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_insufficient_numpy_write_data(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Randomly select physical channels to test. number_of_channels = random.randint( 2, len(x_series_device.ao_physical_chans)) channels_to_test = random.sample(x_series_device.ao_physical_chans, number_of_channels) with nidaqmx.Task() as task: task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.name for c in channels_to_test]), max_val=10, min_val=-10) number_of_samples = random.randint(1, number_of_channels - 1) values_to_test = numpy.float64( [random.uniform(-10, 10) for _ in range(number_of_samples)]) with pytest.raises(DaqError) as e: task.write(values_to_test, auto_start=True) assert e.value.error_code == -200524 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_extraneous_write_data(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Randomly select physical channels to test. number_of_channels = random.randint( 1, len(x_series_device.ao_physical_chans)) channels_to_test = random.sample(x_series_device.ao_physical_chans, number_of_channels) with nidaqmx.Task() as task: task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.name for c in channels_to_test]), max_val=10, min_val=-10) # Generate random values to test. number_of_data_rows = random.randint(number_of_channels + 1, number_of_channels + 10) values_to_test = [[random.uniform(-10, 10) for _ in range(10)] for _ in range(number_of_data_rows)] with pytest.raises(DaqError) as e: task.write(values_to_test, auto_start=True) assert e.value.error_code == -200524 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_extraneous_numpy_write_data(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Randomly select physical channels to test. number_of_channels = random.randint( 1, len(x_series_device.ao_physical_chans)) channels_to_test = random.sample(x_series_device.ao_physical_chans, number_of_channels) with nidaqmx.Task() as task: task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.name for c in channels_to_test]), max_val=10, min_val=-10) # Generate random values to test. number_of_data_rows = random.randint(number_of_channels + 1, number_of_channels + 10) values_to_test = [[random.uniform(-10, 10) for _ in range(10)] for _ in range(number_of_data_rows)] numpy_data = numpy.float64(values_to_test) with pytest.raises(DaqError) as e: task.write(numpy_data, auto_start=True) assert e.value.error_code == -200524 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_numpy_write_incorrectly_shaped_data(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Randomly select physical channels to test. number_of_channels = random.randint( 2, len(x_series_device.ao_physical_chans)) channels_to_test = random.sample(x_series_device.ao_physical_chans, number_of_channels) number_of_samples = random.randint(50, 100) with nidaqmx.Task() as task: task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.name for c in channels_to_test]), max_val=10, min_val=-10) task.timing.cfg_samp_clk_timing(1000, samps_per_chan=number_of_samples) # Generate write data but swap the rows and columns so the numpy # array is shaped incorrectly, but the amount of samples is still # the same. values_to_test = numpy.float64( [[random.uniform(-10, 10) for _ in range(number_of_channels)] for _ in range(number_of_samples)]) with pytest.raises(DaqError) as e: task.write(values_to_test, auto_start=True) assert e.value.error_code == -200524
class TestDigitalSingleChannelReaderWriter(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the digital single channel readers and writers in the NI-DAQmx Python API. These tests use only a single X Series device by both writing to and reading from ONLY the digital output lines. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_one_line(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) do_line = random.choice(x_series_device.do_lines).name with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_line, line_grouping=LineGrouping.CHAN_PER_LINE) writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) # Generate random values to test. values_to_test = [bool(random.getrandbits(1)) for _ in range(10)] values_read = [] for value_to_test in values_to_test: writer.write_one_sample_one_line(value_to_test) time.sleep(0.001) values_read.append(reader.read_one_sample_one_line()) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_multi_line(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_lines = random.randint(2, len(x_series_device.do_lines)) do_lines = random.sample(x_series_device.do_lines, number_of_lines) with nidaqmx.Task() as task: task.do_channels.add_do_chan( flatten_channel_string([d.name for d in do_lines]), line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) # Generate random values to test. values_to_test = numpy.array( [bool(random.getrandbits(1)) for _ in range(number_of_lines)]) writer.write_one_sample_multi_line(values_to_test) time.sleep(0.001) values_read = numpy.zeros(number_of_lines, dtype=bool) reader.read_one_sample_multi_line(values_read) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_port_byte(self, x_series_device, seed): if not any([d.do_port_width <= 8 for d in x_series_device.do_ports]): pytest.skip("Requires digital port with at most 8 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) do_port = random.choice( [d for d in x_series_device.do_ports if d.do_port_width <= 8]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = [ int(random.getrandbits(do_port.do_port_width)) for _ in range(10) ] writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) values_read = [] for value_to_test in values_to_test: writer.write_one_sample_port_byte(value_to_test) time.sleep(0.001) values_read.append(reader.read_one_sample_port_byte()) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_port_uint16(self, x_series_device, seed): if not any([d.do_port_width <= 16 for d in x_series_device.do_ports]): pytest.skip("Requires digital port with at most 16 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) do_port = random.choice( [do for do in x_series_device.do_ports if do.do_port_width <= 16]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = [ int(random.getrandbits(do_port.do_port_width)) for _ in range(10) ] writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) values_read = [] for value_to_test in values_to_test: writer.write_one_sample_port_uint16(value_to_test) time.sleep(0.001) values_read.append(reader.read_one_sample_port_uint16()) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample_port_uint32(self, x_series_device, seed): if not any([d.do_port_width <= 32 for d in x_series_device.do_ports]): pytest.skip("Requires digital port with at most 32 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) do_port = random.choice( [do for do in x_series_device.do_ports if do.do_port_width <= 32]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = [ int(random.getrandbits(do_port.do_port_width)) for _ in range(10) ] writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) values_read = [] for value_to_test in values_to_test: writer.write_one_sample_port_uint32(value_to_test) time.sleep(0.001) values_read.append(reader.read_one_sample_port_uint32()) numpy.testing.assert_array_equal(values_read, values_to_test) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_port_byte(self, x_series_device, seed): if not any([d.do_port_width <= 8 for d in x_series_device.do_ports]): pytest.skip("Requires digital port with at most 8 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 20) do_port = random.choice( [d for d in x_series_device.do_ports if d.do_port_width <= 8]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array([ int(random.getrandbits(do_port.do_port_width)) for _ in range(number_of_samples) ], dtype=numpy.uint8) writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) task.start() writer.write_many_sample_port_byte(values_to_test) time.sleep(0.001) # Since we're writing to and reading from ONLY the digital # output lines, we can't use sample clocks to correlate the # read and write sampling times. Thus, we essentially read # the last value written multiple times. values_read = numpy.zeros(number_of_samples, dtype=numpy.uint8) reader.read_many_sample_port_byte( values_read, number_of_samples_per_channel=number_of_samples) expected_values = [ values_to_test[-1] for _ in range(number_of_samples) ] numpy.testing.assert_array_equal(values_read, expected_values) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_port_uint16(self, x_series_device, seed): if not any([d.do_port_width <= 16 for d in x_series_device.do_ports]): pytest.skip("Requires digital port with at most 16 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 20) do_port = random.choice( [d for d in x_series_device.do_ports if d.do_port_width <= 16]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array([ int(random.getrandbits(do_port.do_port_width)) for _ in range(number_of_samples) ], dtype=numpy.uint16) writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) task.start() writer.write_many_sample_port_uint16(values_to_test) time.sleep(0.001) # Since we're writing to and reading from ONLY the digital # output lines, we can't use sample clocks to correlate the # read and write sampling times. Thus, we essentially read # the last value written multiple times. values_read = numpy.zeros(number_of_samples, dtype=numpy.uint16) reader.read_many_sample_port_uint16( values_read, number_of_samples_per_channel=number_of_samples) expected_values = [ values_to_test[-1] for _ in range(number_of_samples) ] numpy.testing.assert_array_equal(values_read, expected_values) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample_port_uint32(self, x_series_device, seed): if not any([d.do_port_width <= 32 for d in x_series_device.do_ports]): pytest.skip("Requires digital port with at most 32 lines.") # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 20) do_port = random.choice( [d for d in x_series_device.do_ports if d.do_port_width <= 32]) with nidaqmx.Task() as task: task.do_channels.add_do_chan( do_port.name, line_grouping=LineGrouping.CHAN_FOR_ALL_LINES) # Generate random values to test. values_to_test = numpy.array([ int(random.getrandbits(do_port.do_port_width)) for _ in range(number_of_samples) ], dtype=numpy.uint32) writer = DigitalSingleChannelWriter(task.out_stream) reader = DigitalSingleChannelReader(task.in_stream) task.start() writer.write_many_sample_port_uint32(values_to_test) time.sleep(0.001) # Since we're writing to and reading from ONLY the digital # output lines, we can't use sample clocks to correlate the # read and write sampling times. Thus, we essentially read # the last value written multiple times. values_read = numpy.zeros(number_of_samples, dtype=numpy.uint32) reader.read_many_sample_port_uint32( values_read, number_of_samples_per_channel=number_of_samples) expected_values = [ values_to_test[-1] for _ in range(number_of_samples) ] numpy.testing.assert_array_equal(values_read, expected_values)
class TestCounterReadWrite(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the counter Read and Write functions in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_count_edges_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_pulses = random.randint(2, 100) frequency = random.uniform(5000, 50000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq(counters[0], freq=frequency) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_pulses) ci_channel = read_task.ci_channels.add_ci_count_edges_chan( counters[1]) ci_channel.ci_count_edges_term = '/{0}InternalOutput'.format( counters[0]) read_task.start() write_task.start() write_task.wait_until_done(timeout=2) value_read = read_task.read() assert value_read == number_of_pulses # Verify setting number_of_samples_per_channel (even to 1) # returns a list. value_read = read_task.read(number_of_samples_per_channel=1) assert isinstance(value_read, list) assert len(value_read) == 1 assert value_read[0] == number_of_pulses @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_count_edges_n_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(2, 100) frequency = random.uniform(5000, 50000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 3) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task, \ nidaqmx.Task() as sample_clk_task: # Create a finite pulse train task that acts as the sample clock # for the read task and the arm start trigger for the write task. sample_clk_task.co_channels.add_co_pulse_chan_freq(counters[0], freq=frequency) actual_frequency = sample_clk_task.co_channels.all.co_pulse_freq sample_clk_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/{0}InternalOutput'.format(counters[0]) write_task.co_channels.add_co_pulse_chan_freq( counters[1], freq=actual_frequency) write_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) write_task.triggers.arm_start_trigger.trig_type = ( TriggerType.DIGITAL_EDGE) write_task.triggers.arm_start_trigger.dig_edge_edge = (Edge.RISING) write_task.triggers.arm_start_trigger.dig_edge_src = ( samp_clk_terminal) read_task.ci_channels.add_ci_count_edges_chan(counters[2], edge=Edge.RISING) read_task.ci_channels.all.ci_count_edges_term = ( '/{0}InternalOutput'.format(counters[1])) read_task.timing.cfg_samp_clk_timing( actual_frequency, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=number_of_samples) read_task.start() write_task.start() sample_clk_task.start() sample_clk_task.wait_until_done(timeout=2) value_read = read_task.read( number_of_samples_per_channel=number_of_samples, timeout=2) expected_values = [i + 1 for i in range(number_of_samples)] assert value_read == expected_values @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_pulse_freq_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) frequency = random.uniform(100, 1000) duty_cycle = random.uniform(0.2, 0.8) starting_edge = random.choice([Edge.RISING, Edge.FALLING]) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq( counters[0], freq=frequency, duty_cycle=duty_cycle) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) read_task.ci_channels.add_ci_pulse_chan_freq(counters[1], min_val=100, max_val=1000) read_task.ci_channels.all.ci_pulse_freq_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.ci_channels.all.ci_pulse_freq_starting_edge = ( starting_edge) read_task.start() write_task.start() value_read = read_task.read(timeout=2) write_task.stop() assert numpy.isclose(value_read.freq, frequency, rtol=0.01) assert numpy.isclose(value_read.duty_cycle, duty_cycle, rtol=0.01) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_pulse_time_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) high_time = random.uniform(0.001, 0.01) low_time = random.uniform(0.001, 0.01) starting_edge = random.choice([Edge.RISING, Edge.FALLING]) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_time(counters[0], high_time=high_time, low_time=low_time) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) read_task.ci_channels.add_ci_pulse_chan_time(counters[1], min_val=0.001, max_val=0.01) read_task.ci_channels.all.ci_pulse_time_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.ci_channels.all.ci_pulse_time_starting_edge = ( starting_edge) read_task.start() write_task.start() value_read = read_task.read(timeout=2) write_task.stop() assert numpy.isclose(value_read.high_time, high_time, rtol=0.01) assert numpy.isclose(value_read.low_time, low_time, rtol=0.01) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_pulse_ticks_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) high_ticks = random.randint(100, 1000) low_ticks = random.randint(100, 1000) starting_edge = random.choice([Edge.RISING, Edge.FALLING]) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_ticks( counters[0], '/{0}/100kHzTimebase'.format(x_series_device.name), high_ticks=high_ticks, low_ticks=low_ticks) write_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS) read_task.ci_channels.add_ci_pulse_chan_ticks( counters[1], source_terminal='/{0}/100kHzTimebase'.format( x_series_device.name), min_val=100, max_val=1000) read_task.ci_channels.all.ci_pulse_ticks_term = ( '/{0}InternalOutput'.format(counters[0])) read_task.ci_channels.all.ci_pulse_ticks_starting_edge = ( starting_edge) read_task.start() write_task.start() value_read = read_task.read(timeout=2) write_task.stop() assert value_read.high_tick == high_ticks assert value_read.low_tick == low_ticks
class TestAnalogCreateChannels(object): """ Contains a collection of pytest tests that validate the analog Create Channel functions in the NI-DAQmx Python API. These tests simply call create channel functions with some valid values for function parameters, and then read properties to verify that the parameter values were set properly. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_voltage_chan(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_voltage_chan( ai_phys_chan, name_to_assign_to_channel="VoltageChannel", terminal_config=TerminalConfiguration.NRSE, min_val=-20.0, max_val=20.0, units=VoltageUnits.FROM_CUSTOM_SCALE, custom_scale_name="double_gain_scale") assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "VoltageChannel" assert ai_channel.ai_term_cfg == TerminalConfiguration.NRSE assert ai_channel.ai_min == -20.0 assert ai_channel.ai_max == 20.0 assert (ai_channel.ai_voltage_units == VoltageUnits.FROM_CUSTOM_SCALE) assert (ai_channel.ai_custom_scale.name == "double_gain_scale") @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_current_chan(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_current_chan( ai_phys_chan, name_to_assign_to_channel="CurrentChannel", terminal_config=TerminalConfiguration.RSE, min_val=-0.01, max_val=0.01, units=CurrentUnits.AMPS, shunt_resistor_loc=CurrentShuntResistorLocation.EXTERNAL, ext_shunt_resistor_val=100.0) assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "CurrentChannel" assert ai_channel.ai_term_cfg == TerminalConfiguration.RSE assert ai_channel.ai_min == -0.01 assert ai_channel.ai_max == 0.01 assert ai_channel.ai_current_units == CurrentUnits.AMPS assert (ai_channel.ai_current_shunt_loc == CurrentShuntResistorLocation.EXTERNAL) assert ai_channel.ai_current_shunt_resistance == 100.0 # @pytest.mark.parametrize('seed', [generate_random_seed()]) # def test_create_ai_voltage_rms_chan(self, x_series_device, seed): # # Reset the pseudorandom number generator with seed. # random.seed(seed) # # ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name # # with nidaqmx.Task() as task: # ai_channel = task.ai_channels.add_ai_voltage_rms_chan( # ai_phys_chan, name_to_assign_to_channel="VoltageRMSChannel", # terminal_config=TerminalConfiguration.bal_diff, min_val=-1.0, # max_val=1.0, units=VoltageUnits.volts, custom_scale_name="") # # assert ai_channel.name == "VoltageRMSChannel" # assert ai_channel.ai_term_cfg == TerminalConfiguration.bal_diff # assert ai_channel.ai_min == -1.0 # assert ai_channel.ai_max == 1.0 # assert ai_channel.ai_voltage_units == VoltageUnits.volts # assert ai_channel.ai_custom_scale.name == "" @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_rtd_chan(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_rtd_chan( ai_phys_chan, name_to_assign_to_channel="RTDChannel", min_val=28.0, max_val=120.0, units=TemperatureUnits.K, rtd_type=RTDType.PT_3750, resistance_config=ResistanceConfiguration.TWO_WIRE, current_excit_source=ExcitationSource.EXTERNAL, current_excit_val=0.0025, r_0=100.0) assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "RTDChannel" assert numpy.isclose(ai_channel.ai_min, 28.0, atol=1) assert numpy.isclose(ai_channel.ai_max, 221.0, atol=1) assert ai_channel.ai_temp_units == TemperatureUnits.K assert ai_channel.ai_rtd_type == RTDType.PT_3750 assert (ai_channel.ai_resistance_cfg == ResistanceConfiguration.TWO_WIRE) assert ai_channel.ai_excit_src == ExcitationSource.EXTERNAL assert ai_channel.ai_excit_val == 0.0025 assert ai_channel.ai_rtd_r_0 == 100.0 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_thrmstr_chan_iex(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_thrmstr_chan_iex( ai_phys_chan, name_to_assign_to_channel="ThermistorIexChannel", min_val=-30.0, max_val=300.0, units=TemperatureUnits.DEG_C, resistance_config=ResistanceConfiguration.FOUR_WIRE, current_excit_source=ExcitationSource.EXTERNAL, current_excit_val=0.0001, a=0.0013, b=0.00023, c=0.000000102) assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "ThermistorIexChannel" assert numpy.isclose(ai_channel.ai_min, -30.0, atol=1) assert numpy.isclose(ai_channel.ai_max, 300.0, atol=1) assert ai_channel.ai_temp_units == TemperatureUnits.DEG_C assert (ai_channel.ai_resistance_cfg == ResistanceConfiguration.FOUR_WIRE) assert ai_channel.ai_excit_src == ExcitationSource.EXTERNAL assert ai_channel.ai_excit_val == 0.0001 assert ai_channel.ai_thrmstr_a == 0.0013 assert ai_channel.ai_thrmstr_b == 0.00023 assert ai_channel.ai_thrmstr_c == 0.000000102 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_thrmstr_chan_vex(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_thrmstr_chan_vex( ai_phys_chan, name_to_assign_to_channel="ThermistorVexChannel", min_val=-50.0, max_val=300.0, units=TemperatureUnits.DEG_C, resistance_config=ResistanceConfiguration.FOUR_WIRE, voltage_excit_source=ExcitationSource.EXTERNAL, voltage_excit_val=2.5, a=0.001295361, b=0.0002343159, c=0.0000001018703, r_1=5000.0) assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "ThermistorVexChannel" assert numpy.isclose(ai_channel.ai_min, -50.0, atol=1) assert numpy.isclose(ai_channel.ai_max, 300.0, atol=1) assert ai_channel.ai_temp_units == TemperatureUnits.DEG_C assert (ai_channel.ai_resistance_cfg == ResistanceConfiguration.FOUR_WIRE) assert ai_channel.ai_excit_src == ExcitationSource.EXTERNAL assert ai_channel.ai_excit_val == 2.5 assert ai_channel.ai_thrmstr_a == 0.001295361 assert ai_channel.ai_thrmstr_b == 0.0002343159 assert ai_channel.ai_thrmstr_c == 0.0000001018703 assert ai_channel.ai_thrmstr_r_1 == 5000.0 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_resistance_chan(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_resistance_chan( ai_phys_chan, name_to_assign_to_channel="ResistanceChannel", min_val=-1000.0, max_val=1000.0, units=ResistanceUnits.OHMS, resistance_config=ResistanceConfiguration.TWO_WIRE, current_excit_source=ExcitationSource.EXTERNAL, current_excit_val=0.002, custom_scale_name="") assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "ResistanceChannel" assert numpy.isclose(ai_channel.ai_min, -1000.0, atol=1) assert numpy.isclose(ai_channel.ai_max, 1000.0, atol=1) assert ai_channel.ai_resistance_units == ResistanceUnits.OHMS assert (ai_channel.ai_resistance_cfg == ResistanceConfiguration.TWO_WIRE) assert ai_channel.ai_excit_src == ExcitationSource.EXTERNAL assert ai_channel.ai_excit_val == 0.002 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_ai_strain_gage_chan(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_strain_gage_chan( ai_phys_chan, name_to_assign_to_channel="StrainGageChannel", min_val=-0.05, max_val=0.05, units=StrainUnits.STRAIN, strain_config=StrainGageBridgeType.FULL_BRIDGE_I, voltage_excit_source=ExcitationSource.EXTERNAL, voltage_excit_val=1.0, gage_factor=4.0, initial_bridge_voltage=0.0, nominal_gage_resistance=350.0, poisson_ratio=0.30, lead_wire_resistance=0.1, custom_scale_name="") assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "StrainGageChannel" assert numpy.isclose(ai_channel.ai_min, -0.05) assert numpy.isclose(ai_channel.ai_max, 0.05) assert ai_channel.ai_strain_units == StrainUnits.STRAIN assert (ai_channel.ai_strain_gage_cfg == StrainGageBridgeType.FULL_BRIDGE_I) assert ai_channel.ai_excit_src == ExcitationSource.EXTERNAL assert ai_channel.ai_excit_val == 1.0 assert ai_channel.ai_strain_gage_gage_factor == 4.0 assert ai_channel.ai_bridge_initial_voltage == 0.0 assert ai_channel.ai_strain_gage_poisson_ratio == 0.30 assert ai_channel.ai_lead_wire_resistance == 0.1 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_create_ai_voltage_chan_with_excit(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chan = random.choice(x_series_device.ai_physical_chans).name with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_voltage_chan_with_excit( ai_phys_chan, name_to_assign_to_channel="VoltageExcitChannel", terminal_config=TerminalConfiguration.NRSE, min_val=-10.0, max_val=10.0, units=VoltageUnits.VOLTS, bridge_config=BridgeConfiguration.NO_BRIDGE, voltage_excit_source=ExcitationSource.EXTERNAL, voltage_excit_val=0.1, use_excit_for_scaling=False, custom_scale_name="") assert ai_channel.physical_channel.name == ai_phys_chan assert ai_channel.name == "VoltageExcitChannel" assert ai_channel.ai_term_cfg == TerminalConfiguration.NRSE assert numpy.isclose(ai_channel.ai_min, -10.0) assert numpy.isclose(ai_channel.ai_max, 10.0) assert ai_channel.ai_voltage_units == VoltageUnits.VOLTS assert ai_channel.ai_bridge_cfg == BridgeConfiguration.NO_BRIDGE assert ai_channel.ai_excit_src == ExcitationSource.EXTERNAL assert ai_channel.ai_excit_val == 0.1 assert not ai_channel.ai_excit_use_for_scaling
class TestAnalogSingleChannelReaderWriter(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the analog single channel stream reader and writer in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_one_sample(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) loopback_channel_pair = random.choice(loopback_channel_pairs) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.ao_channels.add_ao_voltage_chan( loopback_channel_pair.output_channel, max_val=10, min_val=-10) read_task.ai_channels.add_ai_voltage_chan( loopback_channel_pair.input_channel, max_val=10, min_val=-10) writer = AnalogSingleChannelWriter(write_task.out_stream) reader = AnalogSingleChannelReader(read_task.in_stream) # Generate random values to test. values_to_test = [random.uniform(-10, 10) for _ in range(10)] values_read = [] for value_to_test in values_to_test: writer.write_one_sample(value_to_test) time.sleep(0.001) value_read = reader.read_one_sample() assert isinstance(value_read, float) values_read.append(value_read) numpy.testing.assert_allclose( values_read, values_to_test, rtol=0.05, atol=0.005) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_many_sample(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(20, 100) sample_rate = random.uniform(1000, 5000) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) loopback_channel_pair = random.choice(loopback_channel_pairs) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task, \ nidaqmx.Task() as sample_clk_task: # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. sample_clk_task.co_channels.add_co_pulse_chan_freq( '{0}/ctr0'.format(x_series_device.name), freq=sample_rate) sample_clk_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) samp_clk_terminal = '/{0}/Ctr0InternalOutput'.format( x_series_device.name) write_task.ao_channels.add_ao_voltage_chan( loopback_channel_pair.output_channel, max_val=10, min_val=-10) write_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.RISING, samps_per_chan=number_of_samples) read_task.ai_channels.add_ai_voltage_chan( loopback_channel_pair.input_channel, max_val=10, min_val=-10) read_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=number_of_samples) writer = AnalogSingleChannelWriter(write_task.out_stream) reader = AnalogSingleChannelReader(read_task.in_stream) # Generate random values to test. values_to_test = numpy.array( [random.uniform(-10, 10) for _ in range(number_of_samples)], dtype=numpy.float64) writer.write_many_sample(values_to_test) # Start the read and write tasks before starting the sample clock # source task. read_task.start() write_task.start() sample_clk_task.start() values_read = numpy.zeros(number_of_samples, dtype=numpy.float64) reader.read_many_sample( values_read, number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose( values_read, values_to_test, rtol=0.05, atol=0.005)
class TestMultiThreadedReads(object): """ Contains a collection of pytest tests that validate multi-threaded reads using the NI-DAQmx Python API. These tests create multiple tasks, each of which uses one of 4 simulated X Series devices. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_multi_threaded_analog_read(self, multi_threading_test_devices, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) sample_rate = 10000 samples_per_read = int(sample_rate / 10) number_of_reads = random.randint(200, 500) number_of_samples = samples_per_read * number_of_reads channels_to_test = [] for device in multi_threading_test_devices: channels_to_test.append(random.choice(device.ai_physical_chans)) tasks = [] try: for channel_to_test in channels_to_test: task = None try: task = nidaqmx.Task() task.ai_channels.add_ai_voltage_chan(channel_to_test.name, max_val=10, min_val=-10) task.timing.cfg_samp_clk_timing( sample_rate, samps_per_chan=number_of_samples) except nidaqmx.DaqError: if task is not None: task.close() raise else: tasks.append(task) except nidaqmx.DaqError: for task in tasks: task.close() raise actor_refs = [] actor_proxies = [] for task in tasks: actor_ref = DAQmxReaderActor.start(task) actor_refs.append(actor_ref) actor_proxies.append(actor_ref.proxy()) try: for task in tasks: task.start() read_futures = [] for actor_proxy in actor_proxies: read_futures.append( actor_proxy.read(samples_per_read, number_of_reads, timeout=2)) pykka.get_all(read_futures, (number_of_samples / sample_rate) + 10) finally: for task in tasks: task.close() for actor_ref in actor_refs: try: actor_ref.stop(timeout=(number_of_samples / sample_rate) + 10) except pykka.Timeout: print('Could not stop actor {0} within the specified ' 'timeout.'.format(actor_ref))
class TestPropertyBasicDataTypes(object): """ Contains a collection of pytest tests that validate the property getter, setter and deleter methods for different basic data types. """ def test_boolean_property(self, x_series_device): with nidaqmx.Task() as task: task.ai_channels.add_ai_voltage_chan( x_series_device.ai_physical_chans[0].name) task.timing.cfg_samp_clk_timing(1000) task.triggers.start_trigger.cfg_dig_edge_start_trig( '/{0}/Ctr0InternalOutput'.format(x_series_device.name)) # Test property initial value. assert not task.triggers.start_trigger.retriggerable # Test property setter and getter. task.triggers.start_trigger.retriggerable = True assert task.triggers.start_trigger.retriggerable # Test property deleter. del task.triggers.start_trigger.retriggerable assert not task.triggers.start_trigger.retriggerable def test_enum_property(self, x_series_device): with nidaqmx.Task() as task: task.ai_channels.add_ai_voltage_chan( x_series_device.ai_physical_chans[0].name) task.timing.cfg_samp_clk_timing( 1000, sample_mode=AcquisitionType.CONTINUOUS) # Test property initial value. assert ( task.timing.samp_quant_samp_mode == AcquisitionType.CONTINUOUS) # Test property setter and getter. task.timing.samp_quant_samp_mode = AcquisitionType.FINITE assert (task.timing.samp_quant_samp_mode == AcquisitionType.FINITE) # Test property deleter. del task.timing.samp_quant_samp_mode assert ( task.timing.samp_quant_samp_mode == AcquisitionType.CONTINUOUS) def test_float_property(self, x_series_device): with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_voltage_chan( x_series_device.ai_physical_chans[0].name, max_val=5) # Test property default value. assert ai_channel.ai_max == 5 # Test property setter and getter. max_value = 10 ai_channel.ai_max = max_value assert ai_channel.ai_max == max_value # Test property deleter. Reading this property will throw an # error after being reset. del ai_channel.ai_max with pytest.raises(DaqError) as e: read_value = ai_channel.ai_max assert e.value.error_code == -200695 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_int_property(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) with nidaqmx.Task() as task: task.ci_channels.add_ci_count_edges_chan( x_series_device.ci_physical_chans[0].name) # Test property default value. assert task.in_stream.offset == 0 # Test property setter and getter. value_to_test = random.randint(0, 100) task.in_stream.offset = value_to_test assert task.in_stream.offset == value_to_test value_to_test = random.randint(-100, 0) task.in_stream.offset = value_to_test assert task.in_stream.offset == value_to_test # Test property deleter. del task.in_stream.offset assert task.in_stream.offset == 0 def test_string_property(self, x_series_device): with nidaqmx.Task() as task: ai_channel = task.ai_channels.add_ai_voltage_chan( x_series_device.ai_physical_chans[0].name) # Test property default value. assert ai_channel.description == '' # Test property setter and getter. description = 'Channel description.' ai_channel.description = description assert ai_channel.description == description # Test property deleter. del ai_channel.description assert ai_channel.description == '' @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_uint_property(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) with nidaqmx.Task() as task: task.ai_channels.add_ai_voltage_chan( x_series_device.ai_physical_chans[0].name) task.timing.cfg_samp_clk_timing(1000) # Test property initial value. assert task.timing.samp_clk_timebase_div == 100000 # Test property setter and getter. value_to_test = random.randint(500, 10000) task.timing.samp_clk_timebase_div = value_to_test assert task.timing.samp_clk_timebase_div == value_to_test # Test property deleter. del task.timing.samp_clk_timebase_div assert task.timing.samp_clk_timebase_div == 100000
class TestContainerOperations(object): """ Contains a collection of pytest tests that validate the container operations in the Python NI-DAQmx API. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_concatenate_operations(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chans = random.sample(x_series_device.ai_physical_chans, 2) with nidaqmx.Task() as task: ai_channel_1 = task.ai_channels.add_ai_voltage_chan( ai_phys_chans[0].name, max_val=5, min_val=-5) ai_channel_2 = task.ai_channels.add_ai_voltage_chan( ai_phys_chans[1].name, max_val=5, min_val=-5) # Concatenate two channels. ai_channel = ai_channel_1 + ai_channel_2 # Test that concatenated channel name has flattened value of the # individual channel names. assert ai_channel.name == flatten_channel_string( [ai_phys_chans[0].name, ai_phys_chans[1].name]) # Test that setting property on concatenated channel changes the # property values of the individual channels. ai_channel.ai_max = 10 assert ai_channel_1.ai_max == 10 assert ai_channel_2.ai_max == 10 # Concatenate two channels. ai_channel_1 += ai_channel_2 # Test that concatenated channel name has flattened value of the # individual channel names. assert ai_channel_1.name == flatten_channel_string( [ai_phys_chans[0].name, ai_phys_chans[1].name]) # Test that setting property on concatenated channel changes the # property values of the individual channels. ai_channel_1.ai_max = 0.1 ai_channel_1.ai_min = -0.1 assert ai_channel_2.ai_max == 0.1 assert ai_channel_2.ai_min == -0.1 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_equality_operations(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chans = random.sample(x_series_device.ai_physical_chans, 2) with nidaqmx.Task() as task: ai_channel_1 = task.ai_channels.add_ai_voltage_chan( ai_phys_chans[0].name, max_val=5, min_val=-5) ai_channel_2 = task.ai_channels.add_ai_voltage_chan( ai_phys_chans[1].name, max_val=5, min_val=-5) assert ai_channel_1 == task.ai_channels[0] assert ai_channel_1 == task.ai_channels[ai_phys_chans[0].name] assert ai_channel_1 != ai_channel_2 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_hash_operations(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Reset the pseudorandom number generator with seed. random.seed(seed) ai_phys_chans = random.sample(x_series_device.ai_physical_chans, 3) with nidaqmx.Task() as task_1, nidaqmx.Task() as task_2: ai_channel_1 = task_1.ai_channels.add_ai_voltage_chan( ai_phys_chans[0].name, name_to_assign_to_channel='VoltageChannel', max_val=5, min_val=-5) ai_channel_2 = task_1.ai_channels.add_ai_voltage_chan( ai_phys_chans[1].name, max_val=5, min_val=-5) ai_channel_3 = task_2.ai_channels.add_ai_voltage_chan( ai_phys_chans[2].name, name_to_assign_to_channel='VoltageChannel', max_val=5, min_val=-5) assert hash(ai_channel_1) == hash(task_1.ai_channels[0]) assert hash(ai_channel_1) != hash(ai_channel_2) assert hash(task_1.ai_channels) != hash(task_2.ai_channels) assert hash(ai_channel_1) != hash(ai_channel_3)
class TestWatchdog(object): """ Contains a collection of pytest tests that validate the watchdog functionality in the NI-DAQmx Python API. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_watchdog_task(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) do_line = random.choice(x_series_device.do_lines) with nidaqmx.system.WatchdogTask( x_series_device.name, timeout=0.5) as task: expir_states = [DOExpirationState( physical_channel=do_line.name, expiration_state=Level.TRISTATE)] task.cfg_watchdog_do_expir_states(expir_states) task.start() # First, assert that watchdog expires after timeout. assert not task.expired time.sleep(1) assert task.expired task.clear_expiration() assert not task.expired task.stop() # Continually reset the watchdog timer using an interval less # than the timeout and assert that it never expires. task.start() for _ in range(5): task.reset_timer() time.sleep(0.2) assert not task.expired task.stop() @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_watchdog_expir_state(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) do_line = random.choice(x_series_device.do_lines) with nidaqmx.system.WatchdogTask( x_series_device.name, timeout=0.1) as task: expir_states = [DOExpirationState( physical_channel=do_line.name, expiration_state=Level.TRISTATE)] task.cfg_watchdog_do_expir_states(expir_states) expir_state_obj = task.expiration_states[do_line.name] assert expir_state_obj.expir_states_do_state == Level.TRISTATE expir_state_obj.expir_states_do_state = Level.LOW assert expir_state_obj.expir_states_do_state == Level.LOW
class TestAnalogReadWrite(TestDAQmxIOBase): """ Contains a collection of pytest tests that validate the analog Read and Write functions in the NI-DAQmx Python API. These tests use only a single X Series device by utilizing the internal loopback routes on the device. """ @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_1_chan_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) loopback_channel_pair = random.choice(loopback_channel_pairs) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.ao_channels.add_ao_voltage_chan( loopback_channel_pair.output_channel, max_val=10, min_val=-10) read_task.ai_channels.add_ai_voltage_chan( loopback_channel_pair.input_channel, max_val=10, min_val=-10) # Generate random values to test. values_to_test = [random.uniform(-10, 10) for _ in range(10)] values_read = [] for value_to_test in values_to_test: write_task.write(value_to_test) time.sleep(0.001) values_read.append(read_task.read()) numpy.testing.assert_allclose(values_read, values_to_test, rtol=0.05, atol=0.005) # Verify setting number_of_samples_per_channel (even to 1) # returns a list. value_read = read_task.read(number_of_samples_per_channel=1) assert isinstance(value_read, list) assert len(value_read) == 1 @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_n_chan_1_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) number_of_channels = random.randint(2, len(loopback_channel_pairs)) channels_to_test = random.sample(loopback_channel_pairs, number_of_channels) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.output_channel for c in channels_to_test]), max_val=10, min_val=-10) read_task.ai_channels.add_ai_voltage_chan(flatten_channel_string( [c.input_channel for c in channels_to_test]), max_val=10, min_val=-10) # Generate random values to test. values_to_test = [ random.uniform(-10, 10) for _ in range(number_of_channels) ] write_task.write(values_to_test) time.sleep(0.001) values_read = read_task.read() numpy.testing.assert_allclose(values_read, values_to_test, rtol=0.05, atol=0.005) # Verify setting number_of_samples_per_channel (even to 1) # returns a list of lists. value_read = read_task.read(number_of_samples_per_channel=1) assert isinstance(value_read, list) assert isinstance(value_read[0], list) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_1_chan_n_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(20, 100) sample_rate = random.uniform(1000, 5000) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) loopback_channel_pair = random.choice(loopback_channel_pairs) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task, \ nidaqmx.Task() as sample_clk_task: # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. sample_clk_task.co_channels.add_co_pulse_chan_freq( '{0}/ctr0'.format(x_series_device.name), freq=sample_rate, idle_state=Level.LOW) sample_clk_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/{0}/Ctr0InternalOutput'.format( x_series_device.name) write_task.ao_channels.add_ao_voltage_chan( loopback_channel_pair.output_channel, max_val=10, min_val=-10) write_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.RISING, samps_per_chan=number_of_samples) read_task.ai_channels.add_ai_voltage_chan( loopback_channel_pair.input_channel, max_val=10, min_val=-10) read_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=number_of_samples) # Generate random values to test. values_to_test = [ random.uniform(-10, 10) for _ in range(number_of_samples) ] write_task.write(values_to_test) # Start the read and write tasks before starting the sample clock # source task. read_task.start() write_task.start() sample_clk_task.start() values_read = read_task.read( number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose(values_read, values_to_test, rtol=0.05, atol=0.005) @pytest.mark.parametrize('seed', [generate_random_seed()]) def test_n_chan_n_samp(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(20, 100) sample_rate = random.uniform(1000, 5000) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) number_of_channels = random.randint(2, len(loopback_channel_pairs)) channels_to_test = random.sample(loopback_channel_pairs, number_of_channels) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task, \ nidaqmx.Task() as sample_clk_task: # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. sample_clk_task.co_channels.add_co_pulse_chan_freq( '{0}/ctr0'.format(x_series_device.name), freq=sample_rate) sample_clk_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/{0}/Ctr0InternalOutput'.format( x_series_device.name) write_task.ao_channels.add_ao_voltage_chan(flatten_channel_string( [c.output_channel for c in channels_to_test]), max_val=10, min_val=-10) write_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.RISING, samps_per_chan=number_of_samples) read_task.ai_channels.add_ai_voltage_chan(flatten_channel_string( [c.input_channel for c in channels_to_test]), max_val=10, min_val=-10) read_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=number_of_samples) # Generate random values to test. values_to_test = [[ random.uniform(-10, 10) for _ in range(number_of_samples) ] for _ in range(number_of_channels)] write_task.write(values_to_test) # Start the read and write tasks before starting the sample clock # source task. read_task.start() write_task.start() sample_clk_task.start() values_read = read_task.read( number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose(values_read, values_to_test, rtol=0.05, atol=0.005)
#probamos un diagnostico para ver si reconoce la placa DAQ y que nombre le está dando #------------ Diagnostico ------------ #correr esto primero y ver que nombre le pone al device!! from nidaqmx import system, constants s = system.System() nombre = list(s.devices) print(nombre) dev = nombre[0] print(dev.name[2]) ##poner esto en la consola para ver que le puedo pedir a dev #dir(dev) @pytest.mark.parametrize('seed', [generate_random_seed()]) # Reset the pseudorandom number generator with seed. def test_one_sample_uint32(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_pulses = 100#random.randint(100) frequency = random.uniform(1000, 10000) # Select random counters from the device. counters = random.sample(self._get_device_counters(x_series_device), 2) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.co_channels.add_co_pulse_chan_freq( counters[0], freq=frequency)