You are on page 1of 73

1e|emark Un|vers|ty Co||ege

ueparLmenL of LlecLrlcal Lnglneerlng, lnformaLlon 1echnology and CyberneLlcs


Faculty of Technology, Postboks 203, Kjlnes ring 56, N-3901 Porsgrunn, Norway. Tel: +47 35 57 50 00 Fax: +47 35 57 54 01





uaLa AcqulslLlon ln C#
PAnS-L11L8 PALvC8SLn, 2014.03.10


2


1able of ConLenLs
1 lnLroducLlon ........................................................................................................................ 3
1.1 vlsual SLudlo ................................................................................................................ 3
1.2 uAC Pardware ............................................................................................................. 6
1.2.1 nl uS8 1C-01 1hermocouple uevlce ..................................................................... 7
1.2.2 nl uS8-6008 uAC uevlce ...................................................................................... 7
1.2.3 myuAC .................................................................................................................. 8
1.3 nl uACmx drlver .......................................................................................................... 9
1.4 MeasuremenL SLudlo ................................................................................................. 10
2 uaLa AcqulslLlon ................................................................................................................ 12
2.1 lnLroducLlon ............................................................................................................... 12
2.1.1 hyslcal lnpuL/ouLpuL slgnals .............................................................................. 13
2.1.2 uAC devlce/hardware ........................................................................................ 13
2.1.3 urlver sofLware ................................................................................................... 14
2.1.4 ?our sofLware appllcaLlon ................................................................................... 14
2.2 MAx - MeasuremenL and AuLomaLlon Lxplorer ....................................................... 13
2.3 uAC ln vlsual SLudlo .................................................................................................. 16
2.3.1 nl-uACmx ........................................................................................................... 16
2.3.2 Lxamples ............................................................................................................. 17
3 My llrsL uAC App ............................................................................................................. 18
3.1 lnLroducLlon ............................................................................................................... 18
3.2 Source Code ............................................................................................................... 19
3 1able of ConLenLs
1uLorlal: uaLa AcqulslLlon ln C#
4 1emperaLure Logglng Lxample ......................................................................................... 22
3 MeasuremenL SLudlo ........................................................................................................ 26
3.1 lnLroducLlon ............................................................................................................... 26
3.2 1emplaLes .................................................................................................................. 27
3.3 1oolbox ...................................................................................................................... 27
3.4 Lxample ..................................................................................................................... 28
6 ConLrol AppllcaLlon ........................................................................................................... 33
6.1 lnLroducLlon ............................................................................................................... 33
6.2 Source Code ............................................................................................................... 34
7 1rendlng uaLa ................................................................................................................... 40
8 ulscreLlzaLlon .................................................................................................................... 42
8.1 Low-pass lllLer ........................................................................................................... 42
8.2 l ConLroller ............................................................................................................... 44
8.2.1 l ConLroller as a SLaLe-space model .................................................................. 43
8.3 rocess Model ........................................................................................................... 46
8.4 llnal AppllcaLlon ........................................................................................................ 47
9 CC ................................................................................................................................... 32
9.1 8ead CC uaLa ........................................................................................................... 32
9.2 WrlLe CC uaLa .......................................................................................................... 34
9.3 uslng a 1lmer ............................................................................................................. 36
10 uslng nl 1C-01 ln vlsual SLudlo and C# ........................................................................... 38
10.1 CreaLe a nl Wlndows AppllcaLlon ............................................................................ 38
10.2 CreaLe a nl uAC Wlndows AppllcaLlon ................................................................... 62
Appendlx A: Source Code ........................................................................................................ 68
My llrsL uAC App ............................................................................................................... 68
ConLrol AppllcaLlon ............................................................................................................. 69
4 1able of ConLenLs
1uLorlal: uaLa AcqulslLlon ln C#
10.3 CC 8ead ................................................................................................................. 71
10.4 CC WrlLe ................................................................................................................ 71


3

1 lnLroducLlon
ln Lhls 1uLorlal we wlll learn how Lo creaLe uAC (uaLa AcqulslLlon) appllcaLlons ln vlsual
SLudlo and C#. We wlll use a uS8-6008 uAC devlce from naLlonal lnsLrumenLs as an
example. ln order Lo use uAC devlces from naLlonal lnsLrumenLs ln C# and vlsual SLudlo we
need Lo nl-uACmx drlver provldes by naLlonal lnsLrumenLs. As parL of Lhls lnsLallaLlon you
can lnsLall a .nL1 Al. We wlll use Lhls Al Lo creaLe a slmple uAC appllcaLlon. ln addlLlon we
wlll use MeasuremenL SLudlo whlch ls an add-on Lo vlsual SLudlo whlch makes lL easler Lo
creaLe more advanced uAC appllcaLlons.
ln Lhls 1uLorlal we end up wlLh a conLrol appllcaLlon. We wlll send and read daLa Lo a uAC
devlce, and we wlll creaLe our own dlscreLe lu conLroller, low-pass fllLer and a dlscreLe
model of our sysLem. We wlll also read and wrlLe daLa Lo an CC server.
?ou wlll flnd Lhls documenL and loLs of oLher lnformaLlon ln Lhe followlng web slLe:
http:]]home.h|t.no]~hansha]?tutor|a|=csharp_daq
1.1 vlsual SLudlo
MlcrosofL vlsual SLudlo ls an lnLegraLed developmenL envlronmenL (luL) from MlcrosofL. lL
can be used Lo develop console and graphlcal user lnLerface appllcaLlons along wlLh
Wlndows lorms appllcaLlons, web slLes, web appllcaLlons, and web servlces ln boLh naLlve
code LogeLher wlLh managed code for all plaLforms supporLed by MlcrosofL Wlndows,
Wlndows hone, Wlndows CL, .nL1 lramework, .nL1 CompacL lramework and MlcrosofL
SllverllghL.
lor more lnformaLlon abouL vlsual SLudlo and C#, vlslL Lhe followlng web page:
http:]]home.h|t.no]~hansha]?tutor|a|=csharp
8elow we see Lhe lnLegraLed developmenL envlronmenL (luL) ln vlsual SLudlo:
6 lnLroducLlon
1uLorlal: uaLa AcqulslLlon ln C#


new pro[ecLs are creaLed from Lhe new ro[ecL" wlndow:

1.2 uAC Pardware
ln Lhls 1uLorlal we wlll use dlfferenL hardware avalllble from naLlonal lnsLrumenLs as
examples:
7 lnLroducLlon
1uLorlal: uaLa AcqulslLlon ln C#
1C-01 1hermocouple devlce
uS8-6008 uAC uevlce
MyuAC
1.2.1 nl uS8 1C-01 1hermocouple uevlce
8elow we see Lhe nl uS8-1C01 1hermocouple MeasuremenL devlce.


We wlll glve code examples of how Lo use Lhls devlce ln C#. Slnce Lhls ls a uACmx supporLed
devlce from naLlonal lnsLrumenLs, Lhe programlng sLrucLure wlll be Lhe same as for nl
uS8-6008. We wlll use Lhe nl uS8-1C01 devlce ln ChapLer 10 - uslng nl 1C-01 ln vlsual SLudlo
and C#.
1.2.2 nl uS8-6008 uAC uevlce
nl uS8-6008 ls a slmple and low-cosL mulLlfuncLlon l/C devlce from naLlonal lnsLrumenLs.

1he devlce has Lhe followlng speclflcaLlons:
8 analog lnpuLs (12-blL, 10 kS/s)
8 lnLroducLlon
1uLorlal: uaLa AcqulslLlon ln C#
2 analog ouLpuLs (12-blL, 130 S/s)
12 dlglLal l/C
uS8 connecLlon, no exLra power-supply neeeded
CompaLlble wlLh LabvlLW, LabWlndows/Cvl, and MeasuremenL SLudlo for vlsual
SLudlo .nL1
nl-uACmx drlver sofLware
1he nl uS8-6008 ls well sulLed for educaLlon purposes due Lo lLs small slze and easy uS8
connecLlon.
1.2.3 myuAC
nl myuAC ls a slmple and lnLulLlve uAC devlce from naLlonal lnsLrumenLs. nl myuAC have
Analog lnpuLs (Al), Analog CuLpuLs (AC), ulglLal lnpuLs (ul) and ulglLal CuLpuLs (uC).

SpeclflcaLlons:
1wo ulfferenLlal Analog lnpuL and Analog CuLpuL Channels (200 ks/s, 16 blL, +/- 10
volLs)
LlghL ulglLal lnpuL and ulglLal CuLpuL Llnes (3.3 volL 11L-CompaLlble)
+3 , +13, and -13 volL ower Supply CuLpuLs (up Lo 300m WaLLs of ower)
60 volL ulglLal MulLlmeLer (uMM) for Measurlng volLage, CurrenL, and 8eslsLance
ln addlLlon Lo LradlLlonal l/C, Lhe myuAC have a bullL-ln D|g|ta| Mu|t|meter. 1he myuAC can
also be used as a ower Supp|y. uslng Lhe bullL-ln sofLware Lhe myuAC can also be used as
an Csc|||oscope and Iunct|on Generator.
When you plug ln Lhe devlce ln Lhe uS8 connecLlon on your C, Lhe followlng wlll pop-up
auLomaLlcally (nl LLvlSmx lnsLrumenL Launcher):
9 lnLroducLlon
1uLorlal: uaLa AcqulslLlon ln C#

noLe! ?ou need Lo lnsLall Lhe nl LLvlSmx drlver sofLware flrsL
lf you cllck on Lhe uMM buLLon, Lhe bullL-ln ulglLal MulLlmeLer wlll appear:

1.3 nl uACmx drlver
naLlonal lnsLrumenLs provldes a naLlve .nL1 Al for nl-uACmx. 1hls ls avallable as a parL of
Lhe nl-uACmx drlver and does noL requlre MeasuremenL SLudlo.
Note! ln order Lo lnsLall Lhe uACmx Al for C#, make sure Lo selecL .nL1 SupporL" when
lnsLalllng Lhe uACmx drlver.
1hls appllcaLlon uses Lhe C# Al lncluded ln Lhe nl uACmx drlver, so make sure LhaL you
have lnsLalled Lhe nl uACmx drlver ln advance.
uurlng Lhe lnsLallaLlon makesure Lo selecL CusLom":
10 lnLroducLlon
1uLorlal: uaLa AcqulslLlon ln C#

nexL, make sure LhaL you selecL .nL1 lramework x.x SupporL for Lhe verslon of .nL1 LhaL
yourverslon of vlsual SLudlo ld uslng:

1.4 MeasuremenL SLudlo
11 lnLroducLlon
1uLorlal: uaLa AcqulslLlon ln C#
C# ls a powerful programmlng language, buL has few bullL-ln feaLures for measuremenL and
conLrol appllcaLlons. MeasuremenL SLudlo ls an add-on Lo vlsual SLudlo whlch makes lL
easler Lo creaLe such appllcaLlons. WlLh MeasuremenL SLudlo we can lmplemenL uaLa
AcqulslLlon and a graphlcal PMl.

12

2 uaLa AcqulslLlon
2.1 lnLroducLlon
1he purpose of daLa acqulslLlon ls Lo measure an elecLrlcal or physlcal phenomenon such as
volLage, currenL, LemperaLure, pressure, or sound. C-based daLa acqulslLlon uses a
comblnaLlon of modular hardware, appllcaLlon sofLware, and a compuLer Lo Lake
measuremenLs. Whlle each daLa acqulslLlon sysLem ls deflned by lLs appllcaLlon
requlremenLs, every sysLem shares a common goal of acqulrlng, analyzlng, and presenLlng
lnformaLlon. uaLa acqulslLlon sysLems lncorporaLe slgnals, sensors, acLuaLors, slgnal
condlLlonlng, daLa acqulslLlon devlces, and appllcaLlon sofLware.
So summlng up, uaLa AcqulslLlon ls Lhe process of:
Acqulrlng slgnals from real-world phenomena
ulglLlzlng Lhe slgnals
Analyzlng, presenLlng and savlng Lhe daLa
1he uAC sysLem has Lhe followlng parLs lnvolved, see llgure:

1he parLs are:
hyslcal lnpuL/ouLpuL slgnals
uAC devlce/hardware
urlver sofLware
?our sofLware appllcaLlon (AppllcaLlon sofLware)
13 uaLa AcqulslLlon
1uLorlal: uaLa AcqulslLlon ln C#
lor an lnLroducLlon Lo uaLa AcqulslLlon, see Lhls webcasL:
http:]]zone.n|.com]wv]app]doc]p]|d]wv-169
2.1.1 hyslcal lnpuL/ouLpuL slgnals
A physlcal lnpuL/ouLpuL slgnal ls Lyplcally a volLage or currenL slgnal.
2.1.2 uAC devlce/hardware
uAC hardware acLs as Lhe lnLerface beLween Lhe compuLer and Lhe ouLslde world. lL
prlmarlly funcLlons as a devlce LhaL dlglLlzes lncomlng analog slgnals so LhaL Lhe compuLer
can lnLerpreL Lhem
A uAC devlce (uaLa AcqulslLlon Pardware) usually has Lhese funcLlons:
Analog lnpuL
Analog ouLpuL
ulglLal l/C
CounLer/Llmers
We have dlfferenL uAC devlces, such as:
Desktop uAC devlces" where you need Lo plug a Cl uAC board lnLo your
compuLer. 1he sofLware ls runnlng on a compuLer.
ortab|e uAC devlces" for connecLlon Lo Lhe uS8 porL, Wl-ll connecLlons, eLc. 1he
sofLware ls runnlng on a compuLer
D|str|buted uAC devlces" where Lhe sofLware ls developed on your compuLer and
Lhen laLer downloaded Lo Lhe dlsLrlbuLed uAC devlce.

14 uaLa AcqulslLlon
1uLorlal: uaLa AcqulslLlon ln C#


2.1.3 urlver sofLware
urlver sofLware ls Lhe layer of sofLware for easlly communlcaLlng wlLh Lhe hardware. lL forms
Lhe mlddle layer beLween Lhe appllcaLlon sofLware and Lhe hardware. urlver sofLware also
prevenLs a programmer from havlng Lo do reglsLer-level programmlng or compllcaLed
commands ln order Lo access Lhe hardware funcLlons.
urlver sofLware from naLlonal lnsLrumenLs: nl-uACmx
2.1.4 ?our sofLware appllcaLlon
13 uaLa AcqulslLlon
1uLorlal: uaLa AcqulslLlon ln C#
AppllcaLlon sofLware adds analysls and presenLaLlon capablllLles Lo Lhe drlver sofLware. ?our
sofLware appllcaLlon normally does such Lasks as:
8eal-Llme monlLorlng
uaLa analysls
uaLa logglng
ConLrol algorlLhms
Puman machlne lnLerface (PMl)
ln order Lo creaLe your uAC appllcaLlon you need a programmlng developmenL Lool, such as
vlsual SLudlo/C#, LabvlLW, eLc..
2.2 MAx - MeasuremenL and AuLomaLlon
Lxplorer
MeasuremenL & AuLomaLlon Lxplorer (MAx) provldes access Lo your naLlonal lnsLrumenLs
devlces and sysLems.
WlLh MAx, you can:
Conflgure your naLlonal lnsLrumenLs hardware and sofLware
CreaLe and edlL channels, Lasks, lnLerfaces, scales, and vlrLual lnsLrumenLs
LxecuLe sysLem dlagnosLlcs
vlew devlces and lnsLrumenLs connecLed Lo your sysLem
updaLe your naLlonal lnsLrumenLs sofLware
ln addlLlon Lo Lhe sLandard Lools, MAx can expose lLem-speclflc Lools you can use Lo
conflgure, dlagnose, or LesL your sysLem, dependlng on whlch nl producLs you lnsLall. As you
navlgaLe Lhrough MAx, Lhe conLenLs of Lhe appllcaLlon menu and Loolbar change Lo reflecL
Lhese new Lools.
16 uaLa AcqulslLlon
1uLorlal: uaLa AcqulslLlon ln C#


2.3 uAC ln vlsual SLudlo
We can creaLe uAC appllcaLlons wlLh or wlLhouL MeasuremenL SLudlo. ln boLh slLuaLlons you
need Lhe nl-uACmx drlver llbrary.
2.3.1 nl-uACmx
naLlonal lnsLrumenLs provldes a naLlve .nL1 Al for nl-uACmx. 1hls ls avallable as a parL of
Lhe nl-uACmx drlver and does noL requlre MeasuremenL SLudlo.
ln general, daLa acqulslLlon programmlng wlLh uACmx lnvolves Lhe followlng sLeps:
17 uaLa AcqulslLlon
1uLorlal: uaLa AcqulslLlon ln C#
CreaLe a 1ask and vlrLual Channels
SLarL Lhe 1ask
erform a 8ead operaLlon from Lhe uAC
erform a WrlLe operaLlon Lo Lhe uAC
SLop and Clear Lhe 1ask.
uaLa acqulslLlon ln LexL based-programmlng envlronmenL ls very slmllar Lo Lhe LabvlLW
nl-uACmx programmlng as Lhe funcLlons calls ls Lhe same as Lhe nl-uACmx vl's.
uslng nl-uACmx ln 1exL 8ased rogrammlng LnvlronmenLs:
http:]]zone.n|.com]devzone]cda]tut]p]|d]S409#toc4
2.3.2 Lxamples
Lxamples lnsLalled as parL of nl-uACmx:
1he locaLlon of examples wlll depend on Lhe verslon of vlsual SLudlo and ls llsLed ln Lhe
followlng ueveloper Zone ArLlcle: uslng nl-uACmx ln 1exL 8ased rogrammlng
LnvlronmenLs. 1he mosL common locaLlon ls:
C:\uocumenLs and SeLLlngs\All users\uocumenLs\naLlonal lnsLrumenLs\nl-uAC\Lxamples\uoLnL1<.nL1 lramework verslon>\
newesL examples for .nL1 x.x and vlsual SLudlo 20xx:
C:\uocumenLs and SeLLlngs\All users\uocumenLs\naLlonal lnsLrumenLs\nl-uAC\Lxamples\uoLnL1x.x\
Sub-folders named CS conLaln C# examples. 1hese examples lnsLall wlLh nl-uACmx.
MeasuremenL SLudlo ls noL requlred Lo lnsLall Lhe class llbrarles or Lhe examples.
Note! lf Lhe paLhs above do noL exlsL, be sure you have .nL1 supporL lnsLalled for nl-uACmx.


18

3 My llrsL uAC App
We wlll creaLe a slmple appllcaLlon ln vlsual SLudlo LhaL uses a nl uS8-6008 uAC devlce.

3.1 lnLroducLlon
1hls appllcaLlon uses Lhe C# Al lncluded ln Lhe nl uACmx drlver, so make sure LhaL you
have lnsLalled Lhe nl uACmx drlver ln advance. ?ou don'L need MeasuremenL SLudlo Lo
creaLe Lhls appllcaLlon.
SLarL vlsual SLudlo and creaLe a new Wlndows lorms appllcaLlon.
We wlll creaLe Lhe followlng appllcaLlon ln vlsual SLudlo 2010 and C#:

19 My llrsL uAC App
1uLorlal: uaLa AcqulslLlon ln C#
1he user lnLerface looks llke Lhls:

We sLarL by connecLlng Lhe Analog ln and Analog CuL wlres LogeLher (a so called Loopback
LesL).
When we cllck Lhe WrlLe uaLa" buLLon, Lhe value enLered ln Lhe LexL box Analog CuL" wlll
be wrlLLen Lo Lhe uAC devlce. lf we have connecLed Lhe Analog ln and Analog CuL wlres
LogeLher we wlll read Lhe same value ln Lhe Analog ln" LexLbox when we push Lhe CeL
uaLa" buLLon.
3.2 Source Code
We wlll go Lhrough Lhe dlfferenL parLs of Lhe code ln deLall.
keferences:
1hls appllcaLlon uses Lhe C# Al lncluded ln Lhe nl uACmx drlver, so make sure LhaL you
have lnsLalled Lhe nl uACmx drlver ln advance.
We need Lo add Lhe followlng Assembly references:
naLlonallnsLrumenLs.Common
naLlonallnsLrumenLs.uACmx

We add 8eferences by rlghL-cllcklng Lhe 8eferences node ln Lhe SoluLlon Lxplorer:
20 My llrsL uAC App
1uLorlal: uaLa AcqulslLlon ln C#

When we have added Lhe necessary 8eferences, Lhe SoluLlon Lxplorer wlll look llke Lhls:

In|t|a||zat|on:
We need Lo add Lhe followlng namespaces:
using NationalInstruments;
using NationalInstruments.DAQmx;

Ana|og Cut:
We lmplemenL Lhe code for wrlLlng Lo Lhe Analog CuL channel ln Lhe LvenL Pandler for Lhe
WrlLe uaLa" buLLon:
private void btnWriteAnalogOut_Click(object sender, EventArgs e)
{

Task analogOutTask = new Task();

AOChannel myAOChannel;

myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
21 My llrsL uAC App
1uLorlal: uaLa AcqulslLlon ln C#
);

AnalogSingleChannelWriter writer = new
AnalogSingleChannelWriter(analogOutTask.Stream);

double analogDataOut;

analogDataOut = Convert.ToDouble(txtAnalogOut.Text);

writer.WriteSingleSample(true, analogDataOut);

}

Ana|og In:
We lmplemenL Lhe code for readlng daLa from Lhe Analog ln channel ln Lhe LvenL Pandler for
Lhe CeL uaLa" buLLon:
private void btnGetAnalogIn_Click(object sender, EventArgs e)
{

Task analogInTask = new Task();

AIChannel myAIChannel;

myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);

AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();

txtAnalogIn.Text = analogDataIn.ToString();

}


22

4 1emperaLure Logglng
Lxample
ln Lhls example we wlll use a nl 1C-01 uS8 1hermocouple devlce.

We vlll creaLe Lhe followlng slmple appllcaLlon:

Add keference:
We need Lo add Lhe followlng Assembly references:
naLlonallnsLrumenLs.Common
naLlonallnsLrumenLs.uACmx
We add 8eferences by rlghL-cllcklng Lhe 8eferences node ln Lhe SoluLlon Lxplorer:
23 1emperaLure Logglng Lxample
1uLorlal: uaLa AcqulslLlon ln C#

When we have added Lhe necessary 8eferences, Lhe SoluLlon Lxplorer wlll look llke Lhls:

1he dlls are normally Lo flnd here:

In|t|a||zat|on:
We need Lo add Lhe followlng namespaces:
24 1emperaLure Logglng Lxample
1uLorlal: uaLa AcqulslLlon ln C#
using NationalInstruments;
using NationalInstruments.DAQmx;
Add Code:
LnLer Lhe followlng code llnes:
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;
using NationalInstruments;
using NationalInstruments.DAQmx;

namespace TC01_DAQ_Example
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}


private void btnGetData_Click(object sender, EventArgs e)
{
Task temperatureTask = new Task();

AIChannel myAIChannel;

myAIChannel = temperatureTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);


AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(temperatureTask.Stream);

double analogDataIn = reader.ReadSingleSample();

txtTempData.Text = analogDataIn.ToString();

}
}
}
1est your app||cat|on:
8un your appllcaLlon. When cllcklng Lhe buLLon, you should now reLrleve daLa from Lhe
LemoeraLure devlce.
Lrror?
lf your appllcaLlon runs wlLhouL error LhaL's flne, buL perhaps you geL Lhe followlng error:
23 1emperaLure Logglng Lxample
1uLorlal: uaLa AcqulslLlon ln C#

ln order Lo flx Lhe problem, open Lhe roperLles for your pro[ecL:

Make sure Lo selecL .nL1 lramework x" ln Lhe 1argeL framework" drop-down menu.

26

3 MeasuremenL SLudlo
3.1 lnLroducLlon

C# ls a powerful programmlng language, buL has few bullL-ln feaLures for measuremenL and
conLrol appllcaLlons. MeasuremenL SLudlo ls an add-on Lo vlsual SLudlo whlch makes lL
easler Lo creaLe such appllcaLlons. WlLh MeasuremenL SLudlo we can lmplemenL uaLa
AcqulslLlon and a graphlcal PMl.


MeasuremenL SLudlo for vlsual C# .nL1 provldes:
Managed .nL1 conLrols for creaLlng rlch Web and Wlndows Culs
MulLlLhreaded Al for daLa acqulslLlon
lnsLrumenL conLrol Als
Analysls llbrarles deslgned for englneers and sclenLlsLs
27 MeasuremenL SLudlo
1uLorlal: uaLa AcqulslLlon ln C#

3.2 1emplaLes
MeasuremenL SLudlo has several 1emplaLes LhaL make lL easler Lo bulld uAC appllcaLlons.

3.3 1oolbox
8elow we see Lhe 1oolbox ln vlsual SLudlo LhaL ls lnsLalled wlLh MeasuremenL SLudlo:
28 MeasuremenL SLudlo
1uLorlal: uaLa AcqulslLlon ln C#


ln addlLlon Lo Lhe 1oolbox, MeasuremenL SLudlo also lnsLalls Lhe followlng menu lLem:

3.4 Lxample
ln Lhls example, we wlll selecL Lhe nl wlndows AppllcaLlon" 1emplaLe ln Lhe new ro[ecL"
wlndow .
29 MeasuremenL SLudlo
1uLorlal: uaLa AcqulslLlon ln C#

nexL we selecL Lhe Class Llbrarles we wanL Lo lnclude. ln our case we need aL leasL Lo selecL
Lhe uACmx Llbrary".

When we cllck llnlsh" an empLy pro[ecL wlll be creaLed for us. We are now ready Lo creaLe
our own appllcaLlon.
We sLarL by creaLlng a slmple user lnLerface:
30 MeasuremenL SLudlo
1uLorlal: uaLa AcqulslLlon ln C#

When we cllck Lhe 8ead 1emp" buLLon, Lhe 1emperaLure daLa shall be shown ln Lhe 1emp
uaLa" 1exL8ox.
ln Lhe evenL Pandler for Lhe 8ead 1emp" buLLon, we creaLe Lhe followlng code:
private void btnReadTempData_Click(object sender, EventArgs e)
{

Task analogInTask = new Task();

AIChannel myAIChannel;

myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);


AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();

txtTempData.Text = analogDataIn.ToString();

}
1hen we can LesL our appllcaLlon:

31 MeasuremenL SLudlo
1uLorlal: uaLa AcqulslLlon ln C#
Improvements: We should use a "1|mer" ln order Lo read 1emperaLure daLa aL speclflc
lnLervals lnsLead of pushlng a buLLon each Llme we need daLa.

We drag ln a 1lmer componenL from Lhe 1oolbox. llrsL, we need Lo sLarL Lhe 1lmer:
public Form1()
{
InitializeComponent();

timer1.Start();
}
nexL, we need Lo speclfy Lhe lnLerval. We can do LhaL ln Lhe ropert|es wlndow:

ln Lhe 1lmer LvenL we wrlLe Lhe code for readlng Lhe 1emperaLure:
private void timer1_Tick(object sender, EventArgs e)
{

Task analogInTask = new Task();


AIChannel myAIChannel;


myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);


AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();


txtTempData.Text = analogDataIn.ToString("0.0");

}
llnally, we LesL Lhe appllcaLlon:
32 MeasuremenL SLudlo
1uLorlal: uaLa AcqulslLlon ln C#





33

6 ConLrol AppllcaLlon
6.1 lnLroducLlon
ln Lhls example we wlll use MeasuremenL SLudlo Lo creaLe a slmple conLrol appllcaLlon. We
wlll conLrol Lhe level ln a waLer Lank uslng manual conLrol. 1he process ls as follows:

We wanL Lo conLrol Lhe level ln Lhe waLer Lank uslng a pump on Lhe lnflow. We wlll read Lhe
level uslng our uS8-6008 uAC devlce (Analog ln) and wrlLe Lhe conLrol slgnal (Analog CuL) Lo
Lhe uAC devlce.
1he Analog CuL (conLrol slgnal) wlll be a slgnal beLween ! !!! and Lhe Analog ln (Level)
wlll be a ! !!! slgnal LhaL we need Lo scale Lo ! !!"!".
We wlll creaLe Lhe followlng appllcaLlon:
34 ConLrol AppllcaLlon
1uLorlal: uaLa AcqulslLlon ln C#

We wlll use a Sllder" Lo manually ad[usL Lhe conLrol slgnal and a 1ank Lo lndlcaLe Lhe level ln
Lhe real process.
ln Lhls example we wlll use Lhe Sllde" conLrol and 1ank" conLrol LhaL comes wlLh
MeasuremenL SLudlo.

6.2 Source Code
SLarL a new ro[ecL ln vlsual SLudlo:
33 ConLrol AppllcaLlon
1uLorlal: uaLa AcqulslLlon ln C#

SelecL Lhe nl Wlndows AppllcaLlon" 1emplaLe ln Lhe MeasuremenL SLudlo" node.
ln Lhe wlndow LhaL appears nexL, selecL Lhe Llbrarles you wanL Lo lnclude:

We creaLe Lhe user lnLerface above ln vlsual SLudlo, and lL looks llke Lhls:
36 ConLrol AppllcaLlon
1uLorlal: uaLa AcqulslLlon ln C#


lor Lhe read and wrlLe operaLlons we have creaLed a slmple Class wlLh Lwo meLhods:
public class DaqData
{

public double ReadDaqData()
{
...
}


public void WriteDaqData(double analogDataOut)
{
...
}
}

More abouL Lhe keadDaqData() and Wr|teDaqData() meLhods below.
kead Leve|:
1he 8eaduaquaLa() meLhod handles Lhe loglc for readlng from Lhe uAC devlce:
public double ReadDaqData()
{

Task analogInTask = new Task();

AIChannel myAIChannel;

myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
37 ConLrol AppllcaLlon
1uLorlal: uaLa AcqulslLlon ln C#
AIVoltageUnits.Volts
);

AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();

return analogDataIn;
}

Wr|te Contro| Va|ue:
1he WrlLeuaquaLa() meLhod handles Lhe loglc for wrlLlng Lo Lhe uAC devlce:
public void WriteDaqData(double analogDataOut)
{

Task analogOutTask = new Task();

AOChannel myAOChannel;

myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);

AnalogSingleChannelWriter writer = new
AnalogSingleChannelWriter(analogOutTask.Stream);

writer.WriteSingleSample(true, analogDataOut);

}

1|mer:
ln Lhe prevlous example (My llrsL uAC App") we was readlng and wrlLlng Lo Lhe uAC devlce
when cllcklng a buLLon, buL ln an ordlnary appllcaLlon Lhls ls noL a good soluLlon. ln order Lo
read and wrlLe daLa on regular lnLervals we wlll use a 1lmer".
ln Lhe ComponenLs" Loolbox we flnd Lhe 1lmer" ConLrol:
38 ConLrol AppllcaLlon
1uLorlal: uaLa AcqulslLlon ln C#

ln Lhe roperLles wlndow we can speclfy Lhe lnLerval (Sampllng 1lme") ln mllllseconds.


We can sLarL Lhe Llmer wlLh Lhe followlng code:
public Form1()
{
InitializeComponent();

timer1.Start();
}

ln Lhe 1lmer LvenL we creaLe Lhe maln loglc ln our appllcaLlon. We call Lhe 8eaduaquaLa()
and WrlLeuaquaLa() meLhods, updaLes Lhe Cul, eLc.
private void timer1_Tick(object sender, EventArgs e)
{

DaqData myDaqData = new DaqData();

//Read Data
double analogDataIn;
39 ConLrol AppllcaLlon
1uLorlal: uaLa AcqulslLlon ln C#

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);

}


40

7 1rendlng uaLa
now we wanL Lo exLend our appllcaLlon wlLh funcLlonallLy for vlewlng hlsLorlcal daLa uslng a
Lrend ploL.
8elow we see Lhe new user lnLerface:

ln Lhls example we wlll use Lhe WaveformCraph" conLrol ln MeasuremenL SLudlo.
1he source code ls Lhe same as ln Lhe prevlous example, excepL for one new llne of code ln
Lhe 1lmer LvenL:
waveformGraph.PlotYAppend(analogDataIn);

1he WaveformCraph" conLrol has loLs of funcLlonallLy you can seL ln Lhe roperLles wlndow
or cllcklng Lhe SmarL 1ag Anchor (llLLle arrow ln Lhe upper rlghL corner of Lhe conLrol).

8elow we see Lhe roperLles wlndow (lefL slde) and Lhe SmarL 1ag anel (rlghL slde) for Lhe
WaveformCraph conLrol:
41 1rendlng uaLa
1uLorlal: uaLa AcqulslLlon ln C#





42

8 ulscreLlzaLlon
1he nexL lmprovemenLs Lo our appllcaLlon would be Lo lmplemenL a Low-pass lllLer ln order
Lo remove Lhe nolse from Lhe slgnal when readlng Lhe level. AnoLher lmprovemenL would be
Lo replace Lhe manual conLrol wlLh a l conLroller LhaL do Lhe [ob for us. llnally lL would be
nlce Lo have a maLhemaLlcal model of our waLer Lank so we can slmulaLe and LesL Lhe
behavlor of Lhe real sysLem wlLhouL connecL Lo lL.
So we need Lo creaLe dlscreLe verslons of Lhe low-pass fllLer, Lhe l conLroller and Lhe
process model. We can, e.g., use Lhe Luler lorward dlscreLlzaLlon meLhod:
! !
!
!!!
!!
!
!
!

or Lhe Luler 8ackward dlscreLlzaLlon meLhod:
! !
!
!
!!
!!!
!
!

!
!
ls Lhe Sampllng 1lme.
8.1 Low-pass lllLer
1he Lransfer funcLlon for a flrsL-order low-pass fllLer may be wrlLLen:
! ! !
!!!!
!!!!
!
!
!
!
! !!

Where !
!
ls Lhe Llme-consLanL of Lhe fllLer, !!!! ls Lhe fllLer lnpuL and ! ! ls Lhe fllLer
ouLpuL.
D|screte vers|on:
lL can be shown LhaL a dlscreLe verslon can be sLaLed as:
!
!
! ! !! !
!!!
!!!
!

Where
! !
!
!
!
!
!!
!

43 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
Where !
!
ls Lhe Sampllng 1lme.
lL ls a golden rule LhaL !
!
! !
!
and ln pracLlce we should use Lhe followlng rule:
!
!
!
!
!
!

roof:
Clven:
!
!
!
!
!
!
! !!

1hls glves:
!
!
! !! ! ! !
!
!
!" !! ! !
lnverse Laplace glves:
!
!
! !! ! !
We use Lhe Luler 8ackward dlscreLlzaLlon meLhod, ! !
!
!
!!
!!!
!
!
, whlch glves:
!
!
!
!
!!
!!!
!
!
!!
!
! !
!

1hen we geL:
!
!
!
!
!!
!!!
!!
!
!
!
! !
!
!
!

!
!
!
!
!!
!
!
!!!
!!
!
!
!
! !
!
!
!

!
!
!!
!
!!
!
! ! !
!
!
!!!
!!
!
!
!

1hls glves:
!
!
!
!
!
!
!
!!
!
!
!!!
!
!
!
!
!
!!
!
!
!

lor slmpllclLy we seL:
!
!
!
!
!!
!
! !
1hls glves:
!
!
! !! !!!!
!!!
!!!
!

44 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
! !
!
!
!
!
!!
!

[Lnd of roof]
8.2 l ConLroller
A l conLroller may be wrlLLen:
! ! ! !
!
!!
!
! ! !
!
!
!
!
!"#
!
!

Where ! ls Lhe conLroller ouLpuL and ! ls Lhe conLrol error:
! ! ! ! ! !!!!!
Laplace:
! ! ! !
!
! ! !
!
!
!
!
!
! !
D|screte vers|on:
We sLarL wlLh:
! ! ! !
!
!!
!
! ! !
!
!
!
!
!"#
!
!

ln order Lo make a dlscreLe verslon uslng, e.g., Luler, we can derlve boLh sldes of Lhe
equaLlon:
! ! !
!
!!
!
! !
!
!
!
!
!
lf we use Luler lorward we geL:
!
!
!!
!!!
!
!
!
!
!!!
!!
!!!!!
!
!
!!
!
!
!
!!
!!!
!
!
!
!
!
!
!
!
!

1hen we geL:
!
!
! !
!!!
!!
!!!
!!
!!!!!
!!
!
!
!
!!
!!!
!
!
!
!
!
!
!
!
!

Where
!
!
! !
!
!!
!

43 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
We can also spllL Lhe equaLlon above ln 2 dlfferenL pars by seLLlng:
!!
!
! !
!
!!
!!!

1hls glves Lhe followlng l conLrol algorlLhm:
!
!
! !
!
!!
!

!!
!
! !
!!!
!!
!!!!!
!!
!
!
!
!!
!!!
!
!
!
!
!
!
!
!
!

!
!
! !
!!!
!!!
!

1hls algorlLhm can easlly be lmplemenLed ln C#.
8.2.1 l ConLroller as a SLaLe-space model
Clven:
! ! ! !
!
! ! !
!
!
!
!
!
! !
We seL ! !
!
!
! ! !" ! ! ! ! ! !
1hls glves:
! ! !
! ! !
!
! !
!
!
!
!
!
Where
! ! ! !!
D|screte vers|on:
uslng Luler:
! !
!
!!!
!!
!
!
!

Where !
!
ls Lhe Sampllng 1lme.
1hls glves:
!
!!!
!!
!
!
!
! !
!

46 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
!
!
! !
!
!
!
!
!
!
!
!
!
!

llnally:
!
!
! !
!
!!
!

!
!
! !
!
!
!
!
!
!
!
!
!
!

!
!!!
! !
!
!!
!
!
!

1hls algorlLhm can easlly be lmplemenLed ln C#.
8.3 rocess Model
A very slmple (llnear) model of Lhe waLer Lank ls as follows:
!
!
! ! !
!
!!!
!"#

or
! !
!
!
!
!
!
!!!
!"#

Where:
! [cm] ls Lhe level ln Lhe waLer Lank
! [v] ls Lhe pump conLrol slgnal Lo Lhe pump
!
!
[cm2] ls Lhe cross-secLlonal area ln Lhe Lank
!
!
[(cm3/s)/v] ls Lhe pump galn
!
!"#
[cm3/s] ls Lhe ouLflow Lhrough Lhe valve (Lhls ouLflow can be modeled more
accuraLely Laklng lnLo accounL Lhe valve characLerlsLlc expresslng Lhe relaLlon
beLween pressure drop across Lhe valve and Lhe flow Lhrough Lhe valve).

We can use Lhe Luler lorward dlscreLlzaLlon meLhod ln order Lo creaLe a dlscreLe model:
! !
!
!!!
!!
!
!
!

1hen we geL:
!
!!!
!!
!
!
!
!
!
!
!
!
!
!
!
!!
!"#

47 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
llnally:
!
!!!
! !
!
!
!
!
!
!
!
!
!
!
!!
!"#

8.4 llnal AppllcaLlon
We exLend our ConLrol AppllcaLlon wlLh a dlscreLe l conLroller, a dlscreLe Low-pass fllLer
and a dlscreLe process model, so we can swlLch beLween Lhe real process and a slmulaLor.
Cur user lnLerface ls as follows:

8elow we see Lhe ro[ecL and SoluLlon ln vlsual SLudlo:
48 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#

8elow we wlll show and descrlbe Lhe lmporLanL parLs of Lhe code.
I Contro||er:
We creaLe a new Class for our lu algorlLhm, by rlghL-cllck ln Lhe SoluLlon Lxplorer
(Add-new lLem.)

1he Add new lLem wlndow appears:
49 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#

SelecL Lhe Class lLem and a proper name, e.g. ldConLroller".
1he |dContro||er Class ls as follows:
class PidController
{

public double r; //Reference Value
public double Kp; //Proportional Gain for PID Controler
public double Ti; //Integral Time for PID Controler
public double Ts; //Sampling Time

private double z; //Internal variable


public double PiController(double y)
{
double e; // Error between Reference and Measurement
double u; // Controller Output

//PID Algoritm
e = r - y;
u = Kp * e + (Kp / Ti) * z;
z = z + Ts * e;

return u;
}

}
We Lhen lnlLlallze Lhe ldConLroller Class:
PidController pidControl = new PidController
{
Ts=0.1,
r=5,
Kp=0.8,
Ti=15
};
llnally we use Lhe conLroller:
private void ControlSystem()
30 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
{

//Write Control Value

if (switchController.Value == true) //Use Manual Control
{

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;
}

myDaqData.WriteDaqData(controllerOutput); //Write to DAQ

}

Low-pass I||ter:
We creaLe Lhe Low-pass lllLer as a separaLe Class Lo:
class Filter
{

public double yk;
public double Ts;
public double Tf;


public double LowPassFilter(double yFromDaq)
{

double a;
double yFiltered;

a = Ts / (Ts + Tf);


yFiltered = (1 - a) * yk + a * yFromDaq;
yk = yFiltered;

return yFiltered;

}
}
We Lhen lnlLlallze Lhe fllLer:
Filter filter = new Filter
{
Ts = 0.1,
Tf = 2
};
llnally we use Lhe fllLer:
31 ulscreLlzaLlon
1uLorlal: uaLa AcqulslLlon ln C#
// Lowpass filtering the Measure Value due to noise
levelMeasurement = filter.LowPassFilter(levelMeasurement);

D|screte Mode|:
We do Lhe same for Lhe dlscreLe model.
We have creaLed a Class and a Level1ankModel MeLhod LhaL we use ln our slmulaLlon:
levelMeasurement = model.LevelTankModel(controllerOutput);




32

9 CC
ln order Lo communlcaLe wlLh an CC Server we can use Lhe uaLaSockeL Al LhaL ls parL of
Lhe MeasuremenL SLudlo. We use Lhe MaLrlkon CC SlmulaLlon Server.
9.1 8ead CC uaLa
8elow we wlll go Lhrough a very slmple example. We wlll read one value from Lhe CC
Server each Llme we cllck a buLLon.
V|sua| Stud|o ro[ect:

Code:
We deflne a uaLaSockeL ob[ecL:
DataSocket dataSocket = new DataSocket();
nexL, We ConnecL Lo Lhe CC Server:
string opcUrl;
opcUrl = "opc://localhost/MATRIKON.OPC.Simulation/Bucket Brigade.Real4";
33 CC
1uLorlal: uaLa AcqulslLlon ln C#

if (dataSocket.IsConnected)
dataSocket.Disconnect();

dataSocket.Connect(opcUrl, AccessMode.Read);
llnally, we 8ead CC uaLa:
private void btnReadOpc_Click(object sender, EventArgs e)
{
dataSocket.Update();

txtReadOpcValue.Text = dataSocket.Data.Value.ToString();
}


We LesL Lhe AppllcaLlon uslng Lhe MaLrlkon CC Lxplorer:


Se|ectUr|:
We can use Lhe Se|ectUr| meLhod lf we wanL Lo plck Lhe CC lLem from a llsL of avallable
servers (boLh local servers and neLwork servers) and lLems.
dataSocket.SelectUrl();
1he Se|ctUr| meLhod wlll pop up Lhe followlng wlndow:
34 CC
1uLorlal: uaLa AcqulslLlon ln C#

9.2 WrlLe CC uaLa
We use Lhe same uaLaSockeL Al here.
V|sua| Stud|o ro[ect:
8elow we wlll go Lhrough a very slmple example. We wlll wrlLe one value Lo Lhe CC Server
each Llme we cllck a buLLon.

33 CC
1uLorlal: uaLa AcqulslLlon ln C#
Code:
We deflne a uaLaSockeL ob[ecL:
DataSocket dataSocket = new DataSocket();
nexL, We ConnecL Lo Lhe CC Server:
string opcUrl;
opcUrl = "opc://localhost/MATRIKON.OPC.Simulation/Bucket Brigade.Real4";

if (dataSocket.IsConnected)
dataSocket.Disconnect();

dataSocket.Connect(opcUrl, AccessMode.Write);
llnally, we WrlLe CC uaLa:
private void btnWriteOpc_Click(object sender, EventArgs e)
{

double opcValue = 0;

opcValue = Convert.ToDouble(txtWriteOpcValue.Text);

dataSocket.Data.Value = opcValue;

dataSocket.Update();
}

We LesL Lhe AppllcaLlon uslng Lhe MaLrlkon CC Lxplorer:

36 CC
1uLorlal: uaLa AcqulslLlon ln C#
9.3 uslng a 1lmer
We can use a Llmer ln order Lo read values conLlnuously", l.e. aL speclflc lnLervals.
ln Lhe ComponenLs" Loolbox we flnd Lhe 1lmer" ConLrol:

ln Lhe roperLles wlndow we can speclfy Lhe lnLerval (Sampllng 1lme") ln mllllseconds.


We can sLarL Lhe Llmer wlLh Lhe followlng code:
public Form1()
{
InitializeComponent();

timer1.Start();
}

ln Lhe 1lmer LvenL we creaLe Lhe code ln order Lo read daLa aL Lhls speclflc lnLerval.
37 CC
1uLorlal: uaLa AcqulslLlon ln C#
private void timer1_Tick(object sender, EventArgs e)
{




}


38

10 uslng nl 1C-01 ln
vlsual SLudlo and C#
ln order Lo use Lhe nl uS8-1C01 1hermocouple MeasuremenL devlce wlLh C# we need Lo
have Lhe DAmx dr|ver and Lhe uACmx Al for C# lnsLalled. ln order Lo lnsLall Lhe uACmx
Al for C#, make sure Lo selecL .nL1 SupporL" when lnsLalllng Lhe uACmx drlver.
C# ls a powerful programmlng language, buL has few bullL-ln feaLures for measuremenL and
conLrol appllcaLlons. Measurement Stud|o ls an add-on Lo vlsual SLudlo whlch makes lL
easler Lo creaLe such appllcaLlons. WlLh MeasuremenL SLudlo we can lmplemenL uaLa
AcqulslLlon and a graphlcal PMl.
?ou don'L need Lo use Lhe MeasuremenL SLudlo Lo creaLe an appllcaLlon where you use Lhe
nl uS8-1C01 1hermocouple MeasuremenL devlce, buL lL ls easler.
Pere we wlll use vlsual SLudlo and Lhe MeasuremenL SLudlo Add-ln Lo creaLe some uAC
examples where we geL LemperaLure daLa from Lhe nl uS8-1C01 1hermocouple
MeasuremenL devlce.
10.1 CreaLe a nl Wlndows AppllcaLlon
ln Lhls example, we wlll selecL Lhe nl wlndows AppllcaLlon" 1emplaLe ln Lhe new ro[ecL"
wlndow.
39 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#

Note! 1he new ro[ecL" wlndow may look dlfferenL on your compuLer, lL depends on whaL
feaLures you have lnsLalled and whlch verslon or edlLlon of MeasuremenL SLudlo you are
uslng.
nexL we selecL Lhe Class Llbrarles we wanL Lo lnclude. ln our case we need aL leasL Lo selecL
Lhe uACmx Llbrary".

When we cllck llnlsh" an empLy pro[ecL wlll be creaLed for us. We are now ready Lo creaLe
our own appllcaLlon.
60 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#
We sLarL by creaLlng a slmple user lnLerface:

When we cllck Lhe 8ead 1emp" buLLon, Lhe 1emperaLure daLa shall be shown ln Lhe 1emp
uaLa" 1exL8ox.
ln Lhe evenL Pandler for Lhe 8ead 1emp" buLLon, we creaLe Lhe followlng code:
private void btnReadTempData_Click(object sender, EventArgs e)
{

Task analogInTask = new Task();

AIChannel myAIChannel;

myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);


AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();

txtTempData.Text = analogDataIn.ToString();

}
1hen we can LesL our appllcaLlon:

61 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#
Improvements: We should use a "1|mer" ln order Lo read 1emperaLure daLa aL speclflc
lnLervals lnsLead of pushlng a buLLon each Llme we need daLa.

We drag ln a 1lmer componenL from Lhe 1oolbox. llrsL, we need Lo sLarL Lhe 1lmer:
public Form1()
{
InitializeComponent();

timer1.Start();
}
nexL, we need Lo speclfy Lhe lnLerval. We can do LhaL ln Lhe ropert|es wlndow:

ln Lhe 1lmer LvenL we wrlLe Lhe code for readlng Lhe 1emperaLure:
private void timer1_Tick(object sender, EventArgs e)
{

Task analogInTask = new Task();


AIChannel myAIChannel;


myAIChannel = analogInTask.AIChannels.CreateThermocoupleChannel(
"Dev1/ai0",
"Temperature",
0,
100,
AIThermocoupleType.J,
AITemperatureUnits.DegreesC,
25
);


AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();


txtTempData.Text = analogDataIn.ToString("0.0");

}
llnally, we LesL Lhe appllcaLlon:
62 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#


10.2 CreaLe a nl uAC Wlndows AppllcaLlon
Note! 1hls opLlon ls only avalllble lf you Lo have elLher Lhe rofesslonal or LnLerprlse verslon
of Lhe MeasuremenL SLudlo sofLware.
We sLarL by creaLlng a new ro[ecL" from vlsual SLudlo. ln Lhe new ro[ecL" wlndow we
selecL vlsual C#" MeasuremenL SLudlo", and Lhen selecL Lhe nl uAC Wlndows
AppllcaLlon" 1emplaLe LhaL ls parL of Lhe MeasuremenL SLudlo.

Note! 1he new ro[ecL" wlndow may look dlfferenL on your compuLer, lL depends on whaL
feaLures you have lnsLalled and whlch verslon or edlLlon of MeasuremenL SLudlo you are
uslng.

nexL, we need Lo go Lhrough dlfferenL sLeps ln a wlzard.
ln Lhe flrsL sLep we selecL CreaLe a new pro[ecL Lask":
63 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#

ln Lhe nexL sLep we selecL Lhe measuremenL Lype, and slnce Lhe nl uS8-1C01 1hermocouple
MeasuremenL devlce ls for readlng 1emperaLure values, we need Lo selecL Acqulre Slgnals".

ln Lhe Acqulre Slgnals" node we flrsL selecL 1emperaLure" and Lhen selecL
1hermocouple".
64 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#

nexL we need Lo selecL Lhe physlcal channel(s). Slnce Lhe nl uS8-1C01 1hermocouple
MeasuremenL devlce has only one channel avallable, we need Lo selecL al0" (Analog ln,
Channel 0).

nexL we can seL dlfferenL roperLles, such as lnpuL 8ange", AcqulslLlon Mode",
1hermocouple 1ype", eLc.
63 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#


llnally we see a revlew of Lhe user lnLerface before lL ls auLomaLlcally generaLed by Lhe
MeasuremenL SLudlo:
66 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#

When we cllck llnlsh", Lhe SoluLlon, Lhe ro[ecL and user lnLerface wlll be auLomaLlcally
creaLed.

I|gure 1: V|sua| Stud|o Generated So|ut|on
llnally we can LesL Lhe AppllcaLlon:
67 uslng nl 1C-01 ln vlsual SLudlo and C#
1uLorlal: uaLa AcqulslLlon ln C#

WlLh Lhls approach we geL a flylng sLarL" and we can change Lhe code as we please. 1he
drawback wlLh Lhls approach ls LhaL Lhe code LhaL ls auLomaLlcally generaLed ls a llLLle blL
messy".
So acLually, Lhls ls noL a meLhod l wlll recommend Lo use.




68

Appendlx A: Source Code
ln Lhls Appendlx Lhe compleLe source code for all Lhe examples wlll be llsLed.
My llrsL uAC App
1he code for Lhls appllcaLlon ls 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 MyFirstDAQApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}


private void Form1_Load(object sender, EventArgs e)
{

}

private void btnGetAnalogIn_Click(object sender, EventArgs e)
{

Task analogInTask = new Task();


AIChannel myAIChannel;

myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);

AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();

txtAnalogIn.Text = analogDataIn.ToString();
69 Appendlx A: Source Code
1uLorlal: uaLa AcqulslLlon ln C#

}

private void btnWriteAnalogOut_Click(object sender, EventArgs e)
{


Task analogOutTask = new Task();

AOChannel myAOChannel;

myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);

AnalogSingleChannelWriter writer = new
AnalogSingleChannelWriter(analogOutTask.Stream);

double analogDataOut;

analogDataOut = Convert.ToDouble(txtAnalogOut.Text);

writer.WriteSingleSample(true, analogDataOut);



}


}
}

ConLrol AppllcaLlon
1he code for Lhls appllcaLlon ls 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();
}

private void timer1_Tick(object sender, EventArgs e)
{

DaqData myDaqData = new DaqData();

70 Appendlx A: Source Code
1uLorlal: uaLa AcqulslLlon ln C#
//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);

}

private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
}


/// <summary>
/// Reading and Writing Data from DAQ Device
/// </summary>
public class DaqData
{

public double ReadDaqData()
{

Task analogInTask = new Task();

AIChannel myAIChannel;

myAIChannel = analogInTask.AIChannels.CreateVoltageChannel(
"dev1/ai0",
"myAIChannel",
AITerminalConfiguration.Differential,
0,
5,
AIVoltageUnits.Volts
);

AnalogSingleChannelReader reader = new
AnalogSingleChannelReader(analogInTask.Stream);

double analogDataIn = reader.ReadSingleSample();

return analogDataIn;
}


public void WriteDaqData(double analogDataOut)
{

Task analogOutTask = new Task();

AOChannel myAOChannel;

myAOChannel = analogOutTask.AOChannels.CreateVoltageChannel(
"dev1/ao0",
71 Appendlx A: Source Code
1uLorlal: uaLa AcqulslLlon ln C#
"myAOChannel",
0,
5,
AOVoltageUnits.Volts
);

AnalogSingleChannelWriter writer = new
AnalogSingleChannelWriter(analogOutTask.Stream);

writer.WriteSingleSample(true, analogDataOut);

}
}

}

10.3 CC 8ead
using NationalInstruments;
using NationalInstruments.Net;
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 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);
}

private void btnReadOpc_Click(object sender, EventArgs e)
{

dataSocket.Update();

txtReadOpcValue.Text = dataSocket.Data.Value.ToString();
}
}
}
10.4 CC WrlLe
using NationalInstruments;
using NationalInstruments.Net;
using System;
using System.Collections.Generic;
72 Appendlx A: Source Code
1uLorlal: uaLa AcqulslLlon ln C#
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
{

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.Write);
}

private void btnWriteOpc_Click(object sender, EventArgs e)
{

double opcValue = 0;

opcValue = Convert.ToDouble(txtWriteOpcValue.Text);

dataSocket.Data.Value = opcValue;

dataSocket.Update();
}
}
}






1e|emark Un|vers|ty Co||ege
Iacu|ty of 1echno|ogy
k[|nes k|ng S6
N-3914 orsgrunn, Norway
www.h|t.no


nans-etter na|vorsen, M.Sc.
1e|emark Un|vers|ty Co||ege
Iacu|ty of 1echno|ogy
Department of L|ectr|ca| Lng|neer|ng, Informat|on 1echno|ogy and Cybernet|cs

L-ma||: hans.p.ha|vorsenQh|t.no
8|og: http:]]home.h|t.no]~hansha]

You might also like