Programming using DAQ functions
Many National instrument devices such as PXI, SCXI, PCI/PCIe, USB use NI DAQmx drivers and library functions within labview to achieve data acquisition and generation. The most common I/O is Digital Inputs, Digital Outputs, Analogue Inputs, Analogue Outputs and Counter channels. In this article, I would briefly go through some of the good practices that could be used using DAQ functions.
If all you need is to switch on relay or a lamp based on some logic rather than high frequency discrete generation then keep it as simple as possible. From programming perspective, think of a block that you can insert, wire output reference and corresponding discrete value of ‘True’ or ‘False’. Here is how simplified Digital Output Update vi should look like on the code diagram.
Drop-down daq reference automatically populates with all I/O available in NI Max. I can use same vi as many times as i want on code diagram and use drop down to select different digital outputs. I can switch the chosen output on or off based on discrete value wired.
‘If all you need is to switch on a lamp or relay then design vi so you create task, generate and close task on single execution of vi, Khurram Waris said.
Lets take a look at the block diagram of the above Digital Output Update vi. I have designed above vi as a state machine of three states: Initialize, Generate and Shutdown.
In the initialize state above, I simply pass Daq Channel reference to DAQ digital output function. After that, I am transitioning to state ‘Generate’.
In Generate state, I am using DAQ functions to write to output and then transitioning to Shutdown state.
In the shutdown state, I use DAQ mx Stop and Clear task to close current DAQ task and reference. In this state, connected ‘True’ to termination input. I have set state value to ‘Initialize’. So next time DO vi is run, it loads from initialize state. I would emphasise that for DO as well as DI, do not hesitate to keep opening reference and closing reference on every iteration of while loop. It is fine to do that as you are not required to do high speed generation and acquisition but simple on and off or status monitoring of switches through digital inputs.
For Analogue inputs, outputs, counter channels, I would still emphasise to keep Top Level Main vi code diagram to look simple. It should show one single vi doing analogue inputs. Module to do Analogue output and another one for Counters just as shown below.
Labview inherent multithread processing nature would run above vi in parallel manner and block diagram could not look more pleasent.
Analogue Input and Outputs
For Analogue input, I never use above method of open, generate, close in same iteration. I would use multiple channel acquisition in every iteration if possible. I would always create and start acquisition task and leave Analogue Input vi running continuously in ‘Acquire’ state until a Global Stop Condition requires me to transition to Stop state where I would close the task. Here is how I would design individual cases and state machine control.
In initialize state, I would use standard DAQ ‘Create Channel’ function to measure voltage and transition state machine to ‘Configure’ state once I have created all tasks i.e iteration value of while loop is 63 ( for 64 Analogue input acquisition).
In start state, I start the task and then move to ‘Acquire’ state.
In acquire state, I continuously acquire all 64 channel Analogue data and store them in a Functional Global Variable.
For Analogue Inputs, I keep my state machine in ‘Acquire’ state until Global Stop Command is set, Khurram Waris.
This article highlights few of the good, tried and tested practices of programming labview. I hope article is helpful. Any questions, then please drop me a line..