Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

PCIe-653x : Data missing

I use PCIe-6535 and 37 to acquire some data at 400 Kb/s.

I use an external clock (PFI5) and a data_valid signal (PFI3) to enable the acquisition.

Data is received in packet of about 800 Bytes and each packet is sent every N ms.

 

Here is the code to create the task:

 

    DAQmxCreateTask("", &myTask_m);
    DAQmxCreateDIChan(myTask_m, "Dev2/port0/line0:7", "", DAQmx_Val_ChanForAllLines);
    DAQmxCfgBurstHandshakingTimingImportClock(myTask_m, DAQmx_Val_ContSamps, 4096, 400000, "/Dev2/PFI5", DAQmx_Val_Falling, DAQmx_Val_Low, DAQmx_Val_ActiveHigh);
    DAQmxRegisterEveryNSamplesEvent(myTask_m, DAQmx_Val_Acquired_Into_Buffer, 4096, 0, DiEveryNCallback_g, NULL);
    DAQmxRegisterDoneEvent(myTask_m, 0, DoneCallback_g, NULL);

    DAQmxSetDigLvlPauseTrigSrc(myTask_m, "/Dev2/PFI3");
    DAQmxSetPauseTrigType(myTask_m, DAQmx_Val_DigLvl);

    DAQmxStartTask(myTask_m);

 

Here is the code to get data in the callback:

 

   DAQmxReadDigitalU8(taskHandle_i, 4096, READ_DIGITAL_LINES_TIMEOUT_S, DAQmx_Val_GroupByScanNumber, data_l, 4096, &read_l, NULL);

 

So, when N is less than 300 ms, some data are losses.

I have tried to change some parameters (buffer length...) but nothing works.

 

What's wrong with this card/code ?

0 Kudos
Message 1 of 9
(4,687 Views)

Hey lolo3131,

 

I see that you are setting up a timing type of Burst Handshaking, but I was curious if you are actually doing any handshaking? If not, then I would recommend that you check out the example program called ContReadDigChan-PipeSampClkwHshk.c. This example uses the Pipelined Sample Clock timing type, and in the example you can remove the output signals if you are not actually sending anything to your DUT. You can find this C example in the following directory on your machine:

C:\Documents and Settings\All Users\Documents\National Instruments\NI-DAQ\Examples\DAQmx ANSI C\Digital\Read Values\Cont Read Dig Chan-Pipe Samp Clk w Hshk

 

You can find all the digital examples in the following directory:

C:\Documents and Settings\All Users\Documents\National Instruments\NI-DAQ\Examples\DAQmx ANSI C\Digital

which includes some handshaking examples, and other acquisition examples.

 

Another thing I noticed about the code you posted is that you are not doing any kind of error handling, that I can see. In the shipping examples, that should get installed when you install your driver, you will see how to properly implement error handling in your code so that if you are getting an error, you will know.

 

Finally, you mention that you have a pause trigger coming with your data packets, and when that pause trigger is coming in quickly that you are missing expected data. If you have 800 samples in each packet, what data is not getting acquired, is it the first x # of samples out of that 800 or is it the last x # of samples? This will give some insight as to whether the board is not acquiring when the pause is deasserted, or if the acquisition is stopping too soon. Also, I'm going to assume that the N value of time between each packet is changing, but if it is not, then one option you have is that you could just acquire all data from a start trigger, because if you know that N is going to be the same, then in software you can just throw away that data. So this would just be a continuous acquisition with some software processing of the data after it has been acquired. Just something else you can consider if we can't figure out what is going on with the pause trigger. But my recommendation is to check out the Pipelined Sample Clock mode, acquisition with a Pause Trigger, as I think that will give you the behavior you are looking for if you pause trigger is coming in too fast for the Burst Handshaking mode. Try this out and let us know how things go. Thanks, and have a great day.

 

Regards,

DJ L.

0 Kudos
Message 2 of 9
(4,676 Views)

Thank you for your help.

 

With "DAQmxCfgPipelinedSampClkTiming" function, I had a error message from the card (Buffer overflow due to my processing time)

I have fixed my code and it works now.

 

Do you  know why I haven't the error message with the "DAQmxCfgBurstHandshakingTimingImportClock" function ?

In fact, I don't understand very well when I must use DAQmxCfgPipelinedSampClkTiming or DAQmxCfgBurstHandshakingTimingImportClock or ...

 

So, I would like that the pause trigger works on (Rising or Falling) Edge and not on (Low or High) State.

How can I do that ? (Because if the task starts during a packet, the data is unusable)

 

NB: I have delete error handling in the posted message.

 

Best Regards,

Laurent.

0 Kudos
Message 3 of 9
(4,656 Views)

Hey Laurent,

 

First with the buffer overflow error, you were probably doing something serially (like processing your data) while the data was coming into the device, and you were not getting the samples off of the board into system memory fast enough, and the board was still acquiring data. Therefore the buffer overflowed. One way to handle this is to acquire the data into one thread and then create another thread to process the data once you have it in memory.

 

For the question about why you don't get the overflow error message with the handshaking function, what is the difference in how many samples you are acquiring each time you call the read function? Also, check out the following link for help in Choosing a Sample Timing Type for Your Application.

 

For you question on configuring the Pause Trigger, check out the Trigger and Event Summary in the NI 6535/36/37 Help. The Supported Trigger Types for the Pause Trigger are Digital Level and Digital Pattern (pattern match trigger). Both of these are really the low/high state pause/unpause. So if you don't want to actually want to start acquiring until an edge trigger, I would recommend setting up a Start Trigger (for your Rising/Falling trigger), and also a Pause Trigger, for when after you start on the edge of the start trigger, from then on your pause trigger will only acquire when you want it to.

 

Let us know if you have any further questions or concerns. Thanks, and have a great day.

 

Regards,

DJ L.

0 Kudos
Message 4 of 9
(4,646 Views)

Ok, I tried to configure a Start Trigger with "DAQmxCfgDigEdgeStartTrig" function but an error message says that the PFI3 source trigger is used by the Pause Trigger.

In my application, I have only one signal for Start and Pause Trigger. How can I do ?

Must I connect PFI3 and PFI2 to my data_valid signal ?

 

Best regards,

Laurent.

0 Kudos
Message 5 of 9
(4,630 Views)

Hey Laurent,

 

Yes, if possible, connect your Pause Trigger to another PFI line. Let me know if this works for you. Thanks.

 

Regards,

DJ L.

0 Kudos
Message 6 of 9
(4,623 Views)

Hey Laurent,

 

Another option that you have to connect your one signal coming into PFI2, and to route that to PFI3 is you can try and use the "DAQmxConnectTerms" function. This should save you some time in actually physically wiring up the signal to 2 places. Sorry I didn't mention this earlier, but this should also work for you. Please let me know how things are going. Thanks, and have a great day.

 

Regards,

DJ L.

0 Kudos
Message 7 of 9
(4,595 Views)

Thank you for this tip. That works perfectly now. Here is my code :

 

    DAQmxErrChk(DAQmxCreateTask("My Task", &TaskHandle_m));
    DAQmxErrChk(DAQmxCreateDIChan(TaskHandle_m, "Dev2/port0/line0:7", , DAQmx_Val_ChanForAllLines));
    DAQmxErrChk(DAQmxCfgPipelinedSampClkTiming(TaskHandle_m, "/Dev2/PFI5", 400000, DAQmx_Val_Falling, DAQmx_Val_ContSamps, 4096));


    DAQmxErrChk(DAQmxRegisterEveryNSamplesEvent(TaskHandle_m, DAQmx_Val_Acquired_Into_Buffer, 4096, 0, EveryNCallback_g, NULL));
    DAQmxErrChk(DAQmxRegisterDoneEvent(TaskHandle_m, 0, DoneCallback_g, NULL));

 

    DAQmxErrChk(DAQmxCfgDigEdgeStartTrig(TaskHandle_m, "/Dev2/PFI2", DAQmx_Val_Rising));
    DAQmxErrChk(DAQmxSetDigLvlPauseTrigSrc(TaskHandle_m, "/Dev2/PFI3"));
    DAQmxErrChk(DAQmxSetDigLvlPauseTrigWhen(TaskHandle_m, DAQmx_Val_Low));
    DAQmxErrChk(DAQmxSetPauseTrigType(TaskHandle_m, DAQmx_Val_DigLvl));


    DAQmxErrChk(DAQmxSetReadOverWrite(TaskHandle_m, DAQmx_Val_DoNotOverwriteUnreadSamps));


    DAQmxErrChk(DAQmxConnectTerms("/Dev2/PFI3", "/Dev2/PFI2", DAQmx_Val_DoNotInvertPolarity));

    DAQmxErrChk(DAQmxStartTask(TaskHandle_m));

 

Are you OK with that ?

 

Best Regards,

Laurent.

0 Kudos
Message 8 of 9
(4,574 Views)

Hey Laurent,

 

If it is working for you, then I am fine with that ; - ) If you run into any issues let us know. Thanks.

 

Regards,

DJ L.

0 Kudos
Message 9 of 9
(4,568 Views)