08-14-2019 12:25 PM
Kevin, since you're here now... Do you know why the DO task setup seemed to only work for low frequencies? (less than 23.4kHz if I remember correctly, with more or less full output FIFO and regeneration).
I'm fairly sure it's not driven by the sample rate of the digital waveform, except if using on demand timing or waveform timing (neither of which was true).
08-14-2019 02:30 PM
I'll try to take a closer look later in the day when some time frees up. I kinda skimmed the earlier DO part of the discussion, and when I saw keywords like FPGA and cRIO and FIFO's, I didn't really dig in b/c I don't have enough experience to offer much. When the conversation switched to counters, well, that perked up my ears a bit...
-Kevin P
08-14-2019 03:38 PM - edited 08-14-2019 03:38 PM
Try setting the slave trigger directly to "/cDAQ_Name_Here/CtrxInternalOutput" (where x is the counter # of the master). Maybe the start trigger behavior is different for counters than it is for analog and digital tasks in some way where I'm unfamiliar.
08-14-2019 09:14 PM - edited 08-14-2019 09:15 PM
I just went back through the thread. Here are some thoughts and remarks, some of it is just to comment on or emphasize what others have already said. Not exactly a summary, but kinda sorta like a highlights show.
1. 5 samples of DO would be ok to get 40% duty cycle on 1 line, but I agree 10 are needed to generate 2 such signals 180 deg out of phase.
2. Thus, if the signals need to be 100 kHz, the DO task needs to run at 1 MHz sample rate.
3. I don't know the cDAQ hw family nearly as well as desktop-style boards. I'm aware of some desktop boards that top out at 1 MHz for DO, others top out at 10 MHz. Some can self-generate a DO sample clock, others can't.
It appears your cDAQ setup *can* self-generate a DO sample clock. I'd be mildly surprised if it didn't support 1 MHz generation, but not shocked.
4. When DO generation stops early, there's probably a DAQmx error. But from what I see, it isn't being "caught" or noticed. Add an error indicator or dialog, that'll likely give a big clue about what's going on.
I kinda suspect it *is* related to the need to transfer data over USB. A 2k on-board FIFO represents a 2 msec buffer at 1 MHz sample rate. On average it needs to be refilled every 2 msec. Most typically, it probably tries to call for 1/2 buffer of data every 1 msec.
It is NOT surprising to me if USB can't *reliably* keep up with this.
5. I don't really understand the info presented in msg #14. It seems to give credence to cbutcher's thoughts from msg #13
6. The comment from Michael Munroe in msg #19 seemed to have gotten passed over, but might be pretty important.
7. I'd recommend you try setting the following property to force the DO task to regenerate solely from the onboard FIFO memory. Dunno if your cDAQ setup will support this setting, but give it a try. If supported, it takes USB transfer issues out of the picture.
8. Having said all that, I think the counter approach might be worth trying as well. Try specifying the "ArmStartTrigger" terminal like I suggested in msg #30.
-Kevin P
08-15-2019 03:24 AM - edited 08-15-2019 04:02 AM
@croocifer: Your solution is working very good.
(Try setting the slave trigger directly to "/cDAQ_Name_Here/CtrxInternalOutput" (where x is the counter # of the master).
This means, that the triggering of TaskB is working always independent of what counters i use for A/B. I tried all combinations and it works always.![]()
Is it correct that i have to manually write this into a constant? (This selection is not available in the dropdown values when creating a constant.)
Finally i have to create a function that makes this string automatically depending on the selected counter in TASK_A
@Kevin_Price: This is not working ("More-->Arm Start-->Terminal.)
One strange thing:
TaskA: ctr0 and PFI0
TaskB: ctr1 and PFI1
Scope measures signals BNC0 and BNC1
TaskA: ctr0 and PFI0
TaskB: ctr2 and PFI2
Scope measures signals BNC0 and BNC2
TaskA: ctr0 and PFI0
TaskB: ctr3 and PFI3
Scope measures signals BNC0 and BNC3
TaskA: ctr0 and PFI0
TaskB: ctr1 and PFI2
Scope measures signals BNC0 and and BNC1 and BNC2
TaskA: ctr0 and PFI0
TaskB: ctr1 and PFI3
Scope measures signals BNC0 and and BNC1 and BNC2 and BNC3
going back to:
TaskA: ctr0 and PFI0
TaskB: ctr1 and PFI1
Scope still measures signals BNC0 and and BNC1 and BNC2 and BNC3
Closing Labview complete does not change anything, only when i remove/reinsert USB from cDaq and restart labview then the signals stop and output only at the selected outputs.
How can this be explained?
08-15-2019 07:29 AM
1. You can access the counter output signal programmatically in a similar way as the the trigger terminal, using a DAQmx Channel property node. More about this solution below.
2. The other odd behavior you described is probably related to a behavior called "lazy uncommit." Search that phrase here to read more.
3. RE: Arm Start Terminal -- don't bother pursuing further, but I've gotta say I'm surprised that tasks for the other IO types emit a Start Trigger pulse when they start, even if they weren't configured for a trigger. I figured the counter tasks would behave the same, and since the regular StartTrigger terminal wasn't available for routing, the ArmStartTrigger terminal seemed like it might show similar behavior.
4. Back to using one counter's output pulse to trigger the other counter's task. There's a couple subtle things to watch for, and you may need some careful trial and error with your scope to get the timing exactly right.
5. First, the output pulse will be a little delayed from when the theoretical StartTrigger signal *would* have pulsed. The amount of delay is based on the defined pulse timing parameters, the output transitions at the END of those times. To get your 180 deg phase difference, you'll need to account for this extra little bit of delay time at startup.
6. Second, there's some inconsistency amongst the help and examples about this. There are low time, high time, AND initial delay parameters. A typical task with low idle state will use initial delay as the very first waiting time before transitioning high. Thereafter, it alternates between high time and low time.
7. There are further possible things to check into for triggered pulse generation tasks. The behavior can vary by device type. (I think it also had a longer-ago history of variance with different driver versions, but that was quite a long time ago.) Here's a little more info, not sure if it's all you need.
Ideally, you'll be able to calculate the right initial delay value for your triggered counter to make it pulse 180 out of phase with the other "master" counter. But be prepared to do a little trial and error with your scope, measure and adjust until right.
Also, please post back if you learn something surprising from this trial and error.
-Kevin P
08-15-2019 09:04 AM
If someone is interested about the 180° phase shift using the "initial delay" parameter...
I am using 100kHz and a DutyCycle 0,5 on both channels.
To have a 180° phase shift the initial delay of TaskB should be (1/100e3)/2=0,00000500s
Running this the scope shows a picture as attached in 500.jpg. This is not really good.
To make it synchron i manually adjusted the time to 0,00000496.
I think this would be solved when using th DO variant instead of counter. But then i dont have the DutyCycleParameter and i am fixed to the boolean array.
08-15-2019 09:54 AM
First, glad you got it worked out! It looks like a 40 nanosec discrepancy between "theoretically right" and "experimentally confirmed." It appears your chassis uses a 80 MHz internal timebase, which could potentially account for timing discrepancies in increments of 12.5 nanosec.
I'm out on a limb here, but I know there are some things down in the weeds of counter behavior that demand a minimum of 2 timebase ticks. Not everything is well publicized nor handled similarly in the API. If you wire 0 to the initial delay, DAQmx will silently coerce to the minimum legal value of 2 timebase ticks. If you wire 0 to low time or high time, DAQmx will spit back an error. (It used to silently coerce, and I got burned by this in the last couple years when a driver upgrade broke some old previously-working code.)
I'm taking a wild speculative guess that the 40 nanosec you observe is a combo of: 25 nanosec for some hidden place that a 2-timebase-tick rule is enforced, plus another ~15 nanosec delay related to circuitry and signal propagation related to triggering. Even though 3 timebase ticks is pretty close to 40 nanosec, I've never heard of any counter timing quirk related to 1 tick or 3 ticks worth of time. Always 2.
FWIW, I would venture a guess that this 40 nanosec discrepancy is pretty constant and independent of the programmed pulse frequencies.
On another topic, you seem to prefer the counter approach due to more direct control over duty cycle. If you plan to modify these duty cycles on the fly, there are some more things you should know:
It at least *used* to be true, and probably (?) still is that the main 2 pulse timing parameters (whether expressed as low time/high time, or freq / duty cycle) are not treated exactly the same. Dunno if this is (was?) purely an API & DAQmx driver issue or whether it's based in the hardware somehow.
The symptom is (was?) that if you tried to update only the duty cycle parameter in a pulse generation task, nothing would happen. You had to also rewrite your frequency parameter to *activate* the change. (On the other hand, you could write a new value to frequency alone, and the change would activate even if you didn't also write a duty cycle value.) The same holds true with respect to low time / high time though I'm not certain which one does the activation.
Note: I have not investigated this in quite a long time. For example, here's a 12 year old thread where I was already referring to this as a behavior I'd observed in the past and wasn't sure was still true.
-Kevin P
08-15-2019 10:18 AM
Thanks for your tips.
Your guess is very good. The 40ns are stable at all frequencies. I think i add an extra offset parameter so that i can insert the real "initial time" at the control.
10-18-2019 03:18 AM
Hello,
I found a new problem with the output of the two traces.
The start of both is great in timing as wrote before.
But when stopping then i see two problems.
A) Stopping using twice the NI-DAQ-StopTask.vi (which first stops channel_2 and then channel_1) then i see in the scope that channel 1 is running for 2.8ms longer.
B) Stopping hard the complete labview-vi (without executing NI-DAQ StopTask) then i see in the scope that channel 2 is running for 2.8ms longer
So my question is: How can i thrigger the NI9402 to stop both tasks at the same time?
For the parallel start is used the "DAQmx Start Trigger (DigitalEdge).vi" which gets the handel of channel 2 and the InternalOutput as Source of channel1.
Is there also something like this to stop both parallel?
Thanks.