Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

synchronizing multiplexed digital input

I am testing a multiplexed system, which outputs time multiplexed digital outputs. One channel per clock period. For example, if multiplexing 4 channels, the digital outputs are DO_Ch0, DO_Ch1, DO_Ch2, DO_Ch3... The multiplexed system gets its clock from the NI PXIe6368.

I want to read these digital outputs, for which I use a digital input channel. The digital input task uses the same sample clock as used by the multiplexed system, so the output and input are synchronized. How can I synchronize my digital input read operations, so I know what channel sequence is being read?

For example if I use DAQmxReadDigitalU32(taskHandle, nsmpls=4....), the data array can contain [DO_Ch0, DO_Ch1, DO_Ch2, DO_Ch3]

or it can contain [DO_Ch1, DO_Ch2, DO_Ch3, DO_Ch0]

or [DO_Ch2, DO_Ch3, DO_Ch0, DO_Ch1]

How do I ensure that the data array contains a predictable sequence always say:[DO_Ch0, DO_Ch1, DO_Ch2, DO_Ch3]

This problem seems similar to serial data communication, except that my dat sequence does not have any preamble or setup packets.

0 Kudos
Message 1 of 10
(3,625 Views)

It seems strange that it's a multiplexed digital system. What is the purpose behind it? Is it possible to have it output on four different lines?

 

If it's not possible to set the output to four different lines, can you force one of the lines to be a specific value and use that as a reference?

0 Kudos
Message 2 of 10
(3,591 Views)

>It seems strange that it's a multiplexed digital system. What is the purpose behind it? Is it possible to have it output on four different lines?

The multiplexed output comes from an external ADC. The input of ADC is multiplexed.

 

>If it's not possible to set the output to four different lines, can you force one of the lines to be a specific value and use that as a reference?

Because the outputs to be read are generated by an external ADC, I can not insert a predetermined pattern.

0 Kudos
Message 3 of 10
(3,577 Views)

Your DO and DI tasks will each *independently* derive a sample clock from a master timebase on your board.  Thus, when they share a requested sample rate, they will indeed have the same interval time between samples.  This does *not* put them in sync however.

 

The sync you want would also require them to have the same start time and same phase.  When each derives its own sample clock independently, they're unlikely to share the same phase.  They also start at different times in the code you've posted in various threads.

 

Here's my preferred method to get start, phase, and interval timing sync between two tasks:

- Configure task B (input) to use the sample clock from task A (output) as its sample clock.  This is designated with syntax similar to "/Dev1/do/SampleClock" (when digital output is task A).

- Configure task A (output) to use the internal timebase, i.e., the normal way to let it derive its own sample clock.

- START task B FIRST!   It won't be able to do any sampling yet though, not until you start task A to supply it with a configured sample clock.  Because task B is started and waiting, the shared sample clock signal syncs them in all 3 ways -- start, phase, and interval timing.

 

Presumably, you'd send this same signal out to act as the clock for the external MUX.  Again, as long as your input task is started before the clock signal starts, you can expect your first DI sample to correspond to the first channel clocked into the MUX.

 

One subtletly I'll throw in now.  I would usually not sync all 3 ways in a case like this.  I would intentionally offset the phase by a fraction of an interval.  I'd run my DO task and the MUX on the *leading* edge of the clock while running my DI task on the trailing edge.  This gives a tiny bit of time for the MUX to operate and produce a stable output before your DI task samples it.

 

I typically make my own clock with a counter so I can control the polarity and duty cycle.  Then I have both DO and DI use the counter output as their sample clocks, and am sure to start the counter pulse train *last*.

 

 

-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 4 of 10
(3,570 Views)

Thanks for the suggestions. I have been trying to use triggering to synchronize the read and write tasks (apart from sharing the sample clock). Your idea of using the explicit sample clock from write task in the read task would simplify things. But I am curious why the read task won't start until the write task starts? Would not the sample clock used for the write task have started independently of either tasks (and thus being available to start the read task)?

 

 

0 Kudos
Message 5 of 10
(3,558 Views)

It turns out that the sample clock signal is only generated when sampling is happening.  It starts when the task starts and ends when the task ends.  For finite tasks with N samples, you'll get exactly N sample clock pulses.

 

Can't speak to the why, just the what.  I suspect maybe stuff related to the onboard FIFO and DMA transfer of data might be clocked by the sample clock such that it's important that the sample clock starts and stops with the task.

 

 

-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 6 of 10
(3,556 Views)

Hi Kevin,

 

OK, that's pretty interesting. Thanks for the information.

0 Kudos
Message 7 of 10
(3,552 Views)

Hi Kevin,

 

Apologies that I am following on this after a gap. To recoup, you suggested using the <DOWriteClock> in the DIRead task. In my case, the setup has a counter generated master clock. This master clock is used by the external ADC, and therefore is supposed to be used by both digital read and write tasks. When I use the master clock for digital read and write tasks, they are no synchronized.

So, my system has multiplexed digital channels. And, I need to synchronize the channel selection (digital write) with channel read (digital read). If I multiplex two channels, I don't see synchronization. 50% of time the data read is aligned with channel selection, and 50% it is misaligned.

I also tried to use a shared start trigger for both digital write and digital read. This trigger is generated by a counter as a slower pulse train. But even using the same digital trigger does not synchronize digital I/O.

 

Thanks,

 

0 Kudos
Message 8 of 10
(3,499 Views)

It'd help to see code, but I have a hunch that both your DO and DI tasks might be configured to use same (unwired default) polarity setting for the sample clock signal they're using.  

 

See the comment I made toward the end of msg #4 in this thread.  Set your DO task to use the *leading* edge and your DI task to use the *trailing* edge of the clock signal.  For what it sounds like you're trying to do, I'd use a duty cycle of 90-95% to provide maximum settling time after DO MUX selection before sampling DI.

 

 

-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 9 of 10
(3,492 Views)

Hi Kevin,

 

Thanks for the reply. I did some more debugging, and the sample mode was one last thing I needed to fix. For the DigitalRead task the sample mode has to be DAQmx_Val_ContSamps, while I had set it at DAQmx_Val_FiniteSamps.

 

My mux'd digital IO seems to be synchronized now. I will spend some more time to check for robustness.

0 Kudos
Message 10 of 10
(3,486 Views)