03-05-2008 12:48 PM
03-06-2008 12:41 PM
03-06-2008 03:46 PM
Hello GaryP,
If I understand you correctly you're looking to synchronously acquire and generate analog voltages using your PCI-6281 with NI-DAQmx in Python. If this is a case there is a C++ example that already does this--using it you can infer the Python equivalent. This example is for continuous synchronized acquisition and generation, but the basics of synchronizing the two tasks are the same if you change to finite acquisition. Unless you want to do finite retriggerable data acquisition in hardware then you shouldn't need to configure the pulse train task. The analog input and analog output sample clocks are divided down from the same timebase so in order to synchronize them you only need to make sure they start at the same time in order for them to be synchronized. In this example the analog output task is configured to start from the analog input start trigger. Therefore if you start the analog output task before the analog input task they will start at the same time because the analog output task will be started and waiting for the trigger from the analog input task. Then when you start the analog input task the two will start together and be synchronized.
In keeping with high level descriptions of what needs to be done I’ve copied the “Steps:” from the comments of this example as they should apply to any:
Steps:
1. Create analog input and output voltage channels for measurement and acquisition.
2. Set timing parameters for continuous generation and acquisition. The sample rate and number of samples are set to the same values for each task.
3. Configure start triggers that will synchronize both tasks by triggering the output task from the AI Start Trigger.
4. Create the signal to be generated by the output task.
5. Create an CNiDAQmxAnalogSingleChannelWriter and associate it with the output task by using the task's stream. Call CNiDAQmxAnalogSingleChannelWriter::WriteMultiSample to write the data.
6. Call CNiDAQmxTask::Start() on each task to start the acquisition and generation. Note: The output task must start before the input task because it is waiting on the input task for the start trigger.
7. Create an CNiDAQmxAnalogSingleChannelReader and associate it with the input task by using the task's stream. Use the CNiDAQmxAnalogSingleChannelReader::InstallEventHandler method to register the callback for the asynchronous read method. Call CNiDAQmxAnalogSingleChannelReader::ReadMultiSampleAsync to begin the read.
8. Inside the callback, read the data and display it.
9. Call CNiDAQmxAnalogSingleChannelReader::ReadMultiSampleAsync again inside the callback to perform another read.
10. Destroy the CNiDAQmxTask object to clean-up any resources associated with the task.
11. Handle any CNiDAQmxExceptions, if they occur.
<Continued Below...>
03-06-2008 03:47 PM
<Continued from above...>
If you’d like to view the C++ code for this example it installs with NI-DAQmx if you include support for VS2005 C++. If you’ve already installed this support the example should be located in the following path: C:\Documents and Settings\All Users\Documents\National Instruments\NI-DAQ\Examples\MStudioVC2005\Synchronization\Multi-Function\SyncAIAO_DigStart. If you don’t have these examples you can install them by modifying your installation of NI-DAQmx from the Windows Add/Remove programs utility.
I hope this helps get you started, and if I’ve misinterpreted what you’re trying to do please post back with more information about what you’re trying to do. Particularly it would be helpful to know:
1. Is this finite or continuous acquisition/generation? Either of these can be done with the above example with minimal changes; it is configured to be continuous as is.
2. If it is finite do you need it to be retriggerable? If you want to be able to retrigger this you’ll either need to generate a pulse train to use as the sample clock, or you can stop and restart the two tasks—the first option can be done in hardware (by configuring a retriggerable pulse generation task), the second is in software by stopping and restarting the task.
Have a good night!
03-11-2008 09:46 AM
03-12-2008 05:24 PM
Hello Gary,
The Dev1/ai/StartTrigger is an internally available channel on the PCI-6281 so you do not need to route it externally. Assuming you're using a DAQmx Trigger function call to configure the analog output (write) task to start on the "Dev1/ai/StartTrigger" this will be internally routed. Also, if this is what you're doing, if the analog output task is starting then that means the analog input task is also started.
This may be a silly question, but looking at your pseudo code I don’t see a DAQmx Read called anywhere. I also don't see a DAQmx Write, but since you're getting your output I know one must be there. Is it possible that you've omitted this step? It would fit the symptoms you're seeing.
If this is not the case then the issue may be the sample clock. How are you configuring the sample clock? If it is an external clock then are you sure that the input task is receiving it?
Cheers,
03-14-2008 01:05 PM
03-17-2008 06:55 PM
Hello Gary,
Here is how the sequence should go. If there are multiple items for one number the order of those calls doesn't matter. I.e. it doesn't matter which task you create first, but they both need to be created before you configure their timing.
1. Create read and write tasks.
2. Configure timing for read and write tasks.
3. Configure write task to start on the /Dev1/ai/StartTrigger.
6. Start write task.
7. Start read (ai) task. (This will start the write task was well).
8. Call the DAQmx Read and Write functions until all samples are done. This may be in a loop.
9. Clear the read and write tasks.
If you are following this sequence and you see that the write task has started and is working correctly then the read task must also have been started since it triggered the write task. You are correct that you need to call two DAQmx Start Task functions and the order is very important. In this setup you need to start the write task and then the read task. When you start the write task it then waits to receive its start trigger and since that trigger is the ai start trigger it needs to be started before the read task. If you reverse the order the read task will start, but the write task will never receive its start trigger. While the default behavior of the DAQmx Read is to start the task, that is not the preferred method and for purpose of synchronization doing it this way would just make things difficult if its even possible.
The three function calls you posted look like they have all the correct parameters so my primary concern is the order in which they are called. If you find that you're already using the order I posted above then it may be helpful if you can post some of your code, preferably the smallest section that can reproduce the issue you're seeing.
Have a great night!
03-18-2008 12:34 PM
03-19-2008 02:14 PM
Hi Gary,
I'm glad to hear you've got it working. As long as it’s doing what you want I think that it should be just fine. I did however notice a problem with my instructions in my last post. The write task needs to have its output buffered before you start the task. That means the correct pseudo code should read:
1. Create read and write tasks.
2. Configure timing for read and write tasks.
3. Configure write task to start on the /Dev1/ai/StartTrigger.
6. Call the DAQmx Write to buffer the output.
7. Start write task.
8. Start read (ai) task. (This will start the write task output as well).
9. Call the DAQmx Read and DAQmx Is Task Done VI (for the write) until all samples are done. This may be in a loop.
10. Clear the read and write tasks.
Sorry for the confusion, the original instruction list had this correctly, but I flipped it in the last post. Once again, if it is working the way you expect then you’re probably okay. It just may be a little bit harder to make sure the program is executing the way you think it is with your current setup.
Cheers,