Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

DMA problem reading more than 1 channel (PCI6602)

I am currently trying to get a 3-channel continuous encoder position-measurment running.
1 channel works ok, but as soon as I add 1 more, data for channel 2 is incomplete - looks like data loss.
attached is an example 2chnnl measurment, signal fed to chnnl1 and chnnl2 is the same.
chnnl 1 is ok, as the encoder is rotating at constant speed.
programming is LW-CVI, derived from AngularPosition-Buff-Cont.c (sample program from CVI).

the measurment setup is as follows:

    for (ch = 0; ch < Nch; ch++)
    {
        Fmt(TaskName[ch], "Task%d", ch);
        DAQmxCreateTask(TaskName[ch],&taskHandle[ch]);
        Fmt(Ctr, "%s%d", CtrBase, ch);
        Fmt(chName, "ch%d", ch);
        // ein/vierfachauswertung (X1/X4), ticks zählen
        DAQmxCreateCIAngEncoderChan (taskHandle[ch], Ctr, chName, DecodingType,1, 0.0, DAQmx_Val_AHighBHigh, Units, pprev, 0.0, "");
        // data transfer explizit auf DMA 16.07.07
        DAQmxSetChanAttribute (taskHandle[ch], chName, DAQmx_CI_DataXferMech, DAQmx_Val_DMA, NCMAX / Nch);   
        DAQmxCfgSampClkTiming (taskHandle[ch], SampleSource, MAXRATE, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, Nsamp);
    }

I also tried without the line 'DAQmxSetChanAttribute (taskHandle[ch], chName, DAQmx_CI_DataXferMech,DAQmx_Val_DMA, NCMAX / Nch)'
- result is just the same.
so, I suppose, DMA is just working for chnnl1, regardless, if explicitly set, or not.
I'm using a PCI 6602 card (which is supposed to do DMA on up to 3 channels), DAQMx 8.3, if that matters.

anyone has a clue what to try next ?



--
Once the game is over, the king and the pawn go back into the same box.
0 Kudos
Message 1 of 7
(5,181 Views)
Hello Josswern,

That's right, the 6602 has 3 DMA channels.
Could you attach a working CVI project to reproduce this.
Maybe I can test it and find out something.

Regards,
WolfgangZ

0 Kudos
Message 2 of 7
(5,166 Views)
Hello Wolfgang,
please find attached the beforementioned project - executable omitted to save bandwidth.
and thanks for taking the time to look into this!

Werner
--
Once the game is over, the king and the pawn go back into the same box.
0 Kudos
Message 3 of 7
(5,160 Views)
Hello Werner,

Realy Strange. At the moment I can not see the reason for the problem.
If you use counter 0 and 1 and disconect counter 0. What happens? Are the values of counter 1 correct?
What happens if you use counter 0 and 2 without using counter 1?

Regards,
Wolfgang

0 Kudos
Message 4 of 7
(5,143 Views)
Hello Wolfgang,
this problem turns out to become even more strange:
I have meanwhile transferred the hardware+software to an old PC where I have a full cvi development installation.
daqmx/max versions are exactly same as before (MAX 4.1.0.3001, NI-DAQMx 8.3.0f0), as is OS (win XP SP2).
now the results are much better (see attached pic), but still not ok.
count results from chnnl2 are still off by ~40 ticks after 20000 samples, where I would expect 1 or 2 max., as the signal ist exactly the same on each chnnl.
see also attached data file.
of course, your proposal to check chnnl1,2 individually doesn't make much sense anymore now, as it seems to be quite linear in each case.
perhaps I should try to go back to the original PC with the beforementioned, really weird results to check this again.
otherwise, I could try to build a similar application using traditional NI-DAQ driver, maybe that will do better...


--
Once the game is over, the king and the pawn go back into the same box.
Download All
0 Kudos
Message 5 of 7
(5,117 Views)
Hello Werner,

The difference of ~ 40 ticks on your old PC is explainable and I can reproduce this on my PC, too.
You have two count registers which will be incremented by a pulse of the source connector at the same time, but you can not read out the count register at the same time.
Your are reading the first counter with DAQmxReadCounterF64 and than the second counter.
Between the first and the secound reading elapse some few time. In this time the second count register will be incremented by some ticks.
If you want to avoid this you should do a buffered measurement. There is an example in Example Finder which is named "Cnt-Buf-Cont-ExtClk.prj".
I did the test with 6602 in LabVIEW (it was faster to program) and now I got exactly the same results for both counters. For the external clock I took the same signal which I used for the source connector. If you read out the count register in buffered mode you are getting the results in array.

Regards
WolfgangZ
0 Kudos
Message 6 of 7
(5,093 Views)
Hello Wolfgang,
thanks again for your efforts, and for the hint(s).
However, I still can't figure out what's the basic difference between my program and the mentioned example (Cnt-Buf-Cont-ExtClk.prj) -
basically this one does just the same as my approach, namely read data from the counter
(especially, I can't see anything different related to simultaneous, buffered acquisition of several channels):

    if( event==EVENT_TIMER_TICK && gTaskHandle ) {
        DAQmxErrChk (DAQmxReadCounterU32(gTaskHandle,gSamplesToRead,10.0,gData,gSamplesToRead,&numRead,0));
        if( numRead>0 )
            PopulateMeasurementListBox(gData,numRead);
    }

- the only difference I can see is that:

1. DAQmxReadCounterU32 ist used insted of DAQmxReadCounterF64

2. read operation is done in a timer callback whereas my program uses a loop, where the total number of acquired samples is checked:

    while ( sum < SumNsamp ) {
        DAQmxErrChk (DAQmxReadCounterF64 (taskHandle[0], Nsamp, (double) Timeout, data0,
                                          NCMAX, &read, 0));
        sum = sum + read;
        if (Nch > 1) {
            DAQmxErrChk (DAQmxReadCounterF64 (taskHandle[1], Nsamp, (double) Timeout, data1,
                                              NCMAX, &read, 0));
            sum = sum + read;
        }
        if (Nch > 2) {
            DAQmxErrChk (DAQmxReadCounterF64 (taskHandle[2], Nsamp, (double) Timeout, data2,
                                              NCMAX, &read, 0));
            sum = sum + read;
        }
    }

of course, I use sequential calls to DAQmxReadCounterF64(), as I have more than one channel - DAQmx does not allow to create more than 1 channel / task,
so I suppose, more than 1 channels in Cnt-Buf-Cont-ExtClk.prj (which is 1 channel only) would have to be handeled just the same way, or am I wrong with this,
and there is another way to simultaneously read data from several tasks ?

best regards.
Werner

--
Once the game is over, the king and the pawn go back into the same box.
0 Kudos
Message 7 of 7
(5,064 Views)