01-09-2025 03:36 AM
Hi
I'm using a PXIe-8375 (slot1), PXIe-6396 (slot3) and a PXIe-6614 (slot4) in a PXIe-1071 Chassis. With the NI-DAQmx library (latest, v1.0.2) and python, I would like to read out up to 8 analog, 8 digital and 1 counter channel from the PXIe-6396 and up to 8 counter inputs from the PXIe-6614. The sample clock is generated by the PXIe-6396 and fed to the PXIe-6614 through the PXI_Trig0 line, which means I should be able to read out data with a max. sample clock of 14.29 MHz (max. ADC sample speed of PXIe-6396).
It all works reliably up to 5MHz while reading out 8 analoge channels, 8 digital inputs (one port), 1 counter (quadrature encoder) and 8 counter inputs (edge counting mode). I can see that all callback functions are called on-time, meaning there is plenty of time before the next read out occurs.
That means: With the above channel selection, I get 11 tasks/callbacks (1 AI, 1 Enc, 1 DI, 8 CI). All 11 callbacks are called and executed within 6 ms, I then need additional 6 ms to send out the raw data. With a read out speed of 50 Hz, that leaves 20 ms - 2 * 6 ms = 8 ms before the next callbacks will be called.
If I then switch to 10 MHz sample clock, not all callbacks are called/executed, not even late. The problem is with the CI callbacks. At 10 MHz, only 4 CI callbacks are called, at 14.29 MHz no CI callback is called. The other callbacks (AI, DI, Enc) are fine, I'm "just" missing some CI callbacks. I don't get any error messages. With the full channel selection, I should still get 11 tasks/callbacks, but only 7 are acutally called. These 7 are called and executed within 8 ms, so there should be enough time to call the remaining 4 CI callbacks.
It gets even more misterious when I select only part of the counter inputs on the PXI-6614 (at 10 MHz):
Before executing test no. 6 above, I had assumed that there are like two groups of channels that cannot be read out together at 10 MHz, but test no. 6disagrees with that theory.
Some other maybe helpful information:
- A single CI callback call at 10 MHz needs 0.98 ms to process.
- With full channel selection, all 11 tasks are started without error (task.start() is inside try/exception, I don't get an exeception).
Any help is greatly appreciated!
Stephan
01-10-2025 06:56 AM
Sorry, I'm no help with anything related to Python callbacks. Just wanted to give a little nudge for a small troubleshooting step.
Have you tried a lower callback rate? There's longstanding tribal knowledge around here that reading from DAQmx task buffers at ~10 Hz is a good sweet spot for a wide range of sample rates. With 11 distinct tasks and callbacks, you may want to dial back to somewhere in the 2-5 Hz range, at least for troubleshooting purposes.
Another thought: if all your tasks are sync'ed via shared sample clock, can you just have one actual callback function and then read data from all 11 tasks within that function? Again, at least as an experiment for troubleshooting purposes? (In case the main program architecture encapsulates tasks in a way that makes global-like access more difficult).
-Kevin P
01-13-2025 08:29 AM
Based on earlier discussions with Kevin Price, I am myself now controlling the callbacks rate in python as is:
for index_task, task in enumerate(all_tasks):
task.timing.samp_quant_samp_mode = nidaqmx.constants.AcquisitionType.CONTINUOUS
task.in_stream.input_buf_size = 20 * config_object.master_samp_clk # used for buffer size => this is sizing exactly the data buffer, here 20s, which is very exagerated, but not so big when working with 1MHz+1ADC cards
task.register_every_n_samples_acquired_into_buffer_event(config_object.master_samp_clk, functools.partial(callback_nidaq, index_task)) => registering here for an event every second (my real-time constraints are just graphical display, no pressure 😉 )
I guess you are using the register_every_.... API call to set 20ms callback occurrence, you can tune to Kevin's recommendations
When debugging, I was dumping task.in_stream.avail_samp_per_chan for all tasks from the callbacks. With high cpu loads, callbacks could be delayed a lot and it was proving it. But I would get errors at some point, which you do not get 😞
If you do not set task.in_stream.input_buf_size, you can dump it, it will tell you what nidaqmx has decided through its internal heuristics. That could eventually explain why you don't get any error (well, I am not very optimistic, I have observed on my cards that nidaqmx is not setting seconds of buffering, rather just a few callbacks call and it is probably even worse for very high rate cards)
Sorry if you already tried this first level of observability
01-13-2025 08:36 AM
Lowering the callback rate to 10 Hz results in this error:
nidaqmx.errors.DaqReadError: The application is not able to keep up with the hardware acquisition. Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples to read instead of reading all available samples might correct the problem.
So I assume the 50 Hz callback rate is needed.
I rewrote the code to read data from all tasks in one callback funtion, called by the master task. The behavior is the same, I cannot read all counter channels above 5 MHz sampling rate. However, I get a different error message:
nidaqmx.errors.DaqReadError: Onboard device memory overflow. Because of system and/or bus-bandwidth limitations, the driver could not read data from the device fast enough to keep up with the device throughput. Reduce your sample rate. If your data transfer method is interrupts, try using DMA or USB Bulk. You can also use a product with more onboard memory or reduce the number of programs your computer is executing concurrently.
I made sure that the transfer mechanics of all tasks is set to DMA. I'm not sure what is meant by "Onboard device memory", the internal buffer memory of the PXIe-6614 or the RAM of the readout computer?
Stephan
01-13-2025 08:46 AM
Yes, I do use the "register_every_", but I currently do not set the task.in_stream.input_buf_size, but I will try to play around with it to see if it helps.
Thanks for both your replys!
01-14-2025 03:51 AM - edited 01-14-2025 04:13 AM
If I do not set the buffer size manually, nidaqmx assigns 5x the buffer size it would actually need:
I'm not able to set a smaller buffer size then the auto-calculated one. I can only assign a bigger buffer size, without change in behavior. I've also tried to set the buffer size really big and then reduce the buffer readout rate, without change in behavior.
Concerning the readout computer:
But I think I have found the issue now:
I have seen that there is a newer card to control an NI chassis, the PXIe-8301, using thunderbolt with a speed of up to 2.3 GB/s. This I guess would for sure solve the issue with the connection between the chassis and the computer. However, I don't know if it would solve the issue of the PXIe-6614 using only 1 lane on the PCIe bus?
Like can the PXIe-6614 use 4 lanes? Otherwise it would not make sense to buy a PXIe-8301...
Stephan
01-14-2025 07:38 AM
I checked the dataspec from PXIe 6614 (attached) and it seems to imply that form factor is x1 only so this would be a bottleneck
==================================================================================
Big buffer and low readout rate is effectively the experiment that you had to perform. Not helping unfortunately.
What is weird is that you don't get:
- any error because you would not be able to absorb the 8 data streams from the card to the computer (so card onboard memory would not be freed)
- or any warning at config/start step indicating you that some data streams would be dropped because the PCIe link is not fast enough
You could probably check what is happening by dumping all "task.in_stream.avail_samp_per_chan" in 1 callback (I just rechecked this OK, I have 2 callbacks and I can dump all info on all tasks in any callback). You would see if some tasks are really alive.... even if they don't give you any callback.
Well, in theory, these counters should not be running otherwise you would get an error
01-14-2025 08:38 AM
I was looking at the specification of the PXIe-6614 as well and saw the x1, but the same entry exists in the PXIe-6396 specification sheet. And the PXIe-6396 is connected to PCIe 4 lanes and can run with 10 MHz and 8 channels at int32.
So it is either a bug in the PXIe-6396 specification sheet or the form factor is not the number of lanes but something else (maybe physical width of the card in no. of slots?)
============================================================
I've added a statement to print out the "task.in_stream.avail_samp_per_chan" in my callback. In my test script I have one callback function for all tasks. Before I read out any buffer, I get:
I would expect a bit more than 200'00 samples in each buffer. It looks like the PXIe-6614 cannot aqcuire more than 4 channels at 10 MHz.
If I run the test at 1 MHz sample rate, I get slightly more than 20'000 samples in each buffer, as expected.
01-14-2025 11:50 AM
To be honest, the 1x was surprising me a bit. I remember now we looked at the full 63xx product ecosystem and I rechecked that PCIe 6376 is 4x (3.5MS/s/ch and 16bit only resolution). So a 6386 or 6396 should be the same or more. Yes, PXIe data seems to be wrong
========================================================================
Have you dumped several times to see the evolution ? BTW, the value keeps increasing if you do not read the data (but then it is good to size the buffer big enough...) and you still get the callbacks.
But even without this evolution, it really looks like some CI tasks are just dropped without warning or error. That is beyond my knowledge 😞
01-15-2025 01:28 AM
Yes, I have tried to dump it several times. The "working" CI tasks count up normally until the buffer is full, whereas the "non-working" CI tasks do not count up.
Example:
Looks to me as if the first 4 tasks acquire for ~ 1000 samples and then just die without error message (or the error message is ignored by the nidaqmx python lib, who knows...).
I've tried to increase the buffer size to a ridiculous size of 500 million samples per channel, with the same behavior. I do get an allocation error when trying to set a buffer size of 1 billion samples per channel, so my assumption is that there would be enough onboard memory to keep the samples.
I've reached out to our NI contact to clarify where the bottleneck is, the PXIe/PCIe-8375 or the PXIe-6614. I will also try to update the nidaqmx driver, but I don't expect a change in behavior.
Thanks a lot for your help!!