Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Inconsistent value read by analog input port during multichannel read and write. (python NIDAQMX USB 6289)

Hi! Currently I am trying to write multiple samples through all my 4 Analog Output channels and 4 analog input channels. In order to verify that my samples read are same as the value written, I added a section of code to write those values in a text file to allow me to compare the the values. However, I noticed that only analog input 0 read values inconsistently with it's written values. Other channels were perfectly fine. I did not touch the connections of the wiring before, and the values were quite accurate based on my old tests. So i was wondering if there is any issue with my python code. I connected my ports in a closed loop manner, where ao0 =ai0, ao1=ai1 and etc. Could anyone help me on this please? ( I was actually using Jupyter notebook)

stealthsniper_1-1719545318255.png

 

Download All
0 Kudos
Message 1 of 6
(434 Views)

I would recommend using Test Panels to check if there is any problem on the wiring or hardware.

 

-------------------------------------------------------
Control Lead | Intelline Inc
0 Kudos
Message 2 of 6
(393 Views)

This is probably a very subtle timing issue, pretty deep down in the details.  One thing I noticed was that AI0 at sample i+1 would tend to match (or at least very nearly match) AI1,2,3 at sample i.   This suggests that AO0 sample i is not quite "there" yet at the instant that AI0 sample i gets captured, but that it *is* still there at the time of sample i+1.

 

How can this be?  Well here's a very recent post I made in another thread that addresses much of it.  However, your situation is slightly different with multiple AI channels on a multiplexing device where only the 1st channel in the list seems to be skewed by 1 sample.  So I would emphasize points 3 or 5 I made in that linked post.  Point 4 may have relevance, but point 3 or point 5 would be the likely fix.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy coming to an end (finally!). Permanent license pricing remains WIP. Tread carefully.
0 Kudos
Message 3 of 6
(385 Views)

Hi thanks for your reply!

For point 3, I have tried out your suggestion to set AI0 to sample at falling edge, but values are still mismatched.
For point 5, I do not know how to to implement a delayed counter clock AND also used it in my context.

And also, i plan to integrate this whole functionality of multi-channel-multi-sample-read/write in my other code. So to give some context about the big picture of what I am doing,

I am trying to create a GUI for the python code to allow me to manually adjust the analog output and input pins in a GUI on a separate window (python code attached). You can say that it should work like an oscilloscope. So i would like the option of manually control each individual analog output ports, as well as controlling all 4 analog output ports simultaneously like what we have discussed in this post. So i were to tamper with the timing by implementing a clock counter, I cant visualize in what ways does the rest of the program affected.

stealthsniper_0-1719977561228.png

 



Download All
0 Kudos
Message 4 of 6
(359 Views)

I tried to create a counter to replace it as my clock source, but it pops up this error. (Code attached). I even gave a 100seconds timeout yet it still failed.

 

Error:

{
"name": "DaqReadError",
"message": "Some or all of the samples requested have not yet been acquired.
To wait for the samples to become available use a longer read timeout or read later in your program. To make the samples available sooner, increase the sample rate. If your task uses a start trigger,  make sure that your start trigger is configured correctly. It is also possible that you configured the task for external timing, and no clock was supplied. If this is the case, supply an external clock.
 
Property: DAQmx_Read_RelativeTo
Corresponding Value: DAQmx_Val_CurrReadPos
Property: DAQmx_Read_Offset
Corresponding Value: 0
 
Task Name: _unnamedTask<6>
 
Status Code: -200284",
"stack": "---------------------------------------------------------------------------
DaqReadError                              Traceback (most recent call last)
Cell In[3], line 93
     90     write_task.start()
     92     # Read data
---> 93     reader.read_many_sample(read_data, number_of_samples_per_channel=SAMPLES_PER_CHANNEL)
     94     end_time = time.perf_counter()
     96 # Write input and output channel values to a text file
 
File c:\\Users\\bovta\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\
idaqmx\\stream_readers.py:324, in AnalogMultiChannelReader.read_many_sample(self, data, number_of_samples_per_channel, timeout)
    318 number_of_samples_per_channel = (
    319     self._task._calculate_num_samps_per_chan(
    320         number_of_samples_per_channel))
    322 self._verify_array(data, number_of_samples_per_channel, True, True)
--> 324 _, samps_per_chan_read = self._interpreter.read_analog_f64(
    325     self._handle, number_of_samples_per_channel,
    326     timeout, FillMode.GROUP_BY_CHANNEL.value, data)
    328 return samps_per_chan_read
 
File c:\\Users\\bovta\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\
idaqmx\\_library_interpreter.py:3898, in LibraryInterpreter.read_analog_f64(self, task, num_samps_per_chan, timeout, fill_mode, read_array)
   3888             cfunc.argtypes = [
   3889                 lib_importer.task_handle, ctypes.c_int,
   3890                 ctypes.c_double, ctypes.c_int,
   3891                 wrapped_ndpointer(dtype=numpy.float64,
   3892                 flags=('C','W')), ctypes.c_uint,
   3893                 ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]
   3895 error_code = cfunc(
   3896     task, num_samps_per_chan, timeout, fill_mode, read_array,
   3897     read_array.size, ctypes.byref(samps_per_chan_read), None)
-> 3898 self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
   3899 return read_array, samps_per_chan_read.value
 
File c:\\Users\\bovta\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\
idaqmx\\_library_interpreter.py:6037, in LibraryInterpreter.check_for_error(self, error_code, samps_per_chan_written, samps_per_chan_read)
   6034 extended_error_info = self.get_extended_error_info()
   6036 if samps_per_chan_read is not None:
-> 6037     raise DaqReadError(extended_error_info, error_code, samps_per_chan_read)
   6038 elif samps_per_chan_written is not None:
   6039     raise DaqWriteError(extended_error_info, error_code, samps_per_chan_written)
 
DaqReadError: Some or all of the samples requested have not yet been acquired.
To wait for the samples to become available use a longer read timeout or read later in your program. To make the samples available sooner, increase the sample rate. If your task uses a start trigger,  make sure that your start trigger is configured correctly. It is also possible that you configured the task for external timing, and no clock was supplied. If this is the case, supply an external clock.
 
Property: DAQmx_Read_RelativeTo
Corresponding Value: DAQmx_Val_CurrReadPos
Property: DAQmx_Read_Offset
Corresponding Value: 0
 
Task Name: _unnamedTask<6>
 
Status Code: -200284"
}
0 Kudos
Message 5 of 6
(350 Views)

I really don't know python, but your AI and AO config generally look pretty good.  I'd probably explicitly set the AO active_edge to RISING just to be sure.  There are 2 other minor problems however and then we'll get to the show-stopper.

 

1. With your counter task supplying the sample clock for AO and AI, you should start AO and AI tasks first so they're armed and ready and will be in sync when you start your counter task.

 

2. Your counter task needs to configure its timing, much like AO and AI.  I don't know the exact syntax under Python, but you'll want to specify IMPLICIT timing and I probably FINITE sampling with the same # samples SAMPLES_PER_CHANNEL

 

All that said, I think your overall big picture goal might be doomed if you're hoping to have independent simultaneous control of individual AO and AI channels.  There's only 1 timing engine available for any and all AO and similarly only 1 for any and all AI.  You have to deal with all your AO and AI channels *collectively*.   You can't just write new data to 1 AO channel while the others continue what they were doing, you'd have to write data to *all* of them.

    While theoretically possible to manage this process in a way that mostly seems like independent control (but with unavoidable latency due to buffers being written and transferred), it'd be a pretty tall order to get it working right.

 

But maybe I'm misunderstanding what you want.  Maybe you just need to operate discretely for bursts of finite samples, with plenty of user-involved setup time in between runs.  Something like *that* would be much more readily manageable.

 

 

-Kevin P

 

ALERT! LabVIEW's subscription-only policy coming to an end (finally!). Permanent license pricing remains WIP. Tread carefully.
0 Kudos
Message 6 of 6
(339 Views)