Academic Company Events NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Document Type: Tutorial
NI Supported: Yes
Publish Date: May 9, 2007


Feedback


Yes No

Related Categories

Related Links - Developer Zone

Related Links - Products and Services

Balanced I/O Example DAQ Personality

1 ratings | 5.00 out of 5
Print | PDF

Overview

This document is part of the Customize Your DAQ Device series. This tutorial describes how to use the Balanced I/O Example DAQ Personality. It first explains the overall architecture of the FPGA code and then goes into detail about how to use each of the example host VIs that are included in this example. To download the code for this example DAQ personality, see the Balanced I/O Example DAQ Personality Download

FPGA Personality

All of the core functionality of this intelligent DAQ example personality is contained within the FPGA code.  This FPGA code implements analog input, analog output, counters, and digital IO tasks on a low level.  Each of these components are actually contained within their own separate loops in the LabVIEW FPGA code and in the following sections I will describe how the FPGA code works.  While each of the components of the code are addressed separately, it's important to keep in mind that they are all within one FPGA VI.

Analog Input


[+] Enlarge Image

Figure 1: Analog Input Loop

The outer while loop simply polls the “AI Enable” boolean.  Once this boolean goes true, the analog acquisition begins.  The inner while loop is what actually controls the data acquisition.  This inner while loop consists of a flat sequence structure with 2 frames.  In the first frame, we are simply setting the loop rate such that the loop runs at the specified sampling rate.  There is some additional logic in this frame as well to let the user know how fast the loop is actually running.

The second frame of the sequence structure simultaneously acquires a single sample from each channel (channels 0-7) and builds these 8 samples into a 1D array.  This array is then fed into a single cycle timed loop.  This loop will execute once for each channel that the user requests data from.  For example, if the user requests data from channels 0,1, and 7; this single cycle loop will run 3 times.  Each time the loop runs, it writes a single sample into the analog input DMA FIFO.  The next iteration waits at the “Loop Timer” until it is time to acquire the next data point.

Once the “AI Enable” boolean goes false, the data acquisition stops and control is transferred to the outer loop which waits until “AI Enable” goes high again and the acquisition will start over.  If at any point, the AI FIFO is full when we try to write to it, we terminate the data acquisition and set the “AI Buffer Overflow?” indicator to true.  Also, each time we write data to the AI FIFO, we increment a counter by one.  We do this so we know exactly how much data has been put in the buffer and the host VI can adequately flush the buffer between finite acquisitions.

Analog Output


[+] Enlarge Image
Figure 2: Analog Output Loop

Just like the Analog Input loop, the outer while loop simply polls the “AO Enable” boolean.  Once this boolean goes high, the analog output operation will start.  The inner while loop is what actually controls the analog output operation.  This loop consists of a flat sequence structure with two frames.  The first frame of the sequence structure simply sets the loop rate such that the loop will execute at the appropriate output frequency that the user selects.

The second frame of the sequence structure reads one entry out of the DMA FIFO for each channel that the user selects as a buffered output channel.  For example, if the user selects that they are using analog output channels 0,1, and 7; this while loop will run 3 times and put each value into the appropriate slot in an 8 element array.

The next segment of logic after this loop may look complicated, but is really quite simple.  We start off by converting the “AO Buffer Enable” input into an array of 8 booleans.  Each boolean in this array corresponds to one of the 8 analog output channels.  For example, a TRUE in element zero of this array indicates that AO channel 0 is configured as a buffered channel and we should output the data from the AO FIFO for that channel.  If a FALSE is in element zero of this array, this means that AO channel 0 is configured as a software timed (non-buffered) channel.  If a channel is configured a non-buffered (FALSE) then we should simply output the value in the corresponding control for that channel (“AO 0” in this example).  The logic in this section of code simply looks at the “AO Buffer Enable” boolean for the given channel and if TRUE, it routes the value from the FIFO read to the channel (through the Select function), if FALSE it routes the value of the corresponding channel control to the output.

The analog output operation stops if the user sets the “AO Enable” boolean to FALSE or if a buffer underflow condition occurs.  After this loop exits, the code waits for “AO Enable” to go false (in the case that it was a buffer underflow) and then clears out the AO FIFO by reading from the FIFO until it is empty.  For this logic to work, the host VI must guarantee that after “AO Enable” is set to false, it will no longer put new data points into the AO DMA FIFO until after the next analog output operation.

Once the analog output operation is over, the outer loop takes control again and polls the “AO Enable” boolean until it goes high again and the next analog output operation starts.

Counters


[+] Enlarge Image
Figure 3: Counter Loop

In this example personality there are 4 independent counters.  Each of these counters is implemented in LabVIEW FPGA with identical loops.

Like all of the loops we have looked at so far, the counter loop starts with an outer loop that simply polls the “Counter 0:Enable” boolean.  Once this boolean goes true, the counter operation starts.  The counter consists of a single cycle timed loop which executes once for each tick of the 40MHz internal clock.  Inside this single cycle loop, most of the work of this counter is done in the “Advanced Counter Sub” subvi.  The host program simply has to supply some inputs to the counter which determines how the counter operates.  These parameters are as follows:

Counter 0: Initial Count – Controls what the starting value of the counter is when the counter operation starts. Counter 0: Ticks to Filter – This input allows the user to apply a digital filter to the input signal of the counter.   For example, and value of 5 tells the counter to not count a signal as high until the signal has been high for 5 consecutive ticks of the 40MHz clock. Similarly, once the signal registers as high, it will not switch back to low until the signal has been low for 5 consecutive clock ticks.  Any value greater than 1 will filter the input signal and can be used as a debouncing filter.
Counter 0:Edge – Specifies which edge to count on.  Values include “Rising Edge”, “Falling Edge”, and “Rising AND Falling Edge”.
Counter 0:Count Direction – Controls whether the counter counts “Up” or “Down”.
Counter 0:Enable HW Gate – Tells the counter whether to gate the signal with the physical signal attached to the gate of the counter.  If this is true the counter will only count if the physical gate signal is high.  If this input is false, the counter acts like it is always gated.
Counter 0:Reset Counter – This input tells the counter to reset itself.  When you reset the counter, it sets the counter value back to the “Counter 0:Initial Count” and resets the counter filter's count register (which keeps track of how long a signal has been in the current state).  This “Counter 0:Reset Counter” input effectively stops the counter operation and immediately restarts it.

The outputs of the “Advanced Counter Sub” are the current counter value and the “Counter Reset” signal.  “Counter Reset” is high if the counter was reset by the “Advanced Counter Sub” VI.  If this is the case, we manually set the “Counter 0:Reset Counter” input to false.  This is to prevent the counter from being reset continuously until the user manually un-sets the “Counter 0:Reset Counter” input.

Once the “Counter 0:Enable” signal goes false, we exit the single cycle loop and the outer loop starts polling the “Counter 0:Enable” input again waiting for it to go high.  When “Counter 0:Enable” goes high again, the counter is first reset and then it starts counting again.

Digital Input and Output Ports


Figure 4: Digital I/O Loop

The Digital Input and Output loop is by far the simplest loop in the entire FPGA code.  This loop simply reads the five, 8-bit ports of digital inputs and writes them to five separate indicators.  It also takes the values of five, 8-bit controls and writes these to five outputs.  The loop itself runs continuously as fast as it can without stopping.

Host Examples

Of course, to use the FPGA personality, we need a host that knows how to communicate to the FPGA VI.  As a part of this personality, we have included several host Vis which each illustrate a different functionality of this personality.  In this section, we will go through all of the example hosts and specify how they are used and generally what is going on in the block diagram.

Analog Input

Cont Acq&Graph Voltage-Int Clk.vi


[+] Enlarge Image
Figure 5: Cont Acq&Graph Voltage-Int Clk.vi Front Panel


[+] Enlarge Image
Figure 6: Cont Acq&Graph Voltage-Int Clk.vi Block Diagram

This example illustrates how to do a simple continuous analog acquisition.  The front panel of this VI is very similar to an analogous DAQmx VI.  You simply have to select the RIO VISA Resource Name (usually “RIO0::INSTR”), the channels you want to read from, the sampling rate, and the number of samples to read from the buffer at once.

If you look at the block diagram, the first thing that we do is open a reference to the FPGA VI.  This effectively downloads the FPGA code to your R-series board and starts running.  After this, we set the depth of the host side DMA FIFO.  In this example, we are setting the depth to 32767 elements.  This means that the buffer that resides on our host PC will be large enough to store 32767 samples (all channels are counted in this total).

Next, we start the DMA process by calling “AI FIFO: Start”.  This ensures that as soon as the FPGA stars acquiring samples, they will be transferred from the FPGA memory to the host memory in the background.  After this, we set the AI Loop timer to specify how fast we want to acquire data and we set the “AI Channel Enable” to tell the FPGA which of the eight AI Channels we want to read from.  Finally, we set “AI Enable” to true start our acquisition.

Inside the loop we read the specified number of samples from the FIFO and feed these samples into the “AI Data to Array” sub VI.  This sub VI decimates the 1D array that comes out of the FIFO and builds an appropriate 2D array to be fed into the waveform graph.  Also, in this loop we are checking to see if there has been a buffer overflow and also retrieving the actual loop rate that the FPGA is running at.  The application stops if one of three conditions occurs; the user clicks the stop button, there is a buffer overflow, or there is some other error that occurs.

Once the main loop stops we close the reference to the FPGA and reset the FPGA (stopping the FPGA VI).  Finally, we display any errors that may have occurred to the user.

Acq&Graph Voltage-Int Clk-Retrigger


[+] Enlarge Image
Figure 7: Acq&Graph Voltage-Int Clk-Retrigger Front Panel


[+] Enlarge Image
Figure 8: Acq&Graph Voltage-Int Clk-Retrigger Block Diagram

The “Acq&Graph Voltage-Int Clk-Retrigger” example is much like the previous example except instead of acquiring voltage samples continuously, we acquire a finite amount of samples each time the “Trigger” button is pressed.

Once the reference to the FPGA VI is opened and the FPGA VI is running, we go into our main loop.  This main loop consists of one event structure that waits for the “Trigger” button to be pressed.  Once this button is pressed, we set up the parameters for the acquisition and then read in the specified number of points from the AI FIFO.

The interesting part of this code is what happens after we read in all of the data points and set “AI Enable” to false to stop the data acquisition.  After this we go into the “Flush FIFO” loop.  This loop goes through and reads any extra data that may have been written to the FIFO that we want to clear out of the FIFO before the next iteration occurs.  After we flush out the FIFO, we return to the main loop and wait for the trigger button to be pressed again.  Once the user clicks the stop button, we exit the loop and close out the reference to the FPGA (which stops execution of the FPGA code).

Analog Output

Gen Mult Voltage Update.vi


[+] Enlarge Image
Figure 9: Gen Mult Voltage Update.vi Front Panel


[+] Enlarge Image
Figure 10: Gen Mult Voltage Update.vi Block Diagram

The “Gen Mult Voltage Updates” host example shows the simplest possible use case for analog output with this FPGA personality.  After opening up the reference to the FPGA VI and running it, we simply set “AO Enable” to true and specify a loop speed for the analog output loop on the FPGA.  Once we enter the main loop, we simply calibrate the data in the “AO Channels” array and then write the data to the AO controls on the FPGA.

Cont Gen Voltage Wfm-Int Clk-Non Regeneration


[+] Enlarge Image
Figure 11: Cont Gen Voltage Wfm-Int Clk-Non Regeneration Front Panel


[+] Enlarge Image
Figure 12: Cont Gen Voltage Wfm-Int Clk-Non Regeneration Block Diagram

The “Cont Gen Voltage Wfm-Int Clk-Non Regeneration” example is a more complex example that demonstrates the hardware timed analog output capabilities of the FPGA personality.  In this example we first open a reference to the FPGA VI without running it.  We then set the analog output loop timer and the “AO Buffer Enable”.  If you remember from the previous sections, the “AO Buffer Enable” input is what tells the FPGA code which channels to treat as buffered (hardware timed) outputs and which outputs to treat as static (software timed) outputs.  We then set “AO Enable” to TRUE.  Normally, this would start our analog output on the FPGA but since our FPGA code isn't actually running yet, the analog output operation does not start.

The next thing that we do is generate some samples of a given waveform type and write it to the AO FIFO.  We do this so that there is already some data in the FIFO when the FPGA starts running.  If we waited to write data to the FIFO until after we started the FPGA VI, we would most likely run into buffer under run issues with the FPGA trying to read from the FIFO before we put data in it.

Once we have some initial data in the FIFO, we call the “Run” method on the FPGA to start the FPGA code running.  Since we have already set the “AO Enable” to TRUE, the analog output will start as soon as we call this method.  Inside the while loop, we are simply monitoring the actual loop rate and feeding more data into the analog output FIFO.   In this particular example, the same waveform is fed into all 8 channels.  Once the user clicks the stop button, the loop exits and the FPGA reference is closed out.

Counter


Figure 13: Count Digital Events.vi Front Panel


[+] Enlarge Image
Figure 14: Count Digital Events.vi Front Panel

The “Count Digital Events” host is designed to show to use the counters on this FPGA personality.  We first start by opening a reference to the FPGA code and running it.  After this we set the parameters of the counter (initial count, ticks to filter, etc...).  Finally we set “Counter 0:Enable” to TRUE and the counter operation starts.

We then go into the main while loop.  This loop simply reads the value of the counter and allows the user to reset the counter value.  After the user clicks stop, the FPGA reference is closed and the application finishes.

Digital IO

Write Dig Chan.vi


[+] Enlarge Image
Figure 15: Write Dig Chan.vi Front Panel


[+] Enlarge Image
Figure 16: Write Dig Chan.vi Block Diagram

The “Write Dig Chan” host VI illustrates how to do some simple digital output using this FPGA personality.  On the block diagram, we are simply opening the FPGA reference and running the FPGA VI.  We then go into the main loop and write the values of the “Data to Write” control into Connector 2:DIO Port 0.  These writes happen 10 times per second.  After clicking the stop button, the FPGA reference is closed and the FPGA VI stops.

Read Dig Chan.vi


[+] Enlarge Image
Figure 17: Read Dig Chan.vi Front Panel


[+] Enlarge Image
Figure 18: Read Dig Chan.vi Block Diagram

The “Read Dig Chan” example shows how to use the digital input capabilities of this FPGA personality.  We simply open a reference to the FPGA VI and start the FPGA code running.  After this we go into our main loop and read from the digital ports 10 times per second.  After the user clicks the stop button, we exit the loop and close out the reference to the FPGA.

Conclusion

This Balanced I/O example DAQ personality is intended to show what is possible with R Series Intelligent DAQ Devices and LabVIEW FPGA.  No other device offers 8 analog inputs, 8 analog outputs, 4 simple event counters (with debounce filters), 40 digital input lines and 40 digital output lines, all on a single piece of hardware.  To use this pre-compiled personality, the LabVIEW FPGA module is not necessary, and the NI-RIO driver is the only driver necessary.  Any modifications to the FPGA code, however, must be made using LabVIEW FPGA.

To download this example personality and its accompanying host VIs, go to the Balanced I/O Example DAQ Personality Download page.

Customize Your DAQ Device

National Instruments LabVIEW FPGA Module

R Series Intelligent DAQ Devices

What Can I Do With LabVIEW FPGA?

Advanced Data Acquisition Techniques with Intelligent DAQ

1 ratings | 5.00 out of 5
Print | PDF

Reader Comments | Submit a comment »

 

Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).