11-16-2009 12:39 PM
I am having a problem getting a USB-DAQ to stop while running multiple tasks.
If I set up an analog output stream AND and analog input stream to run concurrently, I have problems:
When I attempt to stop one of these tasks, using <task>.stop, I am having issues;
1) If I stop the analog input stream first, the function will wait a very long time before returning, as if the buffer needs to finish first.
2) If I stop the analog output stream first, the input stream will become null? This causes further problems.
I was not able to find an example application of using a USB-DAQ for concurrent analog input and ouput utilizing a digital input trigger to start both tasks simultaneously.
I relaize that this is a very specialized application of the DAQ, but can the USB version do this? If so, are there examples, or what could I be doing wrong.
Everything works fine except for the ability to stop the process,
Henry.
11-16-2009 05:11 PM
Hi Henry,
What device (e.g. USB-6229, USB-9211, USB-6008, SCXI-1600, DAQPad-6020, etc.) and driver (NI-DAQmx, NI-DAQmx Base, Traditional NI-DAQ) are you using? Could you describe what you mean by "the input stream will become null?" Are you getting an error message? If so, please post the actual text, including the error code.
Brad
11-16-2009 06:44 PM
Sorry to be so vague, I was unsure wheter a USB-DAQ could perform simultaneous output stream and concurrent input stream when both tasks are triggered at the exact same time using a single digital trigger.
I am using a USB-6259 and a USB-6221-OEM. When I issue the command <task_input>.stop then look at the value of <task_output>, it is null:
if (task_input != null)
{
try
{
task_input.Stop();
}
catch (Exception x)
{
task_input.Dispose();
task_input = null;
....
}
task_input.Dispose();
task_input = null;
}
if (task_output != null)
{
.......
If a breakpoint is set at the beginning of this code, task_output is not null. After setting task_input to null, task_output is forced null at the driver level.
I am using DAQ-MX 9.0 .NET in C#.
Henry.
11-16-2009
07:52 PM
- last edited on
08-06-2025
11:23 AM
by
Content Cleaner
Hi Henry,
There is a NI-DAQmx C# AI-AO synchronization example that should be a good starting point: Synchronization/Multi-Function/SyncAIAO_DigStart. (The NI-DAQmx C# example folder location is explained in Where Can I Find NI-DAQmx Examples?)
Issue #1 sounds like you are synchronously reading a large number of samples and the call to input_task.Stop() is waiting to acquire input_task's mutex. You should be able to prevent reads from blocking by using inputTask.Stream.AvailableSamplesPerChannel to find out how many samples are available to read, or by performing asynchronous reads. The SyncAIAO_DigStart example uses asynchronous reads.
Issue #2 is very strange. Stopping one task should not directly affect another in this way. Seeing more of your code might help, but please try running the example and comparing your code to it first.
Brad
11-19-2009 05:45 PM
This is a good example, that I was unaware of. My problem may be that I have a callback for both the Input stream and Output stream.
Perhaps, this is the issue? I will at least attempt to modify the example provided. If this works I will post a resolved status.
If I am still having issues, I will provide more code. Thank you for your help.
H.
11-30-2009 03:54 PM
Brad,
I tried the synchronization example you recommended; Synchronization/Multi-Function/SyncAIAO_DigStart. This example has a few problems.
1. The digital trigger does not work. It always 'just starts' with or without a digital input trigger. Try it yourself.
2. I need to simultaneously start an input stream as-well-as an output stream:
outputTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/Dev1/PFI0", triggerEdge);
I need to add this function, which I think breaks the logic in both your example and my previously error-prone code:
inputTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/Dev1/PFI0", triggerEdge);
After adding this code to the NI example, the trigger works, but I get timeout and other types of unpredictable errors, like .stop taking a long time.
Still searching for a solution,
Henry.
12-01-2009
07:31 PM
- last edited on
08-06-2025
11:24 AM
by
Content Cleaner
Hi Henry,
I agree, the example name is misleading. Only the AO task uses an external digital start trigger, and that trigger comes from the AI task (and is really internal to the device). Your changes to make both tasks use an external start trigger are correct. It may also be helpful to keep using ai/StartTrigger as the AO start trigger source, because this ensures that an early trigger doesn't start one task and not the other.
I tried the example program with your changes, using a USB-6229 and NI-DAQmx 9.0.2. I connected P0.0 to PFI0, and used the "Digital I/O" tab in the device test panel in MAX to produce a rising edge (click "All Output", "Start", "All High"). If the device detects an edge, it starts generating and acquiring data. If it doesn't detect an edge, it pops up a dialog about a timeout error, which is expected. The stop button doesn't hang the program or take a long time to respond.
The timeout errors could be a problem with your trigger signal. Does it always produce an edge when you expect it to? If you use the "Count I/O" tab in the device test panel in MAX to perform edge counting on PFI0, do you get the expected number of counts? Does it meet the device's "Input high voltage" and "Input low voltage" specifications?
Task.Stop() still shouldn't take a long time. What versions of Windows and Visual Studio are you using (including service packs)? Do you still see this behavior if you disconnect all signals from your device, connect P0.0 to PFI0, and use P0.0 to generate the trigger, as I described above?
Brad
12-02-2009 01:28 PM
Brad, thank you very much for your assistance. I am attaching the source code for a demonstration of the problem I am having. In this example, I recommend placing a breakpoint on line #932 of the file, MainForm.cs. Run the code and press the Stop button after a few seconds of triggered acquisition. Here, you will see that the .Stop() command takes an incredibly long time to complete, precisely as I have described. I am using Windows Vista 64-bit, Visual Studio 2008 V 9.0.30729.1 SP, .NET 3.5 SP1. It may be important to note that I have more than 4 gigs of RAM. This is an important factor because Vista64 is notorious for using memory pointers beyond the the 32-bit boundary in systems with 2+ gigs of RAM. We have noticed almost every Vista64 hardware driver we have exhibits errors because of this. I can elaborate more on a solution to this if needed, but for now, just run the example I am attaching and you should clearly see the driver-level bug.
Henry.
12-03-2009 11:23 PM
Hi Henry,
Thanks, that helps a lot. I tried your version of the code on Windows 7 64-bit with 4 GB of RAM (enough to get the BIOS to map physical RAM above 0x100000000), and I can reproduce the hang you're seeing. I'm not an expert in Measurement Studio or .NET, but here's what seems to be going on, and it's not due to USB or 64-bit:
Your reads take a long time because you changed the number of samples to read from 25 to 1000, but the sample rate is still 25 samples/sec. If your device gets a start trigger immediately, the read takes 40 seconds. If not, it takes longer.
Also, you're setting the read timeout to -1. If you look in the class library help that gets installed into Visual Studio, the description of DaqStream.Timeout says "If you set this property to -1 (or Infinite), read or write operations never time out."
With a read timeout of -1, any of these things will make an ordinary synchronous read complete:
However, you're using asynchronous reads. Aren't they different? Well, the interesting part is that asynchronous reads in the DAQmx .NET API still hold the task mutex for the duration of the read. When you call BeginReadMultiSample(), the DAQmx .NET API queues a work item that performs an ordinary synchronous read. While the synchronous read is in progress, any additional calls into inputTask (other than inputTask.Control(TaskAction.Abort), which is handled specially) block until the read completes. As far as I can tell, the DAQmx .NET API doesn't support canceling a read without aborting the task.
If you add a call to inputTask.Control(TaskAction.Abort) on line #932, then DAQmx aborts the input task when you click the Stop button. This releases any resources the input task had reserved, and also makes the worker thread's synchronous read throw a "task aborted" DaqException, which is rethrown if you call EndReadMultiSample() later. After the task has been aborted, calling inputTask.Stop() doesn't hang, and Stop() calls the read callback.
Brad
12-04-2009 01:43 PM
Brad, thanks again. It appears the device cannot do what we need. In using your latest recommendations, all of our critical data is lost. Perhaps I am still using the device incorrectly, but I can confirm that calling .Stop() after a .Control(TaskAction.Abort) renders the callback function useless. This is a much worse case scenario than just waiting an annoyingly long time for the stop function to return. The fact that calling .Stop() actually locks up the host application, until the buffer fills is unacceptable. The solutions you provide forces us to lose all of our data. In short, we need a solution where we can abort an acquisition in brief amount of time and not lose any data.
--If that is possible,
Henry.