0374 Data Acquisition in C
0374 Data Acquisition in C
0374 Data Acquisition in C
blog
Data Acquisition in C#
Hans-Petter Halvorsen
Data Acquisition in C#
Hans-Petter Halvorsen
Copyright © 2017
E-Mail: hans.p.halvorsen@usn.no
Web: https://www.halvorsen.blog
https://www.halvorsen.blog
Table of Contents
1 Introduction ........................................................................................................................ 6
4 Table of Contents
8 Discretization .................................................................................................................... 46
9 OPC .................................................................................................................................... 56
1 Introduction
In this Tutorial we will learn how to create DAQ (Data Acquisition) applications in Visual
Studio and C#. We will use a USB-6008 DAQ device from National Instruments as an
example. In order to use DAQ devices from National Instruments in C# and Visual Studio we
need to NI-DAQmx driver provides by National Instruments. As part of this installation you
can install a .NET API. We will use this API to create a simple DAQ application. In addition, we
will use Measurement Studio which is an add-on to Visual Studio which makes it easier to
create more advanced DAQ applications.
In this Tutorial we end up with a control application. We will send and read data to a DAQ
device, and we will create our own discrete PID controller, low-pass filter and a discrete
model of our system. We will also read and write data to an OPC server.
You will find this document and lots of other information in the following web site:
https://www.halvorsen.blog/documents/programming/csharp/
For more information about Visual Studio and C#, visit the following web page:
https://www.halvorsen.blog/documents/programming/csharp/
7 Introduction
We will give code examples of how to use this device in C#. Since this is a DAQmx supported
device from National Instruments, the programing structure will be the same as for NI USB-
6008.
The NI USB-6008 is well suited for education purposes due to its small size and easy USB
connection.
1.2.3 myDAQ
NI myDAQ is a simple and intuitive DAQ device from National Instruments. NI myDAQ have
Analog Inputs (AI), Analog Outputs (AO), Digital Inputs (DI) and Digital Outputs (DO).
Specifications:
• Two Differential Analog Input and Analog Output Channels (200 ks/s, 16 bit, +/- 10
Volts)
• Eight Digital Input and Digital Output Lines (3.3 Volt TTL-Compatible)
• +5 , +15, and -15 Volt Power Supply Outputs (up to 500m Watts of Power)
• 60 Volt Digital Multimeter (DMM) for Measuring Voltage, Current, and Resistance
In addition to traditional I/O, the myDAQ have a built-in Digital Multimeter. The myDAQ can
also be used as a Power Supply. Using the built-in software the myDAQ can also be used as
an Oscilloscope and Function Generator.
When you plug in the device in the USB connection on your PC, the following will pop-up
automatically (NI ELVISmx Instrument Launcher):
Note! You need to install the NI ELVISmx driver software first
If you click on the DMM button, the built-in Digital Multimeter will appear:
Note! In order to install the DAQmx API for C#, make sure to select “.NET Support” when
installing the DAQmx driver.
This application uses the C# API included in the NI DAQmx driver, so make sure that you
have installed the NI DAQmx driver in advance.
Next, make sure that you select .NET Framework X.x Support for the version of .NET that
your version of Visual Studio is using:
2 Data Acquisition
2.1 Introduction
The purpose of data acquisition is to measure an electrical or physical phenomenon such as
voltage, current, temperature, pressure, or sound. PC-based data acquisition uses a
combination of modular hardware, application software, and a computer to take
measurements. While each data acquisition system is defined by its application
requirements, every system shares a common goal of acquiring, analyzing, and presenting
information. Data acquisition systems incorporate signals, sensors, actuators, signal
conditioning, data acquisition devices, and application software.
The DAQ system has the following parts involved, see Figure:
[Figure: www.ni.com]
13
14 Data Acquisition
• Driver software
• Your software application (Application software)
• Analog input
• Analog output
• Digital I/O
• Counter/timers
• “Desktop DAQ devices” where you need to plug a PCI DAQ board into your
computer. The software is running on a computer.
• “Portable DAQ devices” for connection to the USB port, Wi-Fi connections, etc. The
software is running on a computer
• “Distributed DAQ devices” where the software is developed on your computer and
then later downloaded to the distributed DAQ device.
[Figure: www.ni.com]
[Figure: www.ni.com]
• Real-time monitoring
• Data analysis
• Data logging
• Control algorithms
• Human machine interface (HMI)
In order to create your DAQ application you need a programming development tool, such as
Visual Studio/C#, LabVIEW, etc..
In addition to the standard tools, MAX can expose item-specific tools you can use to
configure, diagnose, or test your system, depending on which NI products you install. As you
navigate through MAX, the contents of the application menu and toolbar change to reflect
these new tools.
2.3.1 NI-DAQmx
National Instruments provides a native .NET API for NI-DAQmx. This is available as a part of
the NI-DAQmx driver and does not require Measurement Studio.
In general, data acquisition programming with DAQmx involves the following steps:
Data acquisition in text based-programming environment is very similar to the LabVIEW NI-
DAQmx programming as the functions calls is the same as the NI-DAQmx VI’s.
http://zone.ni.com/devzone/cda/tut/p/id/5409#toc4
2.3.2 Examples
Examples installed as part of NI-DAQmx:
The location of examples will depend on the version of Visual Studio and is listed in the
following Developer Zone Article: Using NI-DAQmx in Text Based Programming
Environments. The most common location is:
C:\Documents and Settings\All Users\Documents\National Instruments\NI-DAQ\Examples\DotNET<.NET Framework Version>\
Note! If the paths above do not exist, be sure you have .NET support installed for NI-DAQmx.
3.1 Introduction
This application uses the C# API included in the NI DAQmx driver, so make sure that you
have installed the NI DAQmx driver in advance. You don’t need Measurement Studio to
create this application.
We will create the following application in Visual Studio 2010 and C#:
19
20 My First DAQ App
The User Interface looks like this:
We start by connecting the Analog In and Analog Out wires together (a so called Loopback
test).
When we click the “Write Data” button, the value entered in the text box “Analog Out” will
be written to the DAQ device. If we have connected the Analog In and Analog Out wires
together we will read the same value in the “Analog In” textbox when we push the “Get
Data” button.
3.2 Example
We will go through the different parts of the code in detail.
• NationalInstruments.Common
• NationalInstruments.DAQmx
When we have added the necessary References, the Solution Explorer will look like this:
3.2.2 Initialization
We need to add the following Namespaces:
using NationalInstruments;
using NationalInstruments.DAQmx;
AOChannel myAOChannel;
myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);
double analogDataOut;
analogDataOut = Convert.ToDouble(txtAnalogOut.Text);
writer.WriteSingleSample(true, analogDataOut);
3.2.4 Analog In
We implement the code for reading data from the Analog In channel in the Event Handler for
the “Get Data” button:
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);
txtAnalogIn.Text = analogDataIn.ToString();
3.2.5 Error?
If your application runs without error that’s fine, but perhaps you get the following error:
In order to fix the problem, open the Properties for your project:
Make sure to select “.NET Framework X” in the “Target framework” drop-down menu.
4.1 Example
We will create the following simple application:
24
25 Temperature Logging
• NationalInstruments.Common
• NationalInstruments.DAQmx
When we have added the necessary References, the Solution Explorer will look like this:
The dlls are normally to find here:
4.1.2 Initialization
We need to add the following Namespaces:
using NationalInstruments;
using NationalInstruments.DAQmx;
namespace TC01_DAQ_Example
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
AIChannel myAIChannel;
myAIChannel = temperatureTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);
txtTempData.Text = analogDataIn.ToString();
}
}
}
4.1.5 Error?
If your application runs without error that’s fine, but perhaps you get the following error:
In order to fix the problem, open the Properties for your project:
Make sure to select “.NET Framework X” in the “Target framework” drop-down menu.
5 Measurement Studio
5.1 Introduction
C# is a powerful programming language, but has few built-in features for measurement and
control applications. Measurement Studio is an add-on to Visual Studio which makes it
easier to create such applications. With Measurement Studio we can implement Data
Acquisition and a graphical HMI.
[Figure: www.ni.com]
• Managed .NET controls for creating rich Web and Windows GUIs
• Multithreaded API for data acquisition
28
29 Measurement Studio
[Figure: www.ni.com]
5.2 Templates
Measurement Studio has several Templates that make it easier to build DAQ applications.
5.3 Toolbox
Below we see the Toolbox in Visual Studio that is installed with Measurement Studio:
In addition to the Toolbox, Measurement Studio also installs the following menu item:
Next we select the Class Libraries we want to include. In our case we need at least to select
the “DAQmx Library”.
When we click “Finish” an empty project will be created for us. We are now ready to create
our own application.
When we click the “Read Temp” button, the Temperature data shall be shown in the “Temp
Data” TextBox.
In the event Handler for the “Read Temp” button, we create the following code:
private void btnReadTempData_Click(object sender, EventArgs e)
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);
txtTempData.Text = analogDataIn.ToString();
We drag in a Timer component from the Toolbox. First, we need to start the Timer:
public Form1()
{
InitializeComponent();
timer1.Start();
}
Next, we need to specify the interval. We can do that in the Properties window:
In the Timer Event we write the code for reading the Temperature:
private void timer1_Tick(object sender, EventArgs e)
{
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);
txtTempData.Text = analogDataIn.ToString("0.0");
In addition we will use a Pt-100 sensor that we connect to one of the Analog Input channels
on the USB-6008 device:
The Output from this device is between 1-5V that illustrates a temperature between 0 and
100 degrees Celsius.
The procedure and code is identical as the previous example, except a small part as shown
below:
private void timer1_Tick(object sender, EventArgs e)
{
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
1,
5,
AIVoltageUnits.Volts
);
txtTempData.Text = analogDataIn.ToString("0.0");
6 Control Application
6.1 Introduction to the Example
In this example we will use Measurement Studio to create a simple control application. We
will control the level in a water tank using manual control. The process is as follows:
In this example we will use a small-scale laboratory process called LM-900 Level System:
37
38 Control Application
We want to control the level in the water tank using a pump on the inflow. We will read the
level using our USB-6008 DAQ device (Analog In) and write the control signal (Analog Out) to
the DAQ device.
The Analog Out (control signal) will be a signal between 0 − 5𝑉 and the Analog In (Level)
will be a 0 − 5𝑉 signal that we need to scale to 0 − 20𝑐𝑚.
We will use a “Slider” to manually adjust the control signal and a Tank to indicate the level in
the real process.
In this example we will use the “Slide” control and “Tank” control that comes with
Measurement Studio.
6.2 Coding
Start a New Project in Visual Studio:
Select the “NI Windows Application” Template in the “Measurement Studio” node.
In the window that appears next, select the Libraries you want to include:
We create the User Interface above in Visual Studio, and it looks like this:
For the read and write operations we have created a simple Class with two methods:
public class DaqData
{
{
...
}
}
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);
return analogDataIn;
}
AOChannel myAOChannel;
myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);
writer.WriteSingleSample(true, analogDataOut);
In the Properties window we can specify the Interval (“Sampling Time”) in milliseconds.
We can start the timer with the following code:
public Form1()
{
InitializeComponent();
timer1.Start();
}
In the Timer Event we create the main logic in our application. We call the ReadDaqData()
and WriteDaqData() methods, updates the GUI, etc.
private void timer1_Tick(object sender, EventArgs e)
{
//Read Data
double analogDataIn;
analogDataIn = myDaqData.ReadDaqData();
if (analogDataIn < 0)
analogDataIn = 0;
if (analogDataIn > 5)
analogDataIn = 5;
//Scaling:
analogDataIn = analogDataIn * 4; //0-5V -> 0-20cm
tank.Value = analogDataIn;
txtLevelValue.Text = analogDataIn.ToString("0.00");
//Write Data
double analogDataOut;
analogDataOut = sliderControl.Value;
myDaqData.WriteDaqData(analogDataOut);
7 Trending Data
Now we want to extend our application with functionality for viewing historical data using a
trend plot.
In this example we will use the “WaveformGraph” control in Measurement Studio.
The source code is the same as in the previous example, except for one new line of code in
the Timer Event:
waveformGraph.PlotYAppend(analogDataIn);
The “WaveformGraph” control has lots of functionality you can set in the Properties window
or clicking the Smart Tag Anchor (little arrow in the upper right corner of the control).
Below we see the Properties window (left side) and the Smart Tag Panel (right side) for the
WaveformGraph control:
44
45 Trending Data
8 Discretization
The next improvements to our application would be to implement a Low-pass Filter in order
to remove the noise from the signal when reading the level. Another improvement would be
to replace the manual control with a PI controller that do the job for us. Finally it would be
nice to have a mathematical model of our water tank so we can simulate and test the
behavior of the real system without connect to it.
So we need to create discrete versions of the low-pass filter, the PI controller and the
process model. We can, e.g., use the Euler Forward discretization method:
𝑥*+, − 𝑥*
𝑥≈
𝑇.
𝑦(𝑠) 1
𝐻 𝑠 = =
𝑢(𝑠) 𝑇8 𝑠 + 1
Where 𝑇8 is the time-constant of the filter, 𝑢(𝑠) is the filter input and 𝑦 𝑠 is the filter
output.
Discrete version:
𝒚𝒌 = 𝟏 − 𝒂 𝒚𝒌/𝟏 + 𝒂𝒖𝒌
Where
𝑻𝒔
𝒂=
𝑻𝒇 + 𝑻𝒔
46
47 Discretization
It is a golden rule that 𝑇. ≪ 𝑇8 and in practice we should use the following rule:
𝑇8
𝑇. ≤
5
Proof:
Given:
𝑦 1
=
𝑢 𝑇8 𝑠 + 1
This gives:
𝑇8 𝑠 + 1 𝑦 = 𝑢
𝑇8 𝑠𝑦 + 𝑦 = 𝑢
𝑇8 𝑦 + 𝑦 = 𝑢
DE /DEFG
We use the Euler Backward discretization method, 𝑥 ≈ , which gives:
HI
𝑦* − 𝑦*/,
𝑇8 + 𝑦* = 𝑢*
𝑇.
Then we get:
𝑇8 𝑦* − 𝑦*/, + 𝑦* 𝑇. = 𝑢* 𝑇.
𝑇8 𝑦* − 𝑇8 𝑦*/, + 𝑦* 𝑇. = 𝑢* 𝑇.
𝑦* (𝑇8 + 𝑇. ) = 𝑇8 𝑦*/, + 𝑢* 𝑇.
This gives:
𝑇8 𝑇.
𝑦* = 𝑦*/, + 𝑢
𝑇8 + 𝑇. 𝑇8 + 𝑇. *
𝑇.
≡ 𝑎
𝑇8 + 𝑇.
This gives:
𝑦* = (1 − 𝑎)𝑦*/, + 𝑎𝑢*
𝑇.
𝑎=
𝑇8 + 𝑇.
[End of Proof]
8.2 PI Controller
A PI controller may be written:
U
𝐾P
𝑢 𝑡 = 𝑢N + 𝐾P 𝑒 𝑡 + 𝑒𝑑𝜏
𝑇R N
𝑒 𝑡 = 𝑟 𝑡 − 𝑦(𝑡)
Laplace:
𝐾P
𝑢 𝑠 = 𝐾P 𝑒 𝑠 + 𝑒 𝑠
𝑇R 𝑠
Discrete version:
We start with:
U
𝐾P
𝑢 𝑡 = 𝑢N + 𝐾P 𝑒 𝑡 + 𝑒𝑑𝜏
𝑇R N
In order to make a discrete version using, e.g., Euler, we can derive both sides of the
equation:
𝐾P
𝑢 = 𝑢N + 𝐾P 𝑒 + 𝑒
𝑇R
Then we get:
𝑲𝒑
𝒖𝒌 = 𝒖𝒌/𝟏 + 𝒖𝟎,𝒌 − 𝒖𝟎,𝒌/𝟏 + 𝑲𝒑 𝒆𝒌 − 𝒆𝒌/𝟏 + 𝑻𝒆
𝑻𝒊 𝒔 𝒌
Where
𝑒* = 𝑟* − 𝑦*
∆𝑢* = 𝑢* − 𝑢*/,
𝒆𝒌 = 𝒓𝒌 − 𝒚𝒌
𝑲𝒑
∆𝒖𝒌 = 𝒖𝟎,𝒌 − 𝒖𝟎,𝒌/𝟏 + 𝑲𝒑 𝒆𝒌 − 𝒆𝒌/𝟏 + 𝑻𝒆
𝑻𝒊 𝒔 𝒌
𝒖𝒌 = 𝒖𝒌/𝟏 + ∆𝒖𝒌
𝐾P
𝑢 𝑠 = 𝐾P 𝑒 𝑠 + 𝑒 𝑠
𝑇R 𝑠
,
We set 𝑧 = 𝑒 ⇒ 𝑠𝑧 = 𝑒 ⇒ 𝑧 = 𝑒
.
This gives:
𝑧 = 𝑒
𝐾P
𝑢 = 𝐾P 𝑒 + 𝑧
𝑇R
Where
𝑒 = 𝑟 − 𝑦
Discrete version:
Using Euler:
𝑧*+, − 𝑧*
𝑧≈
𝑇.
This gives:
𝑧*+, − 𝑧*
= 𝑒*
𝑇.
𝐾P
𝑢* = 𝐾P 𝑒* + 𝑧
𝑇R *
Finally:
𝒆𝒌 = 𝒓𝒌 − 𝒚𝒌
𝑲𝒑
𝒖𝒌 = 𝑲𝒑 𝒆𝒌 + 𝒛
𝑻𝒊 𝒌
𝒛𝒌+𝟏 = 𝒛𝒌 + 𝑻𝒔 𝒆𝒌
A very simple (linear) model of the water tank is as follows:
𝐴U ℎ = 𝐾P 𝑢−𝐹efU
or
1
ℎ= 𝐾 𝑢−𝐹efU
𝐴U P
Where:
We can use the Euler Forward discretization method in order to create a discrete model:
𝑥*+, − 𝑥*
𝑥≈
𝑇.
Then we get:
ℎ*+, − ℎ* 1
= 𝐾 𝑢 −𝐹
𝑇. 𝐴U P * efU
Finally:
𝑻𝒔
𝒉𝒌+𝟏 = 𝒉𝒌 + 𝑲 𝒖 −𝑭
𝑨𝒕 𝒑 𝒌 𝒐𝒖𝒕
Below we see the Project and Solution in Visual Studio:
Below we will show and describe the important parts of the code.
PI Controller:
We create a new Class for our PID algorithm, by right-click in the Solution Explorer
(Add→New Item…)
The Add New Item window appears:
Select the Class Item and a proper Name, e.g. “PidController”.
//PID Algoritm
e = r - y;
u = Kp * e + (Kp / Ti) * z;
z = z + Ts * e;
return u;
}
controllerOutput = sliderControl.Value;
}
else // Use PID Control
{
controllerOutput = pidControl.PiController(levelMeasurement);
//Scaling
controllerOutput = controllerOutput / 4; //0-20cm -> 0-5V
//Set boundaries
if (controllerOutput < 0)
controllerOutput = 0;
if (controllerOutput > 5)
controllerOutput = 5;
}
Low-pass Filter:
double a;
double yFiltered;
a = Ts / (Ts + Tf);
yFiltered = (1 - a) * yk + a * yFromDaq;
yk = yFiltered;
return yFiltered;
}
}
Discrete Model:
We have created a Class and a LevelTankModel Method that we use in our simulation:
levelMeasurement = model.LevelTankModel(controllerOutput);
9 OPC
In order to communicate with an OPC Server we can use the DataSocket API that is part of
the Measurement Studio. We use the Matrikon OPC Simulation Server.
Code:
56
57 OPC
if (dataSocket.IsConnected)
dataSocket.Disconnect();
dataSocket.Connect(opcUrl, AccessMode.Read);
txtReadOpcValue.Text = dataSocket.Data.Value.ToString();
}
SelectUrl:
We can use the SelectUrl method if we want to pick the OPC item from a list of available
servers (both local servers and network servers) and items.
dataSocket.SelectUrl();
Below we will go through a very simple example. We will write one value to the OPC Server
each time we click a button.
Code:
if (dataSocket.IsConnected)
dataSocket.Disconnect();
dataSocket.Connect(opcUrl, AccessMode.Write);
double opcValue = 0;
opcValue = Convert.ToDouble(txtWriteOpcValue.Text);
dataSocket.Data.Value = opcValue;
dataSocket.Update();
}
In the Properties window we can specify the Interval (“Sampling Time”) in milliseconds.
timer1.Start();
}
In the Timer Event we create the code in order to read data at this specific interval.
…
…
10 Using Measurement
Studio Templates
In order to use the NI USB-TC01 Thermocouple Measurement device with C# we need to
have the DAQmx driver and the DAQmx API for C# installed. In order to install the DAQmx
API for C#, make sure to select “.NET Support” when installing the DAQmx driver.
C# is a powerful programming language, but has few built-in features for measurement and
control applications. Measurement Studio is an add-on to Visual Studio which makes it
easier to create such applications. With Measurement Studio we can implement Data
Acquisition and a graphical HMI.
You don’t need to use the Measurement Studio to create an application where you use the
NI USB-TC01 Thermocouple Measurement device, but it is easier.
Here we will use Visual Studio and the Measurement Studio Add-in to create some DAQ
examples where we get temperature data from the NI USB-TC01 Thermocouple
Measurement device.
62
63 Using Measurement Studio Templates
Note! The “New Project” window may look different on your computer, it depends on what
features you have installed and which version or edition of Measurement Studio you are
using.
Next we select the Class Libraries we want to include. In our case we need at least to select
the “DAQmx Library”.
When we click “Finish” an empty project will be created for us. We are now ready to create
our own application.
When we click the “Read Temp” button, the Temperature data shall be shown in the “Temp
Data” TextBox.
In the event Handler for the “Read Temp” button, we create the following code:
private void btnReadTempData_Click(object sender, EventArgs e)
{
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);
txtTempData.Text = analogDataIn.ToString();
We drag in a Timer component from the Toolbox. First, we need to start the Timer:
public Form1()
{
InitializeComponent();
timer1.Start();
}
Next, we need to specify the interval. We can do that in the Properties window:
In the Timer Event we write the code for reading the Temperature:
private void timer1_Tick(object sender, EventArgs e)
{
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);
txtTempData.Text = analogDataIn.ToString("0.0");
We start by creating a “New Project” from Visual Studio. In the “New Project” window we
select “Visual C#” » “Measurement Studio”, and then select the “NI DAQ Windows
Application” Template that is part of the Measurement Studio.
Note! The “New Project” window may look different on your computer, it depends on what
features you have installed and which version or edition of Measurement Studio you are
using.
In the next step we select the measurement type, and since the NI USB-TC01 Thermocouple
Measurement device is for reading Temperature values, we need to select “Acquire Signals”.
In the “Acquire Signals” node we first select “Temperature” and then select
“Thermocouple”.
Next we need to select the physical channel(s). Since the NI USB-TC01 Thermocouple
Measurement device has only one channel available, we need to select “ai0” (Analog In,
Channel 0).
Next we can set different Properties, such as “Input Range”, “Acquisition Mode”,
“Thermocouple Type”, etc.
Finally we see a Preview of the User Interface before it is automatically generated by the
Measurement Studio:
When we click “Finish”, the Solution, the Project and User Interface will be automatically
created.
Figure 1: Visual Studio Generated Solution
With this approach we get a “flying start” and we can change the code as we please. The
drawback with this approach is that the code that is automatically generated is a little bit
“messy”.
namespace MyFirstDAQApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);
txtAnalogIn.Text = analogDataIn.ToString();
72
73 Appendix A: Source Code
AOChannel myAOChannel;
myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);
double analogDataOut;
analogDataOut = Convert.ToDouble(txtAnalogOut.Text);
writer.WriteSingleSample(true, analogDataOut);
}
}
Control Application
The code for this application is as follows:
using NationalInstruments;
using NationalInstruments.DAQmx;
using NationalInstruments.UI;
using NationalInstruments.UI.WindowsForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Control_Application
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Start();
}
//Read Data
double analogDataIn;
analogDataIn = myDaqData.ReadDaqData();
if (analogDataIn < 0)
analogDataIn = 0;
if (analogDataIn > 5)
analogDataIn = 5;
//Scaling:
analogDataIn = analogDataIn * 4; //0-5V -> 0-20cm
tank.Value = analogDataIn;
txtLevelValue.Text = analogDataIn.ToString("0.00");
//Write Data
double analogDataOut;
analogDataOut = sliderControl.Value;
myDaqData.WriteDaqData(analogDataOut);
/// <summary>
/// Reading and Writing Data from DAQ Device
/// </summary>
public class DaqData
{
AIChannel myAIChannel;
myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);
return analogDataIn;
}
AOChannel myAOChannel;
myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);
writer.WriteSingleSample(true, analogDataOut);
}
}
namespace OPC_Read
{
public partial class Form1 : Form
{
DataSocket dataSocket = new DataSocket();
public Form1()
{
InitializeComponent();
string opcUrl;
opcUrl = "opc://localhost/MATRIKON.OPC.Simulation/Bucket Brigade.Real4";
if (dataSocket.IsConnected)
dataSocket.Disconnect();
dataSocket.Connect(opcUrl, AccessMode.Read);
}
dataSocket.Update();
txtReadOpcValue.Text = dataSocket.Data.Value.ToString();
}
}
}
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace OPC_Write
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string opcUrl;
opcUrl = "opc://localhost/MATRIKON.OPC.Simulation/Bucket Brigade.Real4";
if (dataSocket.IsConnected)
dataSocket.Disconnect();
dataSocket.Connect(opcUrl, AccessMode.Write);
}
double opcValue = 0;
opcValue = Convert.ToDouble(txtWriteOpcValue.Text);
dataSocket.Data.Value = opcValue;
dataSocket.Update();
}
}
}
Data Acquisition in C#
Hans-Petter Halvorsen
Copyright © 2017
E-Mail: hans.p.halvorsen@usn.no
Web: https://www.halvorsen.blog
https://www.halvorsen.blog