Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Counting TTL pulses within specified integration time

joyce,

Looks like we're getting closer, eh?  I have a few comments that I hope will help.

 
...using  Express Write LMF , I get 4 columns of data:        x1|  counts | x2 | analog voltage
x1 and x2 are almost exactly the same (sometimes differ by 0.001, but would be synchronized again later on). So is this "really" synchronized reading ?
No, your readings really aren't guaranteed to be synchronous.  I've never created a LMF or used the express vi, so I don't know where it gets the time column from.  Since you aren't feeding it any time information, either the signal merge or the express vi must attach a timestamp somehow, maybe using the internal msec tick count?
 
I have assigned the same Sample Clock to both AI and CI but I choose "hardware timed single point" for AI.  I have tried "continuous" mode for AI (setting AI DataXferMech to "Interrupts" because I don't have enough DMA channel) but the "x" values (timing) are not the same.  At the end, I think the current configuration seems to work best for my purpose.
Actually, continuous AI using interrupts is exactly what I would suggest you use.  I'll come back to the different time values problem shortly, but first here's the problem with the method you posted:
 
The counter samples are being buffered continuously.  Each call to read 1 sample will retrieve the earliest unread sample in the buffer (so you won't lose any data).  Meanwhile, each call to hw-timed single point AI will wait and return the AI value converted on the next sample clock.  Generally speaking, your counter read will return immediately with existing data.  Then your AI will return with its data.  Meanwhile, the sample clock that allows your AI Read to return will be buffering an additional value into the counter buffer. 
 
Even in the very best case scenario where your sw loop is fast enough that you don't miss any AI samples, your Ctr and AI data is likely to be off by one sample.  In the more likely scenario where the sw loop occasionally misses an AI sample, you'll create a bigger non-correcting discrepancy.  Eventually you're liable to get a Ctr buffer overflow.
 
Advice:
 
1. Configure AI for continuous sampling using interrupts.
 
2. In your main loop, take advantage of your hardware that is buffering your samples.  Namely, read many samples at a time rather than just 1.  Personally, I'd setup an event structure with a case to handle your Stop button.  I'd feed a modest value of 50-200 msec to the timeout case.  Inside it, I'd query one of the tasks for "Available Samples."  Then, whenever that # is big enough (the # depends on sampling rate -- maybe about 1-5 sec worth), I'd request that same # from both tasks.  They should both be able to return their data without waiting, and the data they return will be truly hw-sync'ed.
 
Note that your single-value indicators won't be much use anymore.  I'd recommend replacing them with a 2-plot chart.
 
3. I wouldn't use the LMF express vi inside the loop.  I never use any express vi in a loop.  Their simple ease-of-use usually comes with the price of slower (sometimes much slower) execution.  When you use your own file-writing calls, be sure to open the file once before the loop, only perform writes to the already-opened file while inside the loop, and close the file once after the loop.
 
4. At some point, you may need to explicitly define the buffer sizes.  For your sampling rates, the defaults are liable to work out just fine, but remember that they can be increased explicitly.
 
-Kevin P.
CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 11 of 24
(3,104 Views)
HI Kevin,
 
Thank you for your advices, but I don't really understand how I can do this :
 
................Personally, I'd setup an event structure with a case to handle your Stop button.  I'd feed a modest value of 50-200 msec to the timeout case.  Inside it, I'd query one of the tasks for "Available Samples."  Then, whenever that # is big enough (the # depends on sampling rate -- maybe about 1-5 sec worth), I'd request that same # from both tasks.  They should both be able to return their data without waiting, and the data they return will be truly hw-sync'ed.
 
So I need to use an Event Structure case to handle the Stop button ? Or do I place the Event structure around everything inside the loop and use it to control the Read functions?
I have looked up some examples, but I don't really quite get this one. Could you please give me more help?
 
If I explicitly assign the buffer size and the the number of samples to read, then shouldn't the data  be synchronized ? Why does the Event case handle the situation better?
 
Thanks so much for your help.
 
Joyce
 
0 Kudos
Message 12 of 24
(3,079 Views)

Sorry for combining ideas unnecessarily.  My comments about the event structure were just a statement of habit and personal preference -- it has no real bearing on data synchronization.

If you're not yet familiar with the event structure, don't worry about it for this app.  However, I would still add a call to "Wait (msec)" inside the main While loop so you don't burn CPU unnecessarily.  Somewhere around a 50-200 msec wait is probably about right. 

Query for # of available samples and if large enough, go ahead and read that same # from both buffered tasks.  This is where synchronization is kept.

-Kevin P.

 

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 13 of 24
(3,073 Views)
I was having trouble last week because the error message always said there was no DMA channels available. After chaning this property and some other miscelleneous settings i've finally made it work.

How did you change the DMA channel property to eliminate problem?

0 Kudos
Message 14 of 24
(3,254 Views)
Hi,
 
I used the property node DAQmx Channel-> "properties"-> "Counter Input" ->"General properties"-> "More" -> "Advanced" -> "Data Transfer Mechanism"  , and then choose either Interrupts or DMA.
I think my PCI board only has one DMA channel so I had to change the DataTransferMechanism of Counter Input to "Interrupts."  I first assigned  the Analog Input to Interrupts, and CI to DMA, but then somehow the number of total samples acquired (using the DAQmx Read Property Node) were not synchronized, i.e. AI samples acquired didn't seem correct. So I swithced them around and then it worked.
 
Joyce
0 Kudos
Message 15 of 24
(2,985 Views)

A very general comment for future readers: typically the AI subsystem on a board will have a bigger on-board FIFO for data scheduled for transfer to system RAM than the counter subsystem.  While joyce had success giving DMA to the AI task and interrupts to the counter task, I think one might often avoid DAQmx transfer errors better by giving DMA to the counter subsystem -- especially when acquiring only a couple AI channels or so.

It's probably one of those system-dependent things, so check it out for yourself.

-Kevin P.

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 16 of 24
(2,828 Views)
Don't forget that if you get an M Series board you'll have 6 DMA channels,so you can do pretty much everything via DMA and not have to really worry about the resources.
0 Kudos
Message 17 of 24
(2,802 Views)
Hi
 
  I'm using 6602 board. I wanted to use all the 8 counters to acquire the data. But if I had more than 3 counters I get an error stating the resources are reserved.
 
  Basically I'm not able to acquire data in more than 3 counters. So I thought as there is only 3 DMA in the 6602 board it shows the error meaage the resources are reserved.
 
  I set the the data transfer machanism for the 3 counters to DMA and just added one more counter and set the data transfer mechanism to interrupts. All the four channels will be in the same task.
 
  Again I'm getting the same error the resources are reserved.
 
  Is that something else has to be done to make the data transfer meachanism to interrupt.  How to go about this in C#/DAQMX. I'm not aware of LabView. I could find discussions related to Labview.
 
 Can anyone explain what else should be done for interrupts and dma to work in DAQMX / C# /6602 board
 
Thank you
Mullya
 
0 Kudos
Message 18 of 24
(2,398 Views)

Hi

 Just a small change in my previous post. As the data should be acquired each counter will be a seperate task.

I have also gone through this document  http://digital.ni.com/public.nsf/allkb/c326f7d33ca6db0e86256dfe008043b7

I have set the transfer meachanism for the 4 th counter to interrupt before the BeginReadMultiSampleInt32 and for all other counters it is set to DMA. But still I get an error stating the resources are reserved.

Anything else has to be done for the interrupts to work?

Thanks

Mullya

0 Kudos
Message 19 of 24
(2,395 Views)
What's probably happening is that you are trying to use a Counter that is already paired with another.

For example, if you do a Finite Pulse Train Generation then it will use 2 counters.  If you tell it to do the Finite Pulse Train on channel 1 then it will use the counter pair counter 0 to perform the task.  So you probably have 1 or more tasks that uses 2 counters and are simply trying to use that counter for another task hence the error.

The best way to get around this would be to first see which tasks require 2 counters (Finite Pulse Trains, Frequency Counting), and then make sure that you are not using a paired counter.  The pairs work like this 0-1, 2-3, 4-5, and 6-7.

Once you get all of this then the program should run fine.

Regards,
0 Kudos
Message 20 of 24
(2,390 Views)