Multifunction DAQ

Showing results for 
Search instead for 
Did you mean: 

Simultaneous AI and finite pulse generation: 10 MHz Ref Clock

Go to solution

Hello NI forumites-


I am working in LV 8.6.1 (Windows), and have two PCIe-6259 cards connected with RTSI cable.  My application requires that I be able to simultaneously acquire analog input from 64 channels in a synchronized manner (using the RTSI clock to synch 32 channels of AI on each card), and simultaneously generate a finite pulse train on the counter output of each DAQ card.  The AI and counter tasks need not be synchronized—they both just have to run at same time.  In general, my experiment requires that I start the AI, then the counters.  The AI is controlled through C# code interfaced to LV. I acquire 64 channels at 20 kHz (per channel) Unfortunately, I must plead ignorance in that I don’t know the full details of how that code is working.  The finite pulse trains are generated with the example VI Gen Dig Pulse


I am able to perform each of these tasks in isolation just fine.  The problem arises when I try to run both at the same time.  When I first start the AI, then attempt to start the VI to generate the finite pulse train(s), I get the error message copied below.  The fundamental issue appears to be that the 10 MHz reference clock is already in use for the AI, and the counter operations need that source, but are not allowed to share it.


If this is true, I am a surprised that the 10 MHz can’t be shared by both AI and counter task--after all, it is just a signal that could be fanned-out, routed to two places, I think.


Moreover: I don't understand why the counter(s) need to access/use the 10 MHz ref clock in the first place--the two 6259s need NOT need  communicate to produce a finite pulse train. Can't the two counters on the same 6259 which generate just use an internal timebase (eg 80 or 0.1 MHz) as their source?.   Also, I don't need that precision of timing (my pulse train freq is about 2 kHz).  Basically, I just want to set the counter source to be another internal timebase (e.g. 0.1 MHz timebase)--anything other than the 10 MHz Ref clock. I tried this approach, and that is where I ran into more problems.


The example VI for finite pulse gen chooses the source/timebase using “implicit” mode of  the DAQmx .  I thought I could explicitly set the counter source (step 2 in the block diagram) by changing the mode from “Implicit” to “Sample Clock”, then specify the source as the 0.1 MHz timebase.  This also requires that I change the mode from “finite” to (something like) “hardware single sample” (not "continuous" or "finite"...there are only 3 options), otherwise I get more errors.  When the DAQmx is set to anything other than 'finite', the VI hangs and eventually times out, presumably because the counter doesn't know when to stop counting. 


How can I get the best of both worlds: the capability to choose the counter source AND maintain the mode in finite?


Other clever solutions you might suggest?  Is what I want to do even possible—can I have AI and counters tasks running simultaneously? It seems like there ought to be an easy solution, but I have yet to stumble upon it.


 Many thanks. Jon

Error message:

Specified route cannot be satisfied, because it requires resources that are currently in use by another route.

Property: RefClk.Src
Source Device: Dev1
Source Terminal: None

Required Resources in Use by
Task Name: analogInTask_0
Source Device: Dev1
Source Terminal: 10MHzRefClock
Destination Device: Dev1
Destination Terminal: RefClock

0 Kudos
Message 1 of 14

First the good news -- I'm confident you *can* get there from here.  I've combined AI with counter pulse trains many times without the error you're seeing.


However, I admit I'm puzzled about the 10 MHz reference clock.  I'm not really sure how that's getting involved for *either* task.  I've never gone out of my way to *avoid* using it, nor have I ever seen an error like yours despite doing simultaneous AI, clocked DO, clocked DI, and pulse train generation.


Try adding a DAQmx Channel property node into your counter config chain before the pulse train is started.  The correct property is found at Counter Output/General Properties/Counter Timebase/Source.  The terminal constant may also need a little work.  First, right click it to select "I/O Name Filtering...".  Then check the box for "Include Advanced Terminals."  Once that's done, it's probably easiest to use the drop-down menu to select "Browse..." (found at the top of the list) to see all the possible choices.  Note though that not all the *possible* choices are *valid* choices.



Write back if this doesn't help clear up the error.


-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 2 of 14

Hi Jon,


I'm assuming you're using reference clock synchronization to sync your AI tasks - can you post that part of your code? Based on the error text, I think the issue is that when using the 10MHz clock for synchronizing the AI tasks, on one of the board's routing is taking up a counter terminal that you need to use for your finite counter tasks.  Sadly ref clock in is not shown in the routing table in MAX, so I'm basing this purely on your error code. If you're looking for a quick fix, you could share a sample clock over RTSI instead of the reference clock. According to the routing table in this should not use counter terminals.


Hope this helps,

Andrew S

0 Kudos
Message 3 of 14

Hi Jon,


Does your AI task use the Task.Timing.ReferenceClockRate and Task.Timing.ReferenceClockSource properties? It sounds like it does. If so, the solution is to use the same reference clock settings on the AI and counter tasks.


Why do you have to do this? On M Series, the reference clock is the source of a PLL that generates the internal timebases (80 MHz, 20 MHz, and 100 kHz timebases). These timebases are shared by all of the subsystems on the board (AI, AO, DIO, counters). If you started an AI task that uses the reference clock, and you were already running a counter/timer task that does not use the reference clock, then your counter/timer task's timing would be incorrect, because the PLL takes a while to ramp up or ramp down to the correct frequency. Allowing one task to interfere with another like this would introduce hard-to-find bugs in users' applications, so DAQmx requires both tasks to agree about how to configure the reference clock.


As for what these terminals mean:

  • If you don't specify the reference clock source, the default value is "None", which causes the task to disable the board's PLL and use the internal oscillator directly.
  • If you specify "OnboardClock" as Dev1's reference clock source, DAQmx coerces the value of Dev1's reference clock source property to "/Dev1/10MHzRefClock". This is a terminal that produces a 10 MHz clock signal using Dev1's onboard oscillator (not the PLL). You can then query Dev1's reference clock source and set that value on Dev2, so that Dev1 and Dev2 will have synchronized timebases.



Brad Keryan
Message 4 of 14

Also, "/Dev1/RefClock" represents the input of the reference clock itself. It's hidden because there's nothing useful you can do by routing to (or from) it directly, so it's more of an implementation detail than anything.



Brad Keryan
0 Kudos
Message 5 of 14

Kevin, Andrew, Brad,

Thanks a bunch for your helpful responses.  The goods news (I think) is that the issue can be easily resolved.  It sounds as if the AI/counter tasks and/or boards have a conflict regarding which timebase/clock source to use in common.  If  all tasks on all boards are configured to use the *same* timebase/source clock, hopefully everything will work out just fine.  I''ll dig into this first thing tomorrow and report back.  I'll also try to find the relevant snippets of C# code that are controlling the AI task, in case that can be helpful as well (several thousand lines of open source code I need to go through, the "Neurorighter" project for recording multiple channels/electrodes of brain activity)

Thanks again to all!


0 Kudos
Message 6 of 14

I just dug up what I believe are the relevant parts of the code controlling the AI tasks.  I've posted them below, with a few comments added in caps, in case they trigger any more thoughts in your hippocampi.  It is clear that all AI reference clock sources are being set to "OnboardClock", which, as described earlier is just defaulting to the onboard (non-PLL) 10 MHz clock.  Thus, I think I have two options.  Either change the ref clock for AI in the code below (more difficult); or set the counter task to also use the OnboardClock (easier...if this is allowed for finite pulse gen).  Will let you know how it goes...


Relevant code snippets:


Device analogInDevice = DaqSystem.Local.LoadDevice(Properties.Settings.Default.AnalogInDevice[0]);
                            if (analogInDevice.ProductCategory == ProductCategory.MSeriesDaq)  \\I HAVE M-SERIES 6259
                                spikeTask[0].Timing.ReferenceClockSource = "OnboardClock"; //This will be the master clock



.\\IN MY CASE, I HAVE 2 BOARDS, so the loop will terminate after the first iteration, e.g., setting spikeTask[1] properties.

                        for (int i = 1; i < spikeTask.Count; ++i) //Set other analog in tasks to master clock
                            spikeTask[i].Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                            spikeTask[i].Timing.ReferenceClockRate = spikeTask[0].Timing.ReferenceClockRate;




                    spikeTask[0].Timing.ConfigureSampleClock("", spikeSamplingRate,
                            SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples,  Convert.ToInt32(Convert.ToDouble(textBox_spikeSamplingRate.Text) / 2));


                    for (int i = 1; i < spikeTask.Count; ++i)
                        //Pipe ai dev0's sample clock to slave devices
                        spikeTask[i].Timing.ConfigureSampleClock("/" + Properties.Settings.Default.AnalogInDevice[0] + "/ai/SampleClock", spikeSamplingRate,
                            SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Convert.ToDouble(textBox_spikeSamplingRate.Text) / 2));
                        //Trigger off of ai dev0's trigger
                        spikeTask[i].Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/" + Properties.Settings.Default.AnalogInDevice[0] +
                            "/ai/StartTrigger", DigitalEdgeStartTriggerEdge.Rising);

0 Kudos
Message 7 of 14

OK--so progress has been made!

I first queried the RefClk.Src property and discovered it was being set to Dev1/None.  So, I then explictly set the RefClk.Src to "OnboardClock".    (I've attached a screen shot of the VI, just in case).  Happy to report that this solved the previous issue with conflicting source clocks--I was able to run my AI and my counter tasks (finite pulse gen) for Dev 1 counters 0 and 1. Sweet! 


However, I have now encountered another issue (which seems easily surmountable).  When I to start the AI task, then try start the finite pulse gen on Dev 2, either counter 0 or 1,I get another error, regarding a trigger line already being reserved. 


Error -89126 occurred at DAQmx Start

Possible reason(s):

Trigger line requested could not be reserved because it is already in use.

Property: RefClk.Src
Source Device: Dev2

Task Name: _unnamedTask<68>


If, instead, I start the counter task first, then start the AI, I get a similar, but slightly different error msg:


No registered trigger lines coudl be found between the devices in the route.


If you are using PCI devices, make sure they are connected with a RTSI cable and that the RTSI cable is regstered in MAX. Otherwise  make sure there is an available trigger line on the trigger bus shared between the devices.


Source Device: Dev 1

Destination Device: Dev 2


Task Name: analogInTask_1


Status Code: -89125


These errors are rationl/compatible--there are only so many trigger lines to go around.    However, I am not clear whether there can only be one start trigger carried on the RTSI bus--sounds to me like there can be up to 5 such triggers.  According to pg. 9-3 of the M series manual: "Once all of the devices are using or referencing a common timebase, you can synchronize operations across them by sending a common start trigger out across the RTSI bus and setting their sample clock rates to the same value....In a PCI/PCI Express system, the RTSI bus consists of the RTSI bus
interface and a ribbon cable. The bus can route timing and trigger signals between several functions on as many as five DAQ, vision, motion, or CAN devices in the computer."


I know for finite pulse generation 2 counters need to communicate:  one gates the pulse train of the others.  Maybe one solution would be to route a counter internal output over the RTSI lines to the other counter?  Seems like the solution should be obvious, but is eluding me.


Am all ears for any ideas on how to proceed. 


One sticking point to getting started, is how do I found out what trigger line is being used/already reserved in the first place?  I browsed through all the possible properties in a property node, but didn't find anything that talked about a trigger line.


thanks again for all your help and putting up w/ my long posts.


Almost there,




0 Kudos
Message 8 of 14

ps. previous post was made by me, Jon. Didn't realize another person (labmate) was already logged into NI forums on the computer I was using.

0 Kudos
Message 9 of 14

Hi Jon,


For the RefClk.Src property, DAQmx treats "OnboardClock" as an alias for "10MHzRefClock". Then, when you call spikeTask[0].Control(TaskAction.Verify) (which I'm pretty sure your program does at some point), DAQmx coerces RefClk.Src from "OnboardClock" to "/DeviceName/10MHzRefClock". After that point, reading RefClk.Src does not return "OnboardClock"; it returns "/DeviceName/10MHzRefClock".


To see this, please edit your .NET code and have it print out what it reads from spikeTask[0].Timing.ReferenceClockSource. (Or look at the value in the debugger.) It should print "/Dev1/10MHzRefClock", not "OnboardClock". (Assuming that spikeTask[0] corresponds to Dev1.)


The same thing happens if you set your counter/timer task's RefClk.Src to "OnboardClock". When the counter/timer task is running on Dev2, "OnboardClock" is treated as an alias for "/Dev2/10MHzRefClock". However, both of your AI tasks are still using "/Dev1/10MHzRefClock", which does not match. Dev2's PLL cannot lock to both signals at once, so you get routing errors again.


Solution: in your counter/timer VI, set RefClk.Src to "/Dev1/10MHzRefClock" and set RefClk.Rate to 10e6. Assuming that Dev1 is the master device for AI, then these are the same settings as the AI tasks are using in the .NET code.


By the way, the VI you posted has no data flow to ensure that the property node gets executed before the call to DAQmx To make it work reliably, wire the task and error cluster through the property node.



Brad Keryan
Message 10 of 14