Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Programmatically retrieve Sample Clock signal source as DAQmx terminal?

Kevin,

Unfortunately, I don't think there is a way to determine which resources are being used.  Besides the obvious routes such as PFIs and RTSI or PXI_Trig lines M-Series board have many, many other routes that can be reserved by the driver.  Since there are so many resources it is easier for the API to simply tell the user if they are trying to access a resource that is already reserved rather than trying to provide a huge list of what reservations are taken.  It becomes more complicated since some routes are indirect and so use multiple resources.  In almost all cases there are ways to avoid having to explicitly route and let NI-DAQmx deal with the resources.

In my previous workaround I didn't take advantage of this DAQmx functionality since I didn't understand that the driver was simply acting improperly.  A better work around would be something like this:



DAQmx will not step on the toes of previous tasks.  It will track which resources are reserved and try to use other resources.  If no resources are available an error will occur.

Regards,

Neil S.

Message Edited by Neil S. on 10-03-2007 04:05 PM

0 Kudos
Message 11 of 15
(1,863 Views)

Thanks again, Neil.  Your latest post is actually the exact kind of string-building workaround I mentioned in my original posting, before you joined the thread.  So that seems to confirm that it's the preferred workaround method, and I can let it rest.

But wait, there's another separate question / comment still related to my app.  The context for this stuff again is an attempt to modify an Action Engine whose function is to generate a shared acquisition sample clock and output the clock's terminal for use in configuring other data acq Action Engines.  To date, the acq clock was always a counter pulsetrain but I have a future need to generate it with a dummy AO task.

Furthering this stuff, I'm wanting to let this be determined at run-time by configuring my acq clock using a MAX-defined global virtual channel.  In the past, I simply used a physical counter channel for the config but need this to change for flexibility among CO, AO, and AI.  I haven't tended to use MAX global channels much and am finding that counter output tasks are a bit quirky to configure via MAX.

1. In MAX, counter output channels can *only* be defined in terms of Time with units = Seconds.  This is surprising as it seems more common for people to want to define a frequency in Hz.  Additionally, I find myself on many occasions defining counter behavior with units=Ticks.   The MAX interface for defining counter output channels really should provide more flexibility here.

2. Once a counter output channel has been defined in terms of Time, it won't allow me to override the pulse properties in terms of Frequency.  Combined with the MAX restriction that my global channel forces me to define my channel in terms of Time, this is a significant hassle.  I would like to be able to simply feed in the global channel to DAQmx Create Task, and then set the pulse frequency.  Here's what I'm stuck doing instead:

A. call DAQmx Create Task with my counter output virtual channel

B. query task for timebase freq

C. calculate the integer # of ticks that is the closest approximation to the desired frequency based on the actual timebase freq.

D. convert integer # of ticks to high and low times, and write them the the counter output task

E. calc the corresponding freq to output from my Action Engine

   I'm puzzled by this restriction in DAQmx.  The function DAQmx Create Virtual Channel allows us to define counter outputs in terms of freq, time, or ticks and is clearly smart enough to do the needed calcs and conversions under the hood.  I really don't see the advantage or purpose in its refusal to allow me to set or query a Frequency just because the channel was defined in terms of Time.  Under the hood, it's got to convert all the freq and timebase stuff into integer ticks at some point anyway, so why should it care?  In other words, all the raw information is ultimately in terms of integer ticks.  DAQmx should simply accomodate me when I provide or request info in other units.

   An analogy for the flexibility is the behavior of counter input channels.  Even if I set up an rotary encoder position channel, I'm still allowed to call DAQmx Read to get raw unscaled integer U32 values.  DAQmx doesn't refuse to give me the U32 counts just because I had previously provided it info defining how it *could* scale to DBL degrees.

-Kevin P.

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 12 of 15
(1,848 Views)
Kevin,

As to your last post, I agree this feature would be useful.  Could you create a product suggestion so we can discuss it in future planning meetings:

http://digital.ni.com/applications/psc.nsf/default?openform

I would for a moment also like to return to our previous discussion.  After closer inspection I was actually incorrect about the DAQmx driver.  The driver is actually returning the correct value.  The correct value to return with this property is ai/SampleClockTimebase.  Let me explain why.  Looking at the M-Series manual we can see the timing architecture of the ai subsystem:



ai/SampleClock >> Source actually returns the source that is being routed to the ai/SampleClock through the mux in the above diagram.  This can either be some external source such as PFI or RTSI or the internal ai/SampleClockTimebase through a divisor.  So the source of the ai/SampleClock is still the SampleClockTimebase (albeit divided down).  I suppose Divided Down Sample Clock Timebase would be a better name, but you get the idea.

One thing you can note however, is that ai/SampleClock is always the sample clock for the task, whether it comes from PFI, RTSI, or another counter so you can always safely route the ai/SampleClock to obtain the actual sample clock.  In your case you want a dynamic timing source that can be either a AI, AO or counter task.  To determine which item can be used to route the pulse train you will need to just query the task type and device and then return either:

/Devx/ai/SampleClock, /Devx/ao/SampleClock, or /Devx/CtrnInternalOutput for AI, AO, and CNT tasks respectively.

Regards,

Neil S.


Message Edited by Neil S. on 10-04-2007 12:54 PM

0 Kudos
Message 13 of 15
(1,837 Views)

Quick followup for anyone who lands in this thread:

I submitted a couple product suggestions formally through the link.  While I can follow the reasoning for why "ai/SampleClockTimebase" may be a technically accurate name to return, it's a bit unclear what purpose it could serve.   But since it's at least accurate rather than erroneous, it probably shouldn't be changed.

What I'm requesting instead are new properties in the DAQmx Timing property node.

1. A property with a name like DAQmx Timing-->Sample Clock-->Signal.  This would return a DAQmx Terminal like "ai/SampleClock" which could be wired directly into another task's DAQmx Timing vi as its sample clock.   I think Signal is a better label than Terminal because the word "terminal" also carries a connotation of connector block screw terminals, and some of these timing signals don't usually show up there.

2. An analogous property to identify a counter pulse train output terminal.  While this DAQmx terminal is already available via a DAQmx Channel property, it's tempting to suggest that the same Sample Clock-->Signal property referenced above might also return it.   This would make a nice symmetry in the API, and I think it's justified.  After all, a pulse train is configured by calling DAQmx Timing with "Implicit" timing, meaning that the "sample clock" implicitly IS the pulse train signal.  And I don't forsee any major confusion.  If you query a pulse train task for its sample clock signal, I'm hard pressed to think that you'd want anything else besides a reference to the pulse train signal itself.   One small thing to consider though: perhaps the Timing property should return the internal signal "CtrXInternalOutput" (similar to "ai/SampleClock") while letting the Channel property return the terminal block pin "/Dev1/PFIx".

3. This should extend to hardware-timed DIO as well, including M-series boards that have to "borrow" a sample clock from elsewhere.  When such a timed DI/DO task is queried for Sample Clock-->Signal, the output value should be wire-able into another task's call to DAQmx Timing to sync them.

-Kevin P.

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 14 of 15
(1,797 Views)
I've attached a portion of one of the drawings in the NI-DAQmx Help. You can find the full drawing in the help at NI-DAQmx Key Concepts ->Timing and Triggering ->Clocks. The sampleClk.source property returns the name of the terminal that provides (sources) the signal to the ai/SampeClk terminal circled in red. In other words, the name of the terminal immediately upstream. When the onBoardClk is used as the sample clock, the source is the ai/SampleClkTimebase. When PFI 4 is used then PFI 4 is the source. The source of the signal at the ai/SampleClk terminal cannot be the ai/SampleClk terminal itself.
0 Kudos
Message 15 of 15
(1,776 Views)