10-03-2007 04:02 PM - edited 10-03-2007 04:02 PM
Message Edited by Neil S. on 10-03-2007 04:05 PM
10-04-2007 08:29 AM
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.
10-04-2007 12:53 PM - edited 10-04-2007 12:53 PM
Message Edited by Neil S. on 10-04-2007 12:54 PM
10-12-2007 03:53 PM
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.
10-18-2007 05:20 PM