LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

everynsample event doesn't fire correctly.

I'm using Visual c++ 7.0 write a program to acquire analog data from PCI 6255. I 'm using DAQmx 8.3.

Application:

1. A DC motor controled by DIO of PCI 6255. Port0 line1 and line2, 0 0 stop, 0 1 move forward, 1 0 move backward

2. An encoder is connected to PFI0 of PCI 6255 as external clock for A/D samples.

3. Set PCI 6255 do A/D using external clock ,MAX 10,000 samples per second, each sample contains AI0~AI20

4. Register every 2 samples per channel event to read data. I have to use every 2 samples (2 external pulse from encoder to sync a PCI 6533 DIO)


Flow of program:

All this functions are in one separated thread.

1. Start motor, output from DIO

2. Start Analog voltage acquisition, when motor is moving

3. Stop acquisition and stop motor when reach specified distance

4. Send a message to main window, to display data

Problem:

1. When motor move samll distance, it works well. but when move long distance or and more channels to each sample, it seems event is not fired every 2 samples. it is fired only a few times in the whole movement.

2. I checked signal from encoder, it is about 4.5~5.0 V, so it's not external clock signal problem.

3. I tried to override default input buffer, but it doesn't work.



Please see attachment for my source code. I have worked 2 days and haven't made any progress. I will appreciate any suggestions and help.



Laurence
0 Kudos
Message 1 of 4
(3,249 Views)
Hi Laurence,

Thank you for being decripting on your explanation. Let me paste the portion of the code I looked at:
.
.
.
DAQmxCfgSampClkTiming(taskHandle,"/Dev2/PFI0", 10000.0,DAQmx_Val_Falling,DAQmx_Val_ContSamps,2));
.
.
.
DAQmxRegisterEveryNSamplesEvent(taskHandle,DAQmx_Val_Acquired_Into_Buffer,2,0,ADEveryNCallback,NULL));
.
.
.

From the C reference help we see that the prototype is:

DAQmxCfgSampClkTiming (TaskHandle taskHandle, const char source[], float64 rate, int32 activeEdge, int32 sampleMode, uInt64 sampsPerChanToAcquire);

DAQmxRegisterEveryNSamplesEvent (TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, uInt32 options, DAQmxEveryNSamplesEventCallbackPtr callbackFunction, void *callbackData);


When you configure the timing, there will be a buffer allocation done automatically (see Knowledge Base), in your case 1k. You can change this using Get/Set/Reset Buf_Input_BufSize.

The key problem in your case is the event you are registering. There is an event (IRQ) fired every 200ns (2/10k or depending on your external clock) which is probably too fast for OS software.

To solve this, I would suggest to acquire N samples where N is about 1/10 of your sample clock (or more).  This will help the OS process every Event. Then in your callback you can handle the array to process more data while the card is acquiring the next batch.

Hope this helps,
Gerardo O.
RF SW Engineering R&D
National Instruments
0 Kudos
Message 2 of 4
(3,223 Views)
Hello Gerardo,

Thank you very much for your help.

I found the problem was external clock signal was noisy. In this situation, when one A/D conversion is not finished, another A/D conversion may start. Unfortunately, DAQmxErrChk can not handle this type of error, so the program keep running, but it blocked the reading and event firing correctly. After counting the sample clock (followed Jarrod suggestion), I noticed the A/D card didn't receive correct sample clock at all. I tried to create a task in MAX and run it, it reported this error , after added a filter to the external clock. Evrry thing works fine.

The noise was transient peaks, so I didn't notice it when I checked signal before. It is come from motor.



Laurence
0 Kudos
Message 3 of 4
(3,205 Views)
Hi Laurence,

Thank you for posting the solution and the great technique to debug it which is using the DAQ assistant in MAX to see how the task behave before coding it.
Best regards,
Gerardo O.
RF SW Engineering R&D
National Instruments
0 Kudos
Message 4 of 4
(3,198 Views)