Git Product home page Git Product logo

nidaqmx-python's Introduction

Info Contains a Python API for interacting with NI-DAQmx. See GitHub for the latest source.
Author National Instruments

About

The nidaqmx package contains an API (Application Programming Interface) for interacting with the NI-DAQmx driver. The package is implemented in Python. The package is implemented as a complex, highly object-oriented wrapper around the NI-DAQmx C API using the ctypes Python library.

nidaqmx supports all versions of the NI-DAQmx driver that ships with the C API. The C API is included in any version of the driver that supports it. The nidaqmx package does not require installation of the C header files.

Some functions in the nidaqmx package may be unavailable with earlier versions of the NI-DAQmx driver. Visit the ni.com/downloads to upgrade your version of NI-DAQmx.

nidaqmx supports Windows and Linux operating systems where the NI-DAQmx driver is supported. Refer to NI Hardware and Operating System Compatibility for which versions of the driver support your hardware on a given operating system.

nidaqmx supports CPython 3.8+ and PyPy3.

Installation

Running nidaqmx requires NI-DAQmx to be installed. Visit ni.com/downloads to download the latest version of NI-DAQmx. None of the recommended Additional items are required for nidaqmx to function, and they can be removed to minimize installation size. It is recommended you continue to install the NI Certificates package to allow your Operating System to trust NI built binaries, improving your software and hardware installation experience.

nidaqmx can be installed with pip:

$ python -m pip install nidaqmx

Similar Packages

There are similar packages available that also provide NI-DAQmx functionality in Python:

Getting Started

In order to use the nidaqmx package, you must have at least one DAQ (Data Acquisition) device installed on your system. Both physical and simulated devices are supported. The examples below use an X Series DAQ device (e.g.: PXIe-6363, PCIe-6363, or USB-6363). You can use NI MAX or NI Hardware Configuration Utility to verify and configure your devices.

Finding and configuring device name in NI MAX:

NI MAX Device Name

Finding and configuring device name in NI Hardware Configuration Utility:

NI HWCU Device Name

Tasks in NI-DAQmx

A task is a collection of one or more virtual channels with timing, triggering, and other properties. Refer to NI-DAQmx Task for more information.

Example code to create a task:

>>> import nidaqmx
>>> with nidaqmx.Task() as task:
...     pass

Virtual Channels in NI-DAQmx

Virtual channels, or sometimes referred to generically as channels, are software entities that encapsulate the physical channel along with other channel specific information (e.g.: range, terminal configuration, and custom scaling) that formats the data. A physical channel is a terminal or pin at which you can measure or generate an analog or digital signal. A single physical channel can include more than one terminal, as in the case of a differential analog input channel or a digital port of eight lines. Every physical channel on a device has a unique name (for instance, cDAQ1Mod4/ai0, Dev2/ao5, and Dev6/ctr3) that follows the NI-DAQmx physical channel naming convention. Refer to NI-DAQmx Channel for more information.

Example code that adds an analog input channel to a task, configures the range, and reads data:

>>> import nidaqmx
>>> with nidaqmx.Task() as task:
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai0", min_val=-10.0, max_val=10.0)
...     task.read()
...
AIChannel(name=Dev1/ai0)
-0.14954069643238624

Example code that adds multiple analog input channels to a task, configures their range, and reads data:

>>> import nidaqmx
>>> with nidaqmx.Task() as task:
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai0", min_val=-5.0, max_val=5.0)
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai1", min_val=-10.0, max_val=10.0)
...     task.read()
...
AIChannel(name=Dev1/ai0)
AIChannel(name=Dev1/ai1)
[-0.07477034821619312, 0.8642841883602405]

Timing

You can use software timing or hardware timing to control when a signal is acquired or generated. With hardware timing, a digital signal, such as a clock on your device, controls the rate of acquisition or generation. With software timing, the rate at which the samples are acquired or generated is determined by the software and operating system instead of by the measurement device. A hardware clock can run much faster than a software loop. A hardware clock is also more accurate than a software loop. Refer to Timing, Hardware Versus Software for more information.

Example code to acquire finite amount of data using hardware timing:

>>> import nidaqmx
>>> from nidaqmx.constants import AcquisitionType, READ_ALL_AVAILABLE
>>> with nidaqmx.Task() as task:
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
...     task.timing.cfg_samp_clk_timing(1000.0, sample_mode=AcquisitionType.FINITE, samps_per_chan=10)
...     data = task.read(READ_ALL_AVAILABLE)
...     print("Acquired data: [" + ", ".join(f"{value:f}" for value in data) + "]")
...
AIChannel(name=Dev1/ai0)
Acquired data: [-0.149693, 2.869503, 4.520249, 4.704886, 2.875912, -0.006104, -2.895596, -4.493698, -4.515671, -2.776574]

TDMS Logging

Technical Data Management Streaming (TDMS) is a binary file format that allows for high-speed data logging. When you enable TDMS data logging, NI-DAQmx can stream data directly from the device buffer to the hard disk. Refer to TDMS Logging for more information.

Example code to acquire finite amount of data and log it to a TDMS file:

>>> import nidaqmx
>>> from nidaqmx.constants import AcquisitionType, LoggingMode, LoggingOperation, READ_ALL_AVAILABLE
>>> with nidaqmx.Task() as task:
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
...     task.timing.cfg_samp_clk_timing(1000.0, sample_mode=AcquisitionType.FINITE, samps_per_chan=10)
...     task.in_stream.configure_logging("TestData.tdms", LoggingMode.LOG_AND_READ, operation=LoggingOperation.CREATE_OR_REPLACE)
...     data = task.read(READ_ALL_AVAILABLE)
...     print("Acquired data: [" + ", ".join(f"{value:f}" for value in data) + "]")
...
AIChannel(name=Dev1/ai0)
Acquired data: [-0.149693, 2.869503, 4.520249, 4.704886, 2.875912, -0.006104, -2.895596, -4.493698, -4.515671, -2.776574]

To read the TDMS file, you can use the npTDMS third-party module. Refer to npTDMS for detailed usage.

Example code to read the TDMS file created from example above and display the data:

>>> from nptdms import TdmsFile
>>> with TdmsFile.read("TestData.tdms") as tdms_file:
...   for group in tdms_file.groups():
...     for channel in group.channels():
...       data = channel[:]
...       print("data: [" + ", ".join(f"{value:f}" for value in data) + "]")
...
data: [-0.149693, 2.869503, 4.520249, 4.704886, 2.875912, -0.006104, -2.895596, -4.493698, -4.515671, -2.776574]

Plot Data

To visualize the acquired data as a waveform, you can use the matplotlib.pyplot third-party module. Refer to Pyplot tutorial for detailed usage.

Example code to plot waveform for acquired data using matplotlib.pyplot module:

>>> import nidaqmx
>>> from nidaqmx.constants import AcquisitionType, READ_ALL_AVAILABLE
>>> import matplotlib.pyplot as plt
>>> with nidaqmx.Task() as task:
...   task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
...   task.timing.cfg_samp_clk_timing(1000.0, sample_mode=AcquisitionType.FINITE, samps_per_chan=50)
...   data = task.read(READ_ALL_AVAILABLE)
...   plt.plot(data)
...   plt.ylabel('Amplitude')
...   plt.title('Waveform')
...   plt.show()
...
AIChannel(name=Dev1/ai0)
[<matplotlib.lines.Line2D object at 0x00000141D7043970>]
Text(0, 0.5, 'Amplitude')
Text(0.5, 1.0, 'waveform')

Waveform

For more information on how to use nidaqmx package, refer to Usage section below.

Usage

The following is a basic example of using an nidaqmx.task.Task object. This example illustrates how the single, dynamic nidaqmx.task.Task.read method returns the appropriate data type.

>>> import nidaqmx
>>> with nidaqmx.Task() as task:
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
...     task.read()
...
-0.07476920729381246
>>> with nidaqmx.Task() as task:
...     task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
...     task.read(number_of_samples_per_channel=2)
...
[0.26001373311970705, 0.37796597238117036]
>>> from nidaqmx.constants import LineGrouping
>>> with nidaqmx.Task() as task:
...     task.di_channels.add_di_chan(
...         "cDAQ2Mod4/port0/line0:1", line_grouping=LineGrouping.CHAN_PER_LINE)
...     task.read(number_of_samples_per_channel=2)
...
[[False, True], [True, True]]

A single, dynamic nidaqmx.task.Task.write method also exists.

>>> import nidaqmx
>>> from nidaqmx.types import CtrTime
>>> with nidaqmx.Task() as task:
...     task.co_channels.add_co_pulse_chan_time("Dev1/ctr0")
...     sample = CtrTime(high_time=0.001, low_time=0.001)
...     task.write(sample)
...
1
>>> with nidaqmx.Task() as task:
...     task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
...     task.write([1.1, 2.2, 3.3, 4.4, 5.5], auto_start=True)
...
5

Consider using the nidaqmx.stream_readers and nidaqmx.stream_writers classes to increase the performance of your application, which accept pre-allocated NumPy arrays.

Following is an example of using an nidaqmx.system.System object.

>>> import nidaqmx.system
>>> system = nidaqmx.system.System.local()
>>> system.driver_version
DriverVersion(major_version=16L, minor_version=0L, update_version=0L)
>>> for device in system.devices:
...     print(device)
...
Device(name=Dev1)
Device(name=Dev2)
Device(name=cDAQ1)
>>> import collections
>>> isinstance(system.devices, collections.Sequence)
True
>>> device = system.devices['Dev1']
>>> device == nidaqmx.system.Device('Dev1')
True
>>> isinstance(device.ai_physical_chans, collections.Sequence)
True
>>> phys_chan = device.ai_physical_chans['ai0']
>>> phys_chan
PhysicalChannel(name=Dev1/ai0)
>>> phys_chan == nidaqmx.system.PhysicalChannel('Dev1/ai0')
True
>>> phys_chan.ai_term_cfgs
[<TerminalConfiguration.RSE: 10083>, <TerminalConfiguration.NRSE: 10078>, <TerminalConfiguration.DIFFERENTIAL: 10106>]
>>> from enum import Enum
>>> isinstance(phys_chan.ai_term_cfgs[0], Enum)
True

You can find more examples in nidaqmx-python examples.

Bugs / Feature Requests

To report a bug or submit a feature request, please use the GitHub issues page.

Information to Include When Asking for Help

Please include all of the following information when opening an issue:

  • Detailed steps on how to reproduce the problem and full traceback, if applicable.

  • The python version used:

    $ python -c "import sys; print(sys.version)"
    
  • The versions of the nidaqmx and numpy packages used:

    $ python -m pip list
    
  • The version of the NI-DAQmx driver used. Follow this KB article to determine the version of NI-DAQmx you have installed.

  • The operating system and version, for example Windows 7, CentOS 7.2, ...

Documentation

Documentation is available here.

Additional Documentation

Refer to the NI-DAQmx Help for API-agnostic information about NI-DAQmx or measurement concepts.

NI-DAQmx Help installs only with the full version of NI-DAQmx.

License

nidaqmx is licensed under an MIT-style license (see LICENSE). Other incorporated projects may be licensed under different licenses. All licenses allow for non-commercial and commercial use.

gRPC Features For driver APIs that support it, passing a GrpcSessionOptions instance as a parameter is subject to the NI General Purpose EULA (see NILICENSE).

nidaqmx-python's People

Contributors

archerleong avatar bkeryan avatar carlandersson avatar charitylxy avatar deborahooi96 avatar dependabot[bot] avatar dharaniprakashkm avatar fhchl avatar jlin-ni avatar joe-from-mtl avatar keer1111 avatar mounikabattu17 avatar neilvana avatar rgerkin avatar sakthi-sm avatar samchris007 avatar samuelgarcia avatar shastriuf avatar sov-trotter avatar stefand986 avatar subash-suresh avatar texasaggie97 avatar tirkarthi avatar vigkre avatar waynedroid avatar wondernutz avatar zariiii9003 avatar zhindes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nidaqmx-python's Issues

Flatten/unflatten shouldn't be a part of the API

These exist in LV / C due to the nature of how to interact with the API.

In python

  • flatten
    • str(task.ai_channels)
      unflatten
    • accept both string and arrays of strings.

With these, they shouldn't be needed anymore.

how to configure usb-6009 from Python

I would like to configure the USB-6009 as the following parameters:

  1. sample rate 1000Hz
  2. acquistion mode: continuous
  3. input configuration: RSE

I can read usb-6009 by the following code, but I need to re-configure the 6009 by those upper parameters.
with nidaqmx.Task() as task:
task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
f = open('data_ni_noise_3.csv', 'w+')
f.write('data0,timestamp\n')
while True:
onedata = task.read()
f.write(str(onedata)+',0\n')
f.close()

Thanks!

out_stream.relative_to do not target correct function in dll

Hello,

Trying to use out_stream.relative_to raises an error.

Looking in nidaqmx_task_modules\out_stream.py , I see that the function "relative_to" (setter, property and delete) have errors:
DAQmxGetWriteRelativeTo should be use and not DAQmxGetRelativeTo

For set and delete, same, insert a Write before Relative

Building the documentation fails due to failed module import

If nidaqmx-python is not installed yet, building the nidaqmx-python documentation fails because sphinx cannot import the nidaqmx-python module.

Adding

import os
import sys
sys.path.insert(0, os.path.abspath('../'))

to docs/conf.py fixes the problem (see my pull request #10 ).

System information: Windows 7 (x64), Python 3.6.0 :: Anaconda 4.3.1 (64-bit).

Documentation should encourage restricing install to compatible versions

This project is following semver. The documentation should encourage the user to follow best practices, including helping them from accidentally upgrade to an incompatible version until they are ready

For example, instead of

$ python -m pip install nidaqmx

have

$ python -m pip install nidaqmx~=0.5.0

According to PEP 440, the compatible release version specifier will translate from ~=0.5.0 to >=0.5.0,==0.5.*

Audit function parameter names

Python supports named parameters and would ideally be used in long lists by add channel.

Changing a parameter name will break compatibility though. We should audit to ensure the parameter names are things that we want.

callback_data parameter missing from event_registration functions

For example, the function
def register_every_n_samples_acquired_into_buffer_event(self, sample_interval, callback_method):
has no callback_data as a parameter, but the documentation describes:
The callback_data parameter contains the value you passed in the callback_data parameter of this function.
Is it not implemented yet? Or am I missing something?

Linux supported?

The nidaqmx-python/README.rst says that "nidaqmx supports only the Windows operating system". However, loading of the C library in linux seem to be supported in nidaqmx-python/nidaqmx/_lib.py.

Even if Linux support is experimental or in-official, perhaps it could still be mentioned in the README?

Unregistring callbacks

Using the 'register_every_n_samples_acquired_into_buffer_event' function from the 'task' module to unregister callback functions by passing 'None' instead of a function is not possible.
The variable 'callback_method_ptr' is referenced at line 788, but nothing is assigned to it.
I have not tried it but I assume from looking at the code that this problem will exist in the other related functions as well.

set sample rate of usb-6009

I use the following code to configure usb6009, and the printed time(ms) is:

My intention is set the sample rate as 1000Hz. so to read 1024 sample points should need around 1024ms. the printed t2-t1 is around 770ms.

if I change sample rate to 2000Hz, t2-t1 is still 770ms.... it seems that setting sample rate doesn't take effect.

t2-t1 = 779ms, t3-t2 =266ms
t2-t1 = 758ms, t3-t2 =249ms
t2-t1 = 775ms, t3-t2 =260ms
t2-t1 = 763ms, t3-t2 =250ms
t2-t1 = 774ms, t3-t2 =259ms
t2-t1 = 765ms, t3-t2 =263ms
t2-t1 = 762ms, t3-t2 =256ms
t2-t1 = 768ms, t3-t2 =256ms
t2-t1 = 767ms, t3-t2 =270ms

code to configure and acqure data:

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

nfft = 1024
fs = 1000.0
freqs = np.linspace(0, fs/2, nfft/2+1)

with nidaqmx.Task() as task:
    task.ai_channels.add_ai_voltage_chan("Dev1/ai0", terminal_config=TerminalConfiguration.RSE, min_val=-5.0, max_val=5.0, units=VoltageUnits.VOLTS)
    task.timing.cfg_samp_clk_timing(fs, active_edge=Edge.RISING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=nfft)

    # task.start()
    # task.stop()
    while True:

        t1 = (int(round(time.time() * 1000)))
        data = task.read(number_of_samples_per_channel=nfft)
        t2 = (int(round(time.time() * 1000)))
        tdata = np.array(data)
        tdata -= np.mean(tdata)
        ffto = np.fft.fft(tdata)
        ffto = np.abs(ffto)
        ffto = ffto[0:(nfft/2+1)]

        ax1.clear()
        ax2.clear()
        ax1.plot(data)
        ax2.plot(freqs, ffto)
        fig.show(0)
        plt.pause(0.000000001)
        t3 = (int(round(time.time() * 1000)))
        print 't2-t1 = {0}ms, t3-t2 ={1}ms'.format(t2-t1, t3-t2)

Using nidaqmx over ethernet

Hi,

Our lab is trying to use nidaqmx for a NI 9182 compactDAQmx chasis over the ethernet.

The tutorials you have so far all concern a device mounted over USB. What would be the syntax to use for ethernet?

Here is what I have so far: It would be nice if there is a way to list devices, like the visa library.

__author__ = 'Ge Yang'

ip_address = "192.168.1.216"
import nidaqmx
from nidaqmx.types import CtrTime
with nidaqmx.Task() as task:
    task.co_channels.add_co_pulse_chan_time("{ip}/ctr0".format(ip=ip_address))
    sample = CtrTime(high_time=0.001, low_time=0.001)
    task.write(sample)

with nidaqmx.Task() as task:
    task.ao_channels.add_ao_voltage_chan("{ip}/ao0".format(ip=ip_address))
    task.write([1.1, 2.2, 3.3, 4.4, 5.5], auto_start=True)

Cannot catch load/version issues with public API

It looks like nidaqmx-python/nidaqmx/_lib.py uses a different exception hierarchy than the API (nidaqmx-python/nidaqmx/errors.py).

I can understand not exposing the subclass exceptions since ctypes is an implementation detail but it seems like they should use a common base class for both to catch problems.

Create an example for TDMS recording

The examples don't show how to log long recording data to a tdms file. I'm assuming this API can do that. Anyone have a hello world for that?

Currently I've set it up to register a callback for every N samples to append some list, as in the every_n_samples_event.py examples. At the end of the script, I write that list to a file. The problem comes when I'm now trying parse all the different channels; they're separated in chunks of N and I'd like to just use the work NI already did with TDMS.

Support Waveform Reads/Writes

Right now, there isn't a way to get timing information with reads.

Other parts of the "waveform" part of the API

  • Waveform Writes
    • Setting timing according to dt
  • Duration reads (specifying amount of data by length of time rather than sample count)

register signal event not supported?

Hi all,
I have troubles registering a change detection event. The following code

import nidaqmx.system

def getDaqDcPowerVoltage(task_handle=0, every_n_samples_event_type=0, number_of_samples=0, callback_data=0):
   result = None
   print('this is the digital change detection callback function.')
   print(callback_data)                                            
   return 0                                                        
   
DaqMxSystem = nidaqmx.system.System.local()                         
task = nidaqmx.Task()                                               
task.di_channels.add_di_chan('PXI1Slot2/port0/line0')               
task.timing.cfg_samp_clk_timing(1000)                               
task.Buffer = 10                                                    
task.output_buf_size = 10                                           
task.read_all_avail_samp = True                                     
task.register_signal_event(nidaqmx.constants.Signal.CHANGE_DETECTION_EVENT, getDaqDcPowerVoltage(callback_data = 0))
task.start()

ends in this error:

 cfunc = lib_importer.daqlib.DAQmxRegisterSignalEvent
 AttributeError: 'DaqLibImporter' object has no attribute 'daqlib'

I saw, that the DaqLibImporter class in _lib.py is truely missing the daqlib property. Is this something that is not supported in the current nidaqmx-python implementation or am I doing something wrong?

BR Andreas

problem with reading from encoders

Hi,
I'm using NI6321 with incremental angular encoder.
I use the command: "task1.ci_channels.add_ci_ang_encoder_chan("Dev1/ctr1") "
when I try to read (task1.read function) the angular, I get a steady value of 0.0 even though the correct values are different (as I can see in NIMAX for example)
Do you have an idea why this is happening?
thanks in advance,
Yotam

Exception in callback done_event

Hi,

First of all, thank you for sharing this module. Interacting with NI-DAQmx through Python makes life a lot easier!

When working with the nidaqmx-python, I get the following exception when using the done-event (see minimal example below):

NoneType: None
Exception ignored in: <function cb_done at 0x0000025BE34427B8>

How can I prevent this error ?

Furthermore, I noticed that the callback receives two ints and a None as arguments. Based on the C-API I assume these are the task handle, options parameter and the callback data. How can I use the object handle to recover the object that send the callback?

import nidaqmx
from nidaqmx.constants import *

def cb_done(*args):
    print('Done!')

    for a in args:
        print(a)


if __name__ == "__main__":
    devname = 'nidaq'

    # Create task:
    mytask = nidaqmx.Task('example')
    dev = nidaqmx.system.Device(devname)
    dev.reserve_network_device(True)

    # Add some signal to task:
    mod_name = 'Mod1'
    ai_index = 0
    mytask.ai_channels.add_ai_accel_chan('{0}{2}/ai{1}'.format(devname, ai_index, mod_name),
                                           name_to_assign_to_channel= 'sig1',
                                           terminal_config=TerminalConfiguration.PSEUDODIFFERENTIAL,
                                           min_val=-5.0, max_val=5.0,
                                           units=AccelUnits.METERS_PER_SECOND_SQUARED,
                                           sensitivity=100.0,
                                           sensitivity_units=AccelSensitivityUnits.M_VOLTS_PER_G,
                                           current_excit_source=ExcitationSource.INTERNAL,
                                           current_excit_val   =0.020,
                                           custom_scale_name=''
                                        )

    # Configure timing:
    mytask.timing.cfg_samp_clk_timing(1e3, source='',
                                        active_edge=Edge.RISING,
                                        sample_mode=AcquisitionType.FINITE,
                                        samps_per_chan=int(1e4)
                                     )

    mytask.register_done_event(cb_done)

    # Perform task
    print('Performing Measurement Task...')
    mytask.start()
    mytask.wait_until_done()

READ_ALL_AVAILABLE don't work; in_stream.avail_samp_per_chan always return 0

Windows 10
NI DAQmx v17
python 2.7
USB-6251 (but also have this problem on a PXI device)

I spent a good couple of days trying to make the code run with AcquisitionType.CONTINUOUS and READ_ALL_AVAILABLE but nothing seemed to work.

After a lot of time wondering if it was something related to the acquisition, I could finally pinpoint the problem to the read function.

This code works fine:

data = None
task = nidaqmx.Task()
task.ai_channels.add_ai_voltage_chan("Dev1/ai1")
task.timing.cfg_samp_clk_timing(rate=60, sample_mode=AcquisitionType.CONTINUOUS)
task.start()
time.sleep(5)
t0=time.ctime()
data = task.read(300)
print "{}\n{}".format(time.ctime(), t0)
task.stop()
task.close()
print data

I know the buffer is already filled (and therefore not a problem with the acquisition) because the read function returns instantaneously, without waiting for data, and the data is what I expect.

This, however, don't:

data = None
task = nidaqmx.Task()
task.ai_channels.add_ai_voltage_chan("Dev1/ai1")
task.timing.cfg_samp_clk_timing(rate=60, sample_mode=AcquisitionType.CONTINUOUS)
task.start()
time.sleep(5)
t0=time.ctime()
data = task.read(READ_ALL_AVAILABLE)  # ONLY CHANGED FROM 300 to READ_ALL_AVAILABLE
print "{}\n{}".format(time.ctime(), t0)
task.stop()
task.close()
print data

And I get an empty list for my data variable.

So I read the source code and apparently the avail_samp_per_chan property (function) always return zero, for instance right before the read(300) command:

time.sleep(5)
print task.in_stream.avail_samp_per_chan
data = task.read(300)

So I believe that it is the problem. This function is not returning the correct number of available samples.

Can you confirm the problem and if so, is there any short-term workaround for this? This is a bit urgent as this is being used in a project that has already blew its deadline.

`port0/line1:3` returns 2 lines rather than 3.

Not sure if its just the documentation or the actual code but for this code from the README.rst file

>>> from nidaqmx.constants import LineGrouping
>>> with nidaqmx.Task() as task:
...     task.di_channels.add_di_chan(
...         "cDAQ2Mod4/port0/line1:3", line_grouping=LineGrouping.CHAN_PER_LINE)
...     task.read(number_of_samples_per_channel=2)
...
[[False, True], [True, True]]

The task should have 3 lines in it (port0/line1, port0/line2, port0/line3) because the range syntax is inclusive ([1, 3]) rather than exclusive ([1, 3)).

I confirmed this by reproducing the code in LabVIEW (1Samp rather than NSamp read though). I got 3 lines of bools back.

Error when I call python APIs

On Windows 10, I installed anaconda 2.7 and PyCharm to acquire usb-6009 data.
the driver of usb6009 is correctly installed as I can observe data from "Measurement & Automation Explorer" correctly.

import nidaqmx

with nidaqmx.Task() as task:
aaa=0
task.ai_channels.add_ai_voltage_chan("Dev1/ai0")
print task.read()

when I run the upper code, I got the following error:

Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.1.5\helpers\pydev\pydevd.py", line 1591, in
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.1.5\helpers\pydev\pydevd.py", line 1018, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:/work/code_python/mwsignal/nidaq_mw.py", line 23, in
with nidaqmx.Task() as task:
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx\task.py", line 84, in init
self._handle = lib_importer.task_handle(0)
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx_lib.py", line 178, in task_handle
self._parse_typedefs()
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx_lib.py", line 235, in _parse_typedefs
version = system.driver_version
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx\system\system.py", line 73, in driver_version
return DriverVersion(self._major_version, self._minor_version,
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx\system\system.py", line 108, in _major_version
cfunc = lib_importer.windll.DAQmxGetSysNIDAQMajorVersion
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx_lib.py", line 166, in windll
self._import_lib()
File "C:\ProgramData\Anaconda2\lib\site-packages\nidaqmx_lib.py", line 203, in import_lib
windll = ctypes.windll.LoadLibrary(lib_name)
File "C:\ProgramData\Anaconda2\lib\ctypes_init
.py", line 440, in LoadLibrary
return self.dlltype(name)
File "C:\ProgramData\Anaconda2\lib\ctypes_init
.py", line 362, in init
self._handle = _dlopen(self._name, mode)
TypeError: LoadLibrary() argument 1 must be string, not unicode
Exception AttributeError: "'Task' object has no attribute '_handle'" in <object repr() failed> ignored

Process finished with exit code 1

Counter Resetting Every Read

I am using a USB-6009 multifunction DAQ with Windows 10 and Python 3.6 as a digital counter on the PFI0 port. The counter tests good in NI MAX. Also, if I read multiple samples, the counter does increment as expected when presented with a 1 kHz square wave.

However, I find that the counter state is reset before every read operation. In other words, if I read 1 sample at a time, I will get the value "0" or "1" as an output. If I read, for example, 1000 samples at once, each sample (more or less, depending on sampling rate) is incrementing as expected.

I am using the example code in ci_count_edges.py, which uses i_channels.add_ci_count_edges_chan().

The underlying NI DAQ MX function is DAQmxReadCounterU32Ex(), which isn't supposed to do this. Therefore, the cause is a bit of a mystery to me.

nidaqmx memory leak

version: nidaqmx 0.5.7
NI libraries: nidaq core 9.6
UPDATE: also tested with 17.1 and experience same issue.
python 2.7.14

I've been using v9.6 for years. Recently changed from PyNidaqMx to nidaqmx and noticed a memory leak when polling a digital input line. The below code, while extreme, exacerbates the issue.

import nidaqmx

daq = nidaqmx.system.System().devices[0]

while True:
    with nidaqmx.Task('task') as task:
        task.di_channels.add_di_chan(lines=daq.name + '/port0/line3')
        task.start()
        result = task.read()

if this is of any assistance, printing the heap (using guppy.hpy.heap()) after several minutes of running the above program shows:

12 Partition of a set of 601822 objects. Total size = 59485576 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  12000   2  6288000  11   6288000  11 dict of nidaqmx._task_modules.triggers.Triggers
     1  12000   2  6288000  11  12576000  21 dict of nidaqmx.task.Task
     2  47277   8  4590016   8  17166016  29 str
     3  51472   9  2037184   3  19203200  32 list
     4  14373   2  1686220   3  20889420  35 unicode
     5  12000   2  1680000   3  22569420  38 dict of 0x8092b40
     6  12000   2  1680000   3  24249420  41 dict of 0x80f7030
     7  12000   2  1680000   3  25929420  44 dict of 0x80f7208
     8  12000   2  1680000   3  27609420  46 dict of 0x80f73e0
     9  12000   2  1680000   3  29289420  49 dict of 0x80f75b8

is_task_done() cannot be used

When I do:
`

import nidaqmx
task = nidaqmx.Task()
task.is_task_done()
`

I get :

error "nidaqmx\task.py", line 522, in is_task_done return is_task_done.value nidaqmx\_lib.py", line 35, in _getter return bool(ctypes.c_uint.value.fget(self)) AttributeError: 'getset_descriptor' object has no attribute 'fget'


OS : windows 7 64 bits
Python : 3.5.2 with Anaconda 4.2.0 (32bits)
NIDAQmx : print(system.driver_version) = DriverVersion(major_version=9, minor_version=2, update_version=3)

nidaqmx doesn't work on Python 2.7.13

There is an issue in Python 2.7.13 where _ctypes.LoadLibrary no longer accepts Unicode objects. This will be patched in 2.7.14, but for now users should downgrade to 2.7.12 to use the nidaqmx package.

no version information available

There used to be a version.py file in nidaqmx, which seems to have been removed. This was useful in that I could check nidaqmx.version and ensure that the minimum revision was installed for my application.

Or, please provide a nidaqmx.version like most python packages do.

The fact that older versions had a version.py file means that upgrading will leave the old file there, thus confusing the situation.

task change event with nimi nidcpower sequence sweep

Hi,
I have the following use case. I define a sequence on a nidcpower device using the nimi nidcpower lib. during this sequence I need to observe if a digital input line changes its state. If the state changes I need to measure the nidcpower voltage.

Problem is, that the implementation of wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE, 10) is obviously blocking. Means that my callbacks for the registered events are lost. At least I do not enter the callback at all. So I refactored the implementation to use a thread for both, the nidaqmx task, and nidcpower wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE, 10) . Unfortunately the callback is still not invoked. Is this because the sync option in the c_func call for register_signal_event is always '0'? compare this help site
http://zone.ni.com/reference/en-XX/help/370471AE-01/daqmxcfunc/daqmxregistersignalevent/

If this is the issue, what would be the correct value for this option to be able to invoke the callback from within the thread?

Or is my use case not supported?

try to set voltage that is too high, that is different from what is given.

Hi,

I'm running this code below trying to set the voltage of an NI-9189 with a 9250 DAC module. I try to give the output channel samples from -3.0 v to 3.0 v, but when ran the c module responds with an error claiming that I'm trying to set it to 10.0 v which is beyond the input range of the module.

The nidaqmx library is compiled from this git repo's master. Any help would be greatly appreciated, and thanks in advance!

the code is below:

__author__ = 'Ge Yang'

import nidaqmx.system

system = nidaqmx.system.System.local()
print(system.driver_version)
# DriverVersion(major_version=17L, minor_version=1L, update_version=0L)

for device in system.devices:
    print(device)
# Device(name=cDAQ9189-1C742CB)
# Device(name=cDAQ9189-1C742CBMod4)
# Device(name=cDAQ9189-1C742CBMod5)
# Device(name=cDAQ9189-1C742CBMod6)
# Device(name=cDAQ9189-1C742CBMod7)
# Device(name=cDAQ9189-1C742CBMod8)


import numpy as np
samples = np.linspace(-2, 2, 1000)
with nidaqmx.Task() as task:
    task.ao_channels.add_ao_voltage_chan("cDAQ9189-1C742CBMod7/ao0")
    task.write(samples, auto_start=True)
C:\Users\slab\AppData\Local\Enthought\Canopy32\User\Scripts\python.exe "S:/_Data/170422 - EonHe M018V6 with L3 etch/packages/NI_DAQ_driver_demo/demo2.py"
DriverVersion(major_version=17L, minor_version=1L, update_version=0L)
Device(name=cDAQ9189-1C742CB)
Device(name=cDAQ9189-1C742CBMod4)
Device(name=cDAQ9189-1C742CBMod5)
Device(name=cDAQ9189-1C742CBMod6)
Device(name=cDAQ9189-1C742CBMod7)
Device(name=cDAQ9189-1C742CBMod8)
Traceback (most recent call last):
  File "S:/_Data/170422 - EonHe M018V6 with L3 etch/packages/NI_DAQ_driver_demo/demo2.py", line 23, in <module>
    task.write(samples, auto_start=True)
  File "C:\Users\slab\AppData\Local\Enthought\Canopy32\User\lib\site-packages\nidaqmx\task.py", line 1169, in write
    channels_to_write = self.channels
  File "C:\Users\slab\AppData\Local\Enthought\Canopy32\User\lib\site-packages\nidaqmx\task.py", line 168, in channels
    self._handle, flatten_channel_string(self.channel_names))
  File "C:\Users\slab\AppData\Local\Enthought\Canopy32\User\lib\site-packages\nidaqmx\_task_modules\channels\channel.py", line 118, in _factory
    check_for_error(error_code)
  File "C:\Users\slab\AppData\Local\Enthought\Canopy32\User\lib\site-packages\nidaqmx\errors.py", line 127, in check_for_error
    raise DaqError(error_buffer.value.decode("utf-8"), error_code)
nidaqmx.errors.DaqError: Requested value is not a supported value for this property. The property value may be invalid because it conflicts with another property.
Property: DAQmx_AO_Max
Requested Value:  10.0
Value Must Be Greater Than: -4.242641
Value Must Be Less Than:  4.242641


Channel Name: cDAQ9189-1C742CBMod7/ao0

Task Name: _unnamedTask<0>

Status Code: -200077

Process finished with exit code 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.