clade / PyDAQmx

Interface to National Instrument NIDAQmx driver
Other
133 stars 54 forks source link

Asynchronous read each channel? #18

Closed vslm698 closed 9 years ago

vslm698 commented 9 years ago

Hi, I start to use usb-6289 to read voltage values from each channel. It works well when synchronous reading data. As I need to collect each channel with different time sequence, is there some way to asynchronous read each channel with PyDAQmx? Thanks:).

frejanordsiek commented 9 years ago

It is certainly possible, though the options may vary depending on whether you use nidaqmx or nidaqmxbase. nidaqmx has asynchronous functions using callbacks, if I remember correctly, so it might be straightforward to use them from python. But, nidaqmxbase does not and is synchronous. If you are running GNU/Linux, then you are probably using nidaqmxbase though old versions of nidaqmx are available. If you are running Windows, you could be using either, but are most likely using nidaqmx.

Regardless of which one you are using or whether the asynchronous reads can be done directly from python with nidaqmx, you can use the threading or multiprocessing modules to do it. I personally have had a lot of luck with the threading module. Basically create a thread and give it the TaskHandle for the DAQ. Then have the thread, when it is started, start a continuous acquisition (can be setup before the thread or by the thread itself) and have the thread continuously reading the data into a buffer. Then provide a function that will grab the contents of the buffer and then clear it when called. An important subtlety is that if you use numpy.ndarray for the buffer and append data to it, when you do the grab of say X samples from the beginning of it, you must use numpy.ndarray.copy() for both the returned array and the shrinking the buffer down. Otherwise you will only set slices meaning that changes to one change the other and the buffer will keep growing. An example of how to do this properly is below.

def get_X_sample(X):
    out = buf[:X, :].copy()
    buf = buf[X:, :].copy()
    return out

If you want to see a full and working example, I wrote an acquisition program based on PyDAQmx that is meant to control and run acquisition in a different python environment (possibly on another machine) and stream the data over. It can be found at frejanordsiek/pynidaqutils/pynidaqutils/analog_input.py.

vslm698 commented 9 years ago

Thanks frejanordsiek for your detailed reply, this information is very useful for us, I will first have a try and update later:).