Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Number of sample and sampling rate

Solved!
Go to solution
Highlighted

Hello,

 

I am using a PCI-6251 connected to BNC-2110, to read a QPD data. I used continuous samples configuration, set the sampling rate of the DAQmx to 150 kHz, recorded the sample for about 5 s, and saved the data to a text file. I also have adjusted such that the while loop will read 1500 samples every 10 ms, expecting it to read 150 k data for every 1 s.

 

Using this configuration, I expected to get around 750 k samples, but instead I got around 1.5 M samples. The ms timer value I used as a time reference I saved in the txt file is also messed up.

 

So, my expectation is:

 

row data                          ms timer value

1                                              0

...

1501                                      +10                                       

3001                                      +20

4501                                      +30

6001                                      +40

....

748501                                 +5000

 

What I am getting:

 

row data                          ms timer value

1                                              0

...

1501                                      +10                                       

3001                                       +0

4501                                      +30

6001                                      +40

...

748501                                  +30

750001                                  +40

....

14748501                             +5000

 

Could someone explain what's happened here? Is there something wrong with my thinking or my VI? How can I collect the data as expected (150 kHz sampling rate for 5 s gives 750 k samples)? Attached are the VI (LabVIEW 2016) and the screenshot of the VI.

 

Thank you very much.

 

-Jane

0 Kudos
Message 1 of 16
(543 Views)

Hi Jane,

 

You seem to be splitting the DAQmx task at the output of the Start Task VI, then doing different things with each branch.  As far as I know, this is not a good idea.  Even though LV wires are "by value", in this case you effectively have two references to the same task.  Both instances of setting the offset before the while loop are applied to the same task and there is no way of telling which one will execute first as there is not data flow between them.  You then read the same task twice within the loop, again with no way of knowing in which order these reads take place.

 

I'll have a look your VI and try and come up with some more concrete suggestions a little later today.

 

Andy

Message 2 of 16
(511 Views)
Solution
Accepted by topic author JCArifin

I can't open your VI because I still only have LV2015.  However, I've put together a snippet which hopefully gives you an idea of how to proceed.

DAQmx Acquisition.png

There's no need for any timer in the producer loop.  The DAQmx Read block will wait until the buffer contains enough samples as long as the timeout is not exceeded.  You can extract the data for writing to file from the waveform in the consumer loop, leaving the producer loop to get on with the acquisition.  If you want to be able to stop before the specified number of acquisitions is complete, add the output from the stop button to the OR in the producer loop.

 

Let me know if you have any questions about this.

 

Andy

0 Kudos
Message 3 of 16
(501 Views)

And keep in mind that not all samplerates are supported, it's a good idea to read the actual samplerate property after the configuration.

Greetings from Germany
Henrik

LV since v3.1

“ground” is a convenient fantasy

'˙˙˙˙uıɐƃɐ lɐıp puɐ °06 ǝuoɥd ɹnoʎ uɹnʇ ǝsɐǝld 'ʎɹɐuıƃɐɯı sı pǝlɐıp ǝʌɐɥ noʎ ɹǝqɯnu ǝɥʇ'


0 Kudos
Message 4 of 16
(489 Views)
Solution
Accepted by topic author JCArifin

Can only look at the screenshot now.

 

I think I understand what you *intended* to do by splitting your task ref and operating on it in two different ways.  However, I don't think that's a *valid* way to interact with your DAQmx task.  I'm not 100% sure, but I think DAQmx maintains 1 and only 1 set of task info even when you branch the "task refnum" wire.  The two copies of the task refnum both refer back to the one single set of properties.

 

So when you set DAQmx Read properties 2 times in parallel, I believe that whichever one happens to execute *last* will end up stomping on the first settings and taking precedence for all further task interactions inside the loop.

 

One usage wants to read and graph the most recent prior 150 kSamples (1 sec worth at 150 kHz sampling) which will require no waiting.   The other usage wants to (puzzlingly) read the most recent 1 sample and the next 1499 and enqueue them for a consumer loop to digest.  This will require ~10 msec of waiting.

 

I'm not sure your consumer loop is writing the data correctly either.  The shift register keeps growing a 4xN array by 1500 rows at a time.  First 4x1500, then 4x3000, then 4x4500, etc.  But then you keep rewriting *all* the data every iteration.  If the True constant is for the 'append' input, that would explain why a lot of your data keeps getting repeated in the file.

 

Recommendations:

1. Start from code that looks more like what Andy posted.

2. Choose only 1 way to drive loop timing.  Either use the msec multiple timer and read past samples or use no msec timer and request a fixed # of samples.

3. While it's possible to interact with DAQmx where different parts of the code can peek at different parts of the task data buffer, there are limitations, constraints, and complications.  I've done it in a limited context, but I don't generally recommend it.  It's tricky to get it right, and even if you do there's usually a simpler alternative.  The approach you tried isn't going to get you there.

4. Keep the part where you read 1500 samples at a time, but I'd recommend reading them as a 1D array of waveforms.

5. Replace the other part by simply sending this array of waveforms to a waveform *chart*.  Set up the chart to have a history length that holds 1 second (or whatever).  Note: this part may be a little tricky.  When the datatype for the chart is a 1D array of waveforms (each containing 1500 samples), I *think* you want to set the history length to 100, to allow for 100 such waveform chunks that collectively represent 1 second.

 

 

-Kevin P

0 Kudos
Message 5 of 16
(483 Views)

Thank you everyone for the suggestions and answers. Now I kind of understand what's happened. 

 

My aim was to record DAQ signal with 150 kHz sampling rate for like 10-20 s, while also monitoring the signal real time within 5 s time frame at much lower frame rate. The monitoring does not be at 150 kHz though, but I have not worked on undersampling the signal (I plan to average the signal to undersample it). I kept appending the data to a text file because the data would be very big, such that buffering the data would cause lag and even memory error (does not have enough memory). 

 


@Henrik_Volkers wrote:

And keep in mind that not all samplerates are supported, it's a good idea to read the actual samplerate property after the configuration.


According to the datasheet, PCI-6251 can sample up to 1 MB/s (multi channel), so it should be okay, should not it?

 

So, I will build my VI based on what Andy has shown. I will just use 1 task as everyone suggested, which read the signals in the form of 1D Wfm, and then process the signals to achieve what I want. I will be back after building the VI or have problems.

 

-Jane

0 Kudos
Message 6 of 16
(478 Views)
I kept appending the data to a text file because the data would be very big, such that buffering the data would cause lag and even memory error (does not have enough memory). 

It would be much better to stream data to file incrementally.  You should open the file once before the loop and pass the file refnum into the loop.  Inside the loop, you use the refnum to call a File Write which will then write *incrementally* (i.e., only the new data coming in via queue).  After the loop terminates, you close the file once, using the file refnum.

   There are minor variations of this where you add logic inside the loop to know when you need to open the file (but only once).

 


@Henrik_Volkers wrote:

And keep in mind that not all samplerates are supported, it's a good idea to read the actual samplerate property after the configuration.


According to the datasheet, PCI-6251 can sample up to 1 MB/s (multi channel), so it should be okay, should not it?

Well, yes and no.  Yes, your device can support sampling multiple channels at an *aggregate* rate of 1 MHz.  With 3 channels, that's 333.333 kHz max which is more than the 150 kHz you're targetting.

 

Henrik's point is that you won't get 150 kHz *exactly*.  The sample clock will be an *integer* divisor of the internal timebase (80 MHz).  If you ask for 150 kHz, you'll get an *actual* integer divisor of 533 for a sample rate of 150.0938 kHz.   I was just in a related thread earlier today.  Follow the OP's link in the first msg.

 

Many apps aren't particularly sensitive to such quantization errors, a few are.  If you only need a consistent sample rate of at *least* 150 kHz, you'll be fine.

 

 

-Kevin P

0 Kudos
Message 7 of 16
(468 Views)

I built the VI as suggested, but it still does not record samples as expected.

 

At 150 kHz sampling rate, it only recorded 750 k samples in 10 s. I checked the samples along the timestamp, it recorded 15 k samples every 0.2 s.

 

The saved text file looks like this:

 

06:03:10 AM   (15000 samples)

06:03:11 AM   (15000 samples)

06:03:11 AM   (15000 samples)

06:03:11 AM   (15000 samples)

06:03:11 AM   (15000 samples)

06:03:11 AM   (15000 samples)

06:03:12 AM   (15000 samples)

 

I have tried varying the timeout, samples per channel, and number of iteration; but it always gives me 75 k samples per second, which is half of the expected sampling rates.

 


@Kevin_Price wrote:

Henrik's point is that you won't get 150 kHz *exactly*.  The sample clock will be an *integer* divisor of the internal timebase (80 MHz).  If you ask for 150 kHz, you'll get an *actual* integer divisor of 533 for a sample rate of 150.0938 kHz. ... 


Thank you Kevin for the explanation and the link. But exactly half of the expected sampling rate is too much, is not it?

 

Attached are my VI (saved for LV14) and the snippet of VI.

 

-Jane

0 Kudos
Message 8 of 16
(451 Views)

1. Good idea to move the (relatively slow) graph update out of the data acq loop.  But I think you'll probably be better off with a chart -- they're different things.

 

2. Bad idea to move it into its own loop so you now have 2 consumer loops pulling data from the same queue.  Just put it in the same loop as the file writing.

     What's likely going on is that one of the loops happens to get in line first to retrieve the first chunk of data you enqueue.  As it dequeues, the other loop is now first in line and gets the next chunk of data you enqueue.  And so on, back and forth.  So the file writing loop only retrieves 1/2 the total data and the graphing loop retrieves the other half.

 

 

-Kevin P

0 Kudos
Message 9 of 16
(447 Views)

Yes, as Kevin says in point 2: only dequeue the data in one place (one consumer loop) then do whatever you need to do with that data.  The data written to file can be extracted from the waveform that is being displayed on the graph or chart.

 

Andy

0 Kudos
Message 10 of 16
(406 Views)