Hello,
I’m writing a small application based around the NI DAQCard 6062E, a pcmcia card.
The application continually writes samples to the card’s two analog output channels. A counter is also used for a periodic pulse every 20 ms.
This application works fine when only one Analog output channel is written to. When I use two analog output channels, the card initially works fine, but then swaps the channels at some point. It can swap many times during the simulation, but these are normally spaced apart by several minutes. By this it is meant that the card outputs what was supposed to be on Channel 1 on Channel 0 and vice versa. This occurs regardless of the output SAMPLE rate, so I do not think it is a problem with the performance of my hardware. It appears to either be in my code or in the card itself.
The development is being done using C# and VS.NET without measurement studio and NIDAQmx. The approach taken is to use a buffer. The buffer is large (anywhere from 5000 to 100000 samples has been tried and works. A software timer is used in uiMainForm to update the buffer. The buffer’s available space is filled with as may whole frames each time the time it is called. (A frame is basically a double array with 288 or 576 samples in it).
The development environment I’m using includes:
MS Visual Studio 2003, Professional Edition
see the attached nireport.txt for information about the NI products I’m using.
I’ve attached two souce code files for your review.
The “WaveformSimulator” class contains all calls to the NIDAQmx applications. “uiMainForm.cs” is the generic form used for testing. Here are the highlights:
1. The constant OUTPUT_SAMPLE_RATE, and OUTPUT_BUFFER_SAMPLE_SIZE_PER_CHANNEL are defined at the top of the WaveformSimulator file. These are used in InitializeTask. The OUTPUT_SAMPLE_RATE is set to 14400 samples per second, but if it is changed to 1440, the results are the same.
2. The InitializeTask function at line 133 handles the setup of the NI-DAQ Card. The card is initialized once before starting. Note that the circular buffer is filled before starting the task. This is done by calling FillBufferWithNextFramesInSimulation, and then waiting for the card to catch up with a while statement on line 168.
3. The simulation is started by calling StartSimulation on line 197.
4. The application “uiMainForm.cs” file contains a software timer that calls FillBufferWithNextFramesInSimulation based on the timer. Timer values from 1 ms to 100 ms have been tried. The calling of the FillBufferWithNextFramesInSimulation can be seen on line 311 of uiMainForm.cs.
5. The operation of the FillBufferWithNextFramesInSimulation is the critical function in the class. Here is what happens within it.
a. On line 233, the number of bufferSamplesFreePerChannel is determined from the TASK.
b. The subroutine attempts to write as many whole “frames” to the channel as it can.
i. A Frame is contained in “theStep.OutputBuffer” a double[] array. The frame size is normally a multiple of 288. The assignment of a local variable to this array is done in line 262.
ii. The value output to the card is a variable named symbolValues. This array is created on line 262, and the values are set in subsequent lines. Line 270 shows that index 0 (e.g. Analog Channel 0) is always set with the values from the basebandOutput. Channel 1 always has a value of 5 V for the first 2 samples, and 0 V for the rest of the samples
iii. The samples are written to the buffer in line 277. Each time a sample is written, new memory is allocated. I have attempted this both inside the “for i=0…) loop and outside of it. The results are exactly the same.
iv. I have also tried this with both the WriteMultiSample and the BeginWriteMultiSample methods. The results are the exact same.
I have looked extensively for a NI example that shows updating the buffer with software control and have not found one that uses a mult-channel buffer. All the examples define the buffer before hand and use regeneration, which will not work for this application.
Again, the application seems to work very well, except that it swaps Analog Channels on me. I suspect this happens when the driver copies the code from my buffer to the Card’s buffer, but that seems like just me pointing fingers at NI. Of course, I have no way to debug what happens in your driver, so I need your help to resolve this. An example that uses a circular buffer with multiple analog output channels that does not use regeneration would be welcome as a start. Anyway, I’d be really happy if you can tell me anything I can do to resolve this issue on my end.
Thanks, and have a great day!
-Dennis Arce