Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Direct access to on-board buffer x-series devices USB-6343

Hi,

 

I am running Labview 2009 on and Windows 7 PC with NI-DAQmx 9.4 to control an X-Series USB-6343 Multifunction DAQ device.  I am mainly concerned with using one or more of the DO ports to control some external devices (shutters/switches).  To test my code I am driving a bank of 8 LED's with port0 configured to be a DO port.  I can talk to it fine, write data out in various modes, etc.

 

Here is what I'm trying to do and so far not getting too far probably mostly because I am fairly new to this area but maybe partly because I am finding documentation sparse.  Any help would be greatly appreciated.

 

1.  Timing is critical for controlling my external devices, so I cannot tolerate the tens of ms delays that Windows can introduce.  Therefore I think I want to be writing my DO patterns directly to the USB-6343 "On-board Memory" and am using the DAQmx Channel Property Node DO.UseOnlyOnBrdMem Property to specify this.  So far so good I think.

 

2.  I would like to be able to re-program the patterns in the on-board memory arbitrarily.  For instance, if I load 100 patterns, I would like to be able to interrupt after, say, 50 of the patterns have been outputted, disregard (or maybe pause) the rest of the patterns, and either restart (if paused), or load new patterns and restart.  Is this possible?  It seems like one way should be to simply stop the task (DAQmx Stop Task) and reload, or pause the output with an appropriate timing setup?  However, things seem like they might get complicated based on 3., below.

 

3.  I need to be able to know at what point I have paused or stopped the DO output.  Or to say it another way, I need to know how many patterns have been completed.  For example, if I press a button to stop the task, the new patterns I want to load subsequently might depend on how many of the original patterns were completed.  Is there some internal counter or time elapsed clock or something else that keeps track of how many patterns have been completed that I can access after I stop or pause the execution? 

 

I hope the above is clear but just in case, let me add one concrete example.

 

1.  Load 50 patterns directly into the On-board Memory of the USB-6343.

2.  Start output of the 50 patterns using the Sample Clock configured for Finite Samples at whatever frequency I want.

3.  Stop output (stop task?) before all 50 patterns have been output.

4.  Determine how many of the 50 patterns have been output (How?)

5.  If less than 10, load a new set of 50 patterns.

6.  If greater than 10, load a different new set of 50 patterns.

 

Thank you in advance.

 

Jason

0 Kudos
Message 1 of 10
(5,268 Views)

Hi Jason,

 

I think a simpler way to do this will be to use non-regenerative digital output (so the device doesn't keep writing the same data over and over again). This will allow you to change the data that you are writing to your digital output without having to stop and restart your task. I have slightly modified one of our examples to demonstrate this, which I have attached to this message. If you keep track of the iteration of the while loop, then you will know how many sets of data you have written to the device (which I know you need to do for you application.

 

You will notice that the DAQmx Timing VI is using the default timing source, the onboard clock. This ensures that the data are written using the timing clock on the DAQ device so you won't get the jitter effects of Windows. Essentially, the while loop is telling the DAQ device what to write, but the device is handling the timing of it.

 

I hope that helps.


Regards,


Daniel H.

 

Daniel Hays | Test Software Business Manager
0 Kudos
Message 2 of 10
(5,255 Views)

Hi Daniel,

 

Thank you for the response, it is somewhat helpful for another problem I was having with my code.

 

However, I don't think it gets to my fundamental problem.  Essentially I need to be able to stop the DO in the middle of each "New Data" pattern and know how far it has gotten when the output is stopped or paused. 

 

If I understand your code correctly it will allow me (by looking at the while loop counter) to know how many patterns have been written but not where in each individual patter the FIFO has gotten to.

 

Does that make sense?

 

Thanks,

 

Jason

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

Hi Jason,

 

Yes that makes sense. One good way to keep track of how many samples have been written would be to use a counter to count the edges from the digital output sample clock. If you use a DAQmx Channel Property Node you can route the digital output sample clock to one of your counters. Start the counter task before you start your digital output, then use DAQmx read on the counter task after you clear the digital output counter task. This will tell you how many total samples were written, from which you can figure out where in the current output array the last sample was.

 

Here's how the counter task could be configured:

 

Edge counting DO sample clock.jpg


Does that make sense?

 

Regards,


Daniel H.

Daniel Hays | Test Software Business Manager
0 Kudos
Message 4 of 10
(5,237 Views)

Hi again Daniel,

 

I think that does make sense to me, thanks a lot.  Let me give that a try and if I still have trouble I'll post a follow-up.  Thanks again.

 

Jason

0 Kudos
Message 5 of 10
(5,234 Views)

Hi Jason,

 

Good luck. Your 6343 should support that function so you shouldn't have too much trouble.

 

Regards,


Daniel H.

Daniel Hays | Test Software Business Manager
0 Kudos
Message 6 of 10
(5,228 Views)

Hi Daniel (or anyone else reading this),

 

If you have a moment could you take a look at my code attached?  I am simply trying to display how many patterns have been output by the port0 DO.  It kind of does what I want except for a few problems.

 

First, the counter always starts at 2 for some reason.  Why is that?

 

Second, at low Sample Clock frequency (below ~100Hz), if I let the program run through all 8 of the patterns, the counter sometimes returns 8 and sometimes returns 9.

 

Finally, at Sample Clock frequencies above ~200Hz the counter consistently misses several patterns and returns 2 or 3 or 4 (not reproducibly).

 

I've been looking at the manual, examples, and built-in help in Labview but don't have a great grasp on how the DO, DO clock, counter, counter clock, etc. are interacting.  Do you know a good resource that kind of summaries things nicely for someone like me who is just getting started in this area?

 

Thanks again,

 

Jason

 

 

 

0 Kudos
Message 7 of 10
(5,216 Views)

Sorry, forgot to attach my code, here it is.

 

Jason

0 Kudos
Message 8 of 10
(5,215 Views)

And another question:

 

Can I load the on-board memory (not pc memory/buffer) with additional patterns before the FIFO is empty?

 

For instance I'd like to initially add 2 seconds worth of patterns, start the DO, then after the first half of the patterns (1 second worth) have been output, load another second worth of patterns to refill the on-board memory/FIFO.  I need there to be no gap between the two sets of patterns.

 

Thanks,

 

Jason

0 Kudos
Message 9 of 10
(5,207 Views)

Hi Jason,

 

I've taken a look at your code, and I've noticed a few things that can be done to improve it. First of all, you're very close to having the functionality that you're wanting, and a few small changes should get you there.

 

To address the problems with your VI:

 

The problems you are seeing are due largely to dataflow.

 

1) Your counter value is always starting at 2 because it is picking up a pulse that happens when your DAQmx Write sends data to the FIFO. Thus, when it enters the while loop and reads the first pulse from actually outputting a sample, that is the second pulse. To fix this, wire the Error Out from DAQmx Write to the DAQmx Start for your counter task. Then have the Error Out from the DAQmx Start for the counter task wired to the Error In for the DAQmx Start for the digital output task. This will ensure that the counter task does not count the pulse from DAQmx Write.

 

2/3) The next two problems you are seeing with inconsistent end count values are due to dataflow and the type of digital output task you have created. The problem is that there is nothing to ensure that your DAQmx Read occurs AFTER all the values have been written. If you wire the Error Out from DAQmx Is Task Done to the Error In for DAQmx Read in your while loop, it will force the last read of your counter value to occur after the task has completed, and you will get the same value every time. Combine this with solution number 1 and you should get 8 every time for this VI.


The reason this happens is that your digital output task, once started, is not dependent on your while loop (if you create an indicator for your while loop iterations and watch this as you try different digital output rates, you will see what I mean). With your task set as finite, once you start the task it has all the information it needs. So it just starts writing values and it is up to you to make sure your counter task reads data at the correct time. The way you currently have it configured, the DAQmx Read can occur before all values have been written, which is why you get an end value less than 8. If your output rate is fast enough, then the output task can finish in between the first time the counter task is read but before the first time you check to see if task is done. Thus, DAQmx Read could return 2, 3, or 4 but your task will finish and your while loop will stop before you can call DAQmx read again. Does that make sense? 

 

Using the error wires to force the DAQmx Read to occur after DAQmx Is Task Done will fix this. I've attached a picture of what these changes will look like.

 

As for adding additional patterns before the FIFO is empty, the last VI I sent to you is the way to do that. Use the non-regenerative function, and if you increase the execution speed of the while loop, then DAQmx Write will add more data sets to the buffer even though the DAQ card will still be ouputting data at the same rate. It will "stack up" the data. There is no reason for you to use the Use Only Onboard Memory property for your application. The DAQmx timing VI takes care of the output rate from the card, so it will use the device hardware timing. The jitter you are worried about with Windows will only come into play when you use DAQmx Write to send data to the buffer, and if you're doing this faster than you're outputting data than it will not matter.

 

A couple resources that may help you in the future can be found here:

1) DAQ and Instrument Fundamentals

2) Important DAQmx Functions

3) Timing and Synchronization Features in NI-DAQmx

 

Regards,


Daniel H.

Daniel Hays | Test Software Business Manager
0 Kudos
Message 10 of 10
(5,202 Views)