data acquisition in csharp - halvorsen.blog · 3 table of contents 1 introduction ..... 6

77
https://www.halvorsen.blog Data Acquisition in C# Hans-Petter Halvorsen

Upload: others

Post on 24-Jul-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

https://www.halvorsen.blog

DataAcquisitioninC#Hans-PetterHalvorsen

Page 2: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

DataAcquisitioninC#

Hans-PetterHalvorsen

Copyright©2017

E-Mail:[email protected]

Web:https://www.halvorsen.blog

https://www.halvorsen.blog

Page 3: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

3

TableofContents1 Introduction........................................................................................................................6

1.1 VisualStudio.................................................................................................................6

1.2 DAQHardware.............................................................................................................7

1.2.1 NIUSBTC-01ThermocoupleDevice.....................................................................8

1.2.2 NIUSB-6008DAQDevice......................................................................................8

1.2.3 myDAQ..................................................................................................................9

1.3 NIDAQmxdriver........................................................................................................10

1.4 MeasurementStudio.................................................................................................12

2 DataAcquisition................................................................................................................13

2.1 Introduction...............................................................................................................13

2.1.1 Physicalinput/outputsignals..............................................................................14

2.1.2 DAQdevice/hardware.........................................................................................14

2.1.3 Driversoftware...................................................................................................15

2.1.4 Yoursoftwareapplication...................................................................................16

2.2 MAX–MeasurementandAutomationExplorer........................................................16

2.3 DAQinVisualStudio..................................................................................................17

2.3.1 NI-DAQmx...........................................................................................................17

2.3.2 Examples.............................................................................................................18

3 MyFirstDAQAppwithUSB-6008usingDAQmxDriver....................................................19

3.1 Introduction...............................................................................................................19

3.2 Example......................................................................................................................20

Page 4: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

4 TableofContents

Tutorial:DataAcquisitioninC#

3.2.1 AddReferencestoDAQmxDriver.......................................................................21

3.2.2 Initialization.........................................................................................................21

3.2.3 AnalogOut..........................................................................................................22

3.2.4 AnalogIn.............................................................................................................22

3.2.5 Error?..................................................................................................................23

4 TemperatureLoggingwithTC-01ThermocoupleDevice..................................................24

4.1 Example......................................................................................................................24

4.1.1 AddReferencestoDAQmxDriver.......................................................................24

4.1.2 Initialization.........................................................................................................26

4.1.3 ReadTemperatureData......................................................................................26

4.1.4 Testyourapplication...........................................................................................26

4.1.5 Error?..................................................................................................................27

5 MeasurementStudio........................................................................................................28

5.1 Introduction...............................................................................................................28

5.2 Templates...................................................................................................................29

5.3 Toolbox......................................................................................................................30

5.4 LoggingTemperatureDatawithTC-01ThermocoupleExample...............................31

5.4.1 SelectTemplate...................................................................................................31

5.4.2 SelectClassLibraries...........................................................................................31

5.4.3 UsingaTimer......................................................................................................33

5.5 LoggingTemperatureDatawithUSB-6008Example.................................................35

6 ControlApplication...........................................................................................................37

6.1 IntroductiontotheExample......................................................................................37

6.2 Coding........................................................................................................................39

6.2.1 ReadLevel...........................................................................................................41

6.2.2 WriteControlValue............................................................................................41

Page 5: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

5 TableofContents

Tutorial:DataAcquisitioninC#

6.2.3 UsingaTimer......................................................................................................42

7 TrendingData....................................................................................................................44

8 Discretization....................................................................................................................46

8.1 Low-passFilter...........................................................................................................46

8.2 PIController...............................................................................................................48

8.2.1 PIControllerasaState-spacemodel..................................................................49

8.3 ProcessModel............................................................................................................50

8.4 FinalApplication.........................................................................................................51

9 OPC....................................................................................................................................56

9.1 ReadOPCData...........................................................................................................56

9.2 WriteOPCData..........................................................................................................58

9.3 UsingaTimer.............................................................................................................60

10 UsingMeasurementStudioTemplates...........................................................................62

10.1 CreateaNIWindowsApplication............................................................................62

10.2 CreateaNIDAQWindowsApplication....................................................................66

AppendixA:SourceCode........................................................................................................72

MyFirstDAQApp................................................................................................................72

ControlApplication.............................................................................................................73

10.3 OPCRead.................................................................................................................75

10.4 OPCWrite................................................................................................................75

Page 6: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

6

1 IntroductionInthisTutorialwewilllearnhowtocreateDAQ(DataAcquisition)applicationsinVisualStudioandC#.WewilluseaUSB-6008DAQdevicefromNationalInstrumentsasanexample.InordertouseDAQdevicesfromNationalInstrumentsinC#andVisualStudioweneedtoNI-DAQmxdriverprovidesbyNationalInstruments.Aspartofthisinstallationyoucaninstalla.NETAPI.WewillusethisAPItocreateasimpleDAQapplication.Inaddition,wewilluseMeasurementStudiowhichisanadd-ontoVisualStudiowhichmakesiteasiertocreatemoreadvancedDAQapplications.

InthisTutorialweendupwithacontrolapplication.WewillsendandreaddatatoaDAQdevice,andwewillcreateourowndiscretePIDcontroller,low-passfilterandadiscretemodelofoursystem.WewillalsoreadandwritedatatoanOPCserver.

Youwillfindthisdocumentandlotsofotherinformationinthefollowingwebsite:

https://www.halvorsen.blog/documents/programming/csharp/

1.1 VisualStudioMicrosoftVisualStudioisanintegrateddevelopmentenvironment(IDE)fromMicrosoft.ItcanbeusedtodevelopconsoleandgraphicaluserinterfaceapplicationsalongwithWindowsFormsapplications,websites,webapplications,andwebservicesinbothnativecodetogetherwithmanagedcodeforallplatformssupportedbyMicrosoftWindows,WindowsPhone,WindowsCE,.NETFramework,.NETCompactFrameworkandMicrosoftSilverlight.

FormoreinformationaboutVisualStudioandC#,visitthefollowingwebpage:

https://www.halvorsen.blog/documents/programming/csharp/

Belowweseetheintegrateddevelopmentenvironment(IDE)inVisualStudio:

Page 7: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

7 Introduction

Tutorial:DataAcquisitioninC#

Newprojectsarecreatedfromthe“NewProject”window:

1.2 DAQHardwareInthisTutorialwewillusedifferenthardwareavailablefromNationalInstrumentsasexamples:

Page 8: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

8 Introduction

Tutorial:DataAcquisitioninC#

• TC-01Thermocoupledevice• USB-6008DAQDevice• MyDAQ

1.2.1 NIUSBTC-01ThermocoupleDevice

BelowweseetheNIUSB-TC01ThermocoupleMeasurementdevice.

WewillgivecodeexamplesofhowtousethisdeviceinC#.SincethisisaDAQmxsupporteddevicefromNationalInstruments,theprogramingstructurewillbethesameasforNIUSB-6008.

1.2.2 NIUSB-6008DAQDevice

NIUSB-6008isasimpleandlow-costmultifunctionI/OdevicefromNationalInstruments.

Page 9: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

9 Introduction

Tutorial:DataAcquisitioninC#

Thedevicehasthefollowingspecifications:

• 8analoginputs(12-bit,10kS/s)• 2analogoutputs(12-bit,150S/s)• 12digitalI/O• USBconnection,Noextrapower-supplyneeeded• CompatiblewithLabVIEW,LabWindows/CVI,andMeasurementStudioforVisual

Studio.NET• NI-DAQmxdriversoftware

TheNIUSB-6008iswellsuitedforeducationpurposesduetoitssmallsizeandeasyUSBconnection.

1.2.3 myDAQ

NImyDAQisasimpleandintuitiveDAQdevicefromNationalInstruments.NImyDAQhaveAnalogInputs(AI),AnalogOutputs(AO),DigitalInputs(DI)andDigitalOutputs(DO).

Specifications:

• TwoDifferentialAnalogInputandAnalogOutputChannels(200ks/s,16bit,+/-10Volts)

• EightDigitalInputandDigitalOutputLines(3.3VoltTTL-Compatible) • +5,+15,and-15VoltPowerSupplyOutputs(upto500mWattsofPower) • 60VoltDigitalMultimeter(DMM)forMeasuringVoltage,Current,andResistance

InadditiontotraditionalI/O,themyDAQhaveabuilt-inDigitalMultimeter.ThemyDAQcanalsobeusedasaPowerSupply.Usingthebuilt-insoftwarethemyDAQcanalsobeusedasanOscilloscopeandFunctionGenerator.

Page 10: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

10 Introduction

Tutorial:DataAcquisitioninC#

WhenyoupluginthedeviceintheUSBconnectiononyourPC,thefollowingwillpop-upautomatically(NIELVISmxInstrumentLauncher):

Note!YouneedtoinstalltheNIELVISmxdriversoftwarefirst

IfyouclickontheDMMbutton,thebuilt-inDigitalMultimeterwillappear:

1.3 NIDAQmxdriverNationalInstrumentsprovidesanative.NETAPIforNI-DAQmx.ThisisavailableasapartoftheNI-DAQmxdriveranddoesnotrequireMeasurementStudio.

Note!InordertoinstalltheDAQmxAPIforC#,makesuretoselect“.NETSupport”wheninstallingtheDAQmxdriver.

ThisapplicationusestheC#APIincludedintheNIDAQmxdriver,somakesurethatyouhaveinstalledtheNIDAQmxdriverinadvance.

Page 11: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

11 Introduction

Tutorial:DataAcquisitioninC#

Duringtheinstallationmakesuretoselect“Custom”:

Next,makesurethatyouselect.NETFrameworkX.xSupportfortheversionof.NETthatyourversionofVisualStudioisusing:

Page 12: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

12 Introduction

Tutorial:DataAcquisitioninC#

1.4 MeasurementStudioC#isapowerfulprogramminglanguage,buthasfewbuilt-infeaturesformeasurementandcontrolapplications.MeasurementStudioisanadd-ontoVisualStudiowhichmakesiteasiertocreatesuchapplications.WithMeasurementStudiowecanimplementDataAcquisitionandagraphicalHMI.

Page 13: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

13

2 DataAcquisition2.1 IntroductionThepurposeofdataacquisitionistomeasureanelectricalorphysicalphenomenonsuchasvoltage,current,temperature,pressure,orsound.PC-baseddataacquisitionusesacombinationofmodularhardware,applicationsoftware,andacomputertotakemeasurements.Whileeachdataacquisitionsystemisdefinedbyitsapplicationrequirements,everysystemsharesacommongoalofacquiring,analyzing,andpresentinginformation.Dataacquisitionsystemsincorporatesignals,sensors,actuators,signalconditioning,dataacquisitiondevices,andapplicationsoftware.

Sosummingup,DataAcquisitionistheprocessof:

• Acquiringsignalsfromreal-worldphenomena• Digitizingthesignals• Analyzing,presentingandsavingthedata

TheDAQsystemhasthefollowingpartsinvolved,seeFigure:

[Figure:www.ni.com]

Thepartsare:

• Physicalinput/outputsignals• DAQdevice/hardware

Page 14: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

14 DataAcquisition

Tutorial:DataAcquisitioninC#

• Driversoftware• Yoursoftwareapplication(Applicationsoftware)

ForanIntroductiontoDataAcquisition,seethiswebcast:http://zone.ni.com/wv/app/doc/p/id/wv-169

2.1.1 Physicalinput/outputsignals

Aphysicalinput/outputsignalistypicallyavoltageorcurrentsignal.

2.1.2 DAQdevice/hardware

DAQhardwareactsastheinterfacebetweenthecomputerandtheoutsideworld.Itprimarilyfunctionsasadevicethatdigitizesincominganalogsignalssothatthecomputercaninterpretthem

ADAQdevice(DataAcquisitionHardware)usuallyhasthesefunctions:

• Analoginput• Analogoutput• DigitalI/O• Counter/timers

WehavedifferentDAQdevices,suchas:

• “DesktopDAQdevices”whereyouneedtoplugaPCIDAQboardintoyourcomputer.Thesoftwareisrunningonacomputer.

• “PortableDAQdevices”forconnectiontotheUSBport,Wi-Ficonnections,etc.Thesoftwareisrunningonacomputer

• “DistributedDAQdevices”wherethesoftwareisdevelopedonyourcomputerandthenlaterdownloadedtothedistributedDAQdevice.

Page 15: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

15 DataAcquisition

Tutorial:DataAcquisitioninC#

[Figure:www.ni.com]

[Figure:www.ni.com]

2.1.3 Driversoftware

Driversoftwareisthelayerofsoftwareforeasilycommunicatingwiththehardware.Itformsthemiddlelayerbetweentheapplicationsoftwareandthehardware.Driversoftwarealsopreventsaprogrammerfromhavingtodoregister-levelprogrammingorcomplicatedcommandsinordertoaccessthehardwarefunctions.

Page 16: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

16 DataAcquisition

Tutorial:DataAcquisitioninC#

DriversoftwarefromNationalInstruments:NI-DAQmx

2.1.4 Yoursoftwareapplication

Applicationsoftwareaddsanalysisandpresentationcapabilitiestothedriversoftware.Yoursoftwareapplicationnormallydoessuchtasksas:

• Real-timemonitoring• Dataanalysis• Datalogging• Controlalgorithms• Humanmachineinterface(HMI)

InordertocreateyourDAQapplicationyouneedaprogrammingdevelopmenttool,suchasVisualStudio/C#,LabVIEW,etc..

2.2 MAX–MeasurementandAutomationExplorer

Measurement&AutomationExplorer(MAX)providesaccesstoyourNationalInstrumentsdevicesandsystems.

WithMAX,youcan:

• ConfigureyourNationalInstrumentshardwareandsoftware • Createandeditchannels,tasks,interfaces,scales,andvirtualinstruments • Executesystemdiagnostics • Viewdevicesandinstrumentsconnectedtoyoursystem • UpdateyourNationalInstrumentssoftware

Inadditiontothestandardtools,MAXcanexposeitem-specifictoolsyoucanusetoconfigure,diagnose,ortestyoursystem,dependingonwhichNIproductsyouinstall.AsyounavigatethroughMAX,thecontentsoftheapplicationmenuandtoolbarchangetoreflectthesenewtools.

Page 17: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

17 DataAcquisition

Tutorial:DataAcquisitioninC#

2.3 DAQinVisualStudioWecancreateDAQapplicationswithorwithoutMeasurementStudio.InbothsituationsyouneedtheNI-DAQmxdriverlibrary.

2.3.1 NI-DAQmx

NationalInstrumentsprovidesanative.NETAPIforNI-DAQmx.ThisisavailableasapartoftheNI-DAQmxdriveranddoesnotrequireMeasurementStudio.

Ingeneral,dataacquisitionprogrammingwithDAQmxinvolvesthefollowingsteps:

Page 18: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

18 DataAcquisition

Tutorial:DataAcquisitioninC#

• CreateaTaskandVirtualChannels• StarttheTask• PerformaReadoperationfromtheDAQ• PerformaWriteoperationtotheDAQ• StopandCleartheTask.

Dataacquisitionintextbased-programmingenvironmentisverysimilartotheLabVIEWNI-DAQmxprogrammingasthefunctionscallsisthesameastheNI-DAQmxVI’s.

UsingNI-DAQmxinTextBasedProgrammingEnvironments:

http://zone.ni.com/devzone/cda/tut/p/id/5409#toc4

2.3.2 Examples

ExamplesinstalledaspartofNI-DAQmx:

ThelocationofexampleswilldependontheversionofVisualStudioandislistedinthefollowingDeveloperZoneArticle:UsingNI-DAQmxinTextBasedProgrammingEnvironments.Themostcommonlocationis:

C:\DocumentsandSettings\AllUsers\Documents\NationalInstruments\NI-DAQ\Examples\DotNET<.NETFrameworkVersion>\

Newestexamplesfor.NETx.xandVisualStudio20xx:

C:\DocumentsandSettings\AllUsers\Documents\NationalInstruments\NI-DAQ\Examples\DotNETx.x\

Sub-foldersnamedCScontainC#examples.TheseexamplesinstallwithNI-DAQmx.MeasurementStudioisnotrequiredtoinstalltheclasslibrariesortheexamples.

Note!Ifthepathsabovedonotexist,besureyouhave.NETsupportinstalledforNI-DAQmx.

Page 19: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

19

3 MyFirstDAQAppwithUSB-6008usingDAQmxDriver

WewillcreateasimpleapplicationinVisualStudiothatusesaNIUSB-6008DAQdevice.

3.1 IntroductionThisapplicationusestheC#APIincludedintheNIDAQmxdriver,somakesurethatyouhaveinstalledtheNIDAQmxdriverinadvance.Youdon’tneedMeasurementStudiotocreatethisapplication.

StartVisualStudioandcreateanewWindowsFormsapplication.

WewillcreatethefollowingapplicationinVisualStudio2010andC#:

Page 20: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

20 MyFirstDAQApp

Tutorial:DataAcquisitioninC#

TheUserInterfacelookslikethis:

WestartbyconnectingtheAnalogInandAnalogOutwirestogether(asocalledLoopbacktest).

Whenweclickthe“WriteData”button,thevalueenteredinthetextbox“AnalogOut”willbewrittentotheDAQdevice.IfwehaveconnectedtheAnalogInandAnalogOutwirestogetherwewillreadthesamevalueinthe“AnalogIn”textboxwhenwepushthe“GetData”button.

3.2 ExampleWewillgothroughthedifferentpartsofthecodeindetail.

Page 21: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

21 MyFirstDAQApp

Tutorial:DataAcquisitioninC#

3.2.1 AddReferencestoDAQmxDriver

ThisapplicationusestheC#APIincludedintheNIDAQmxdriver,somakesurethatyouhaveinstalledtheNIDAQmxdriverinadvance.

WeneedtoaddthefollowingAssemblyreferences:

• NationalInstruments.Common• NationalInstruments.DAQmx

WeaddReferencesbyright-clickingtheReferencesnodeintheSolutionExplorer:

WhenwehaveaddedthenecessaryReferences,theSolutionExplorerwilllooklikethis:

3.2.2 Initialization

WeneedtoaddthefollowingNamespaces:

using NationalInstruments; using NationalInstruments.DAQmx;

Page 22: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

22 MyFirstDAQApp

Tutorial:DataAcquisitioninC#

3.2.3 AnalogOut

WeimplementthecodeforwritingtotheAnalogOutchannelintheEventHandlerforthe“WriteData”button:

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

3.2.4 AnalogIn

WeimplementthecodeforreadingdatafromtheAnalogInchannelintheEventHandlerforthe“GetData”button:

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

Page 23: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

23 MyFirstDAQApp

Tutorial:DataAcquisitioninC#

3.2.5 Error?

Ifyourapplicationrunswithouterrorthat’sfine,butperhapsyougetthefollowingerror:

Inordertofixtheproblem,openthePropertiesforyourproject:

Makesuretoselect“.NETFrameworkX”inthe“Targetframework”drop-downmenu.

Page 24: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

24

4 TemperatureLoggingwithTC-01ThermocoupleDevice

InthisexamplewewilluseaNITC-01USBThermocoupledevice.

4.1 ExampleWewillcreatethefollowingsimpleapplication:

4.1.1 AddReferencestoDAQmxDriver

WeneedtoaddthefollowingAssemblyreferences:

Page 25: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

25 TemperatureLogging

Tutorial:DataAcquisitioninC#

• NationalInstruments.Common• NationalInstruments.DAQmx

WeaddReferencesbyright-clickingtheReferencesnodeintheSolutionExplorer:

WhenwehaveaddedthenecessaryReferences,theSolutionExplorerwilllooklikethis:

Thedllsarenormallytofindhere:

Page 26: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

26 TemperatureLogging

Tutorial:DataAcquisitioninC#

4.1.2 Initialization

WeneedtoaddthefollowingNamespaces:

using NationalInstruments; using NationalInstruments.DAQmx;

4.1.3 ReadTemperatureData

Enterthefollowingcodelines:

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

4.1.4 Testyourapplication

Runyourapplication.Whenclickingthebutton,youshouldnowretrievedatafromthetemoeraturedevice.

Page 27: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

27 TemperatureLogging

Tutorial:DataAcquisitioninC#

4.1.5 Error?

Ifyourapplicationrunswithouterrorthat’sfine,butperhapsyougetthefollowingerror:

Inordertofixtheproblem,openthePropertiesforyourproject:

Makesuretoselect“.NETFrameworkX”inthe“Targetframework”drop-downmenu.

Page 28: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

28

5 MeasurementStudio

5.1 Introduction

C#isapowerfulprogramminglanguage,buthasfewbuilt-infeaturesformeasurementandcontrolapplications.MeasurementStudioisanadd-ontoVisualStudiowhichmakesiteasiertocreatesuchapplications.WithMeasurementStudiowecanimplementDataAcquisitionandagraphicalHMI.

[Figure:www.ni.com]

MeasurementStudioforVisualC#.NETprovides:

• Managed.NETcontrolsforcreatingrichWebandWindowsGUIs• MultithreadedAPIfordataacquisition

Page 29: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

29 MeasurementStudio

Tutorial:DataAcquisitioninC#

• InstrumentcontrolAPIs• Analysislibrariesdesignedforengineersandscientists

[Figure:www.ni.com]

5.2 TemplatesMeasurementStudiohasseveralTemplatesthatmakeiteasiertobuildDAQapplications.

Page 30: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

30 MeasurementStudio

Tutorial:DataAcquisitioninC#

5.3 ToolboxBelowweseetheToolboxinVisualStudiothatisinstalledwithMeasurementStudio:

InadditiontotheToolbox,MeasurementStudioalsoinstallsthefollowingmenuitem:

Page 31: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

31 MeasurementStudio

Tutorial:DataAcquisitioninC#

5.4 LoggingTemperatureDatawithTC-01ThermocoupleExample

InthisexamplewewilluseaNITC-01USBThermocoupledevice.

5.4.1 SelectTemplate

Inthisexample,wewillselectthe“NIwindowsApplication”Templateinthe“NewProject”window.

5.4.2 SelectClassLibraries

Page 32: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

32 MeasurementStudio

Tutorial:DataAcquisitioninC#

NextweselecttheClassLibrarieswewanttoinclude.Inourcaseweneedatleasttoselectthe“DAQmxLibrary”.

Whenweclick“Finish”anemptyprojectwillbecreatedforus.Wearenowreadytocreateourownapplication.

WestartbycreatingasimpleUserInterface:

Whenweclickthe“ReadTemp”button,theTemperaturedatashallbeshowninthe“TempData”TextBox.

IntheeventHandlerforthe“ReadTemp”button,wecreatethefollowingcode:

private void btnReadTempData_Click(object sender, EventArgs e)

Page 33: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

33 MeasurementStudio

Tutorial:DataAcquisitioninC#

{ 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(); }

Thenwecantestourapplication:

5.4.3 UsingaTimer

Improvements:Weshouldusea“Timer”inordertoreadTemperaturedataatspecificintervalsinsteadofpushingabuttoneachtimeweneeddata.

WedraginaTimercomponentfromtheToolbox.First,weneedtostarttheTimer:

public Form1() { InitializeComponent(); timer1.Start(); }

Next,weneedtospecifytheinterval.WecandothatinthePropertieswindow:

Page 34: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

34 MeasurementStudio

Tutorial:DataAcquisitioninC#

IntheTimerEventwewritethecodeforreadingtheTemperature:

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

Finally,wetesttheapplication:

Page 35: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

35 MeasurementStudio

Tutorial:DataAcquisitioninC#

5.5 LoggingTemperatureDatawithUSB-6008Example

InthisexamplewewilllogtemperaturedatausingtheUSB-6008device.

InadditionwewilluseaPt-100sensorthatweconnecttooneoftheAnalogInputchannelsontheUSB-6008device:

TheOutputfromthisdeviceisbetween1-5Vthatillustratesatemperaturebetween0and100degreesCelsius.

Page 36: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

36 MeasurementStudio

Tutorial:DataAcquisitioninC#

Theprocedureandcodeisidenticalasthepreviousexample,exceptasmallpartasshownbelow:

private void timer1_Tick(object sender, EventArgs e) { Task analogInTask = new Task(); AIChannel myAIChannel; myAIChannel = analogInTask.AIChannels.CreateVoltageChannel( "dev1/ai0", "myAIChannel", AITerminalConfiguration.Differential, 1, 5, AIVoltageUnits.Volts ); AnalogSingleChannelReader reader = new AnalogSingleChannelReader(analogInTask.Stream); double analogDataIn = reader.ReadSingleSample(); txtTempData.Text = analogDataIn.ToString("0.0"); }

Page 37: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

37

6 ControlApplication6.1 IntroductiontotheExampleInthisexamplewewilluseMeasurementStudiotocreateasimplecontrolapplication.Wewillcontrolthelevelinawatertankusingmanualcontrol.Theprocessisasfollows:

Inthisexamplewewilluseasmall-scalelaboratoryprocesscalledLM-900LevelSystem:

Page 38: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

38 ControlApplication

Tutorial:DataAcquisitioninC#

Wewanttocontrolthelevelinthewatertankusingapumpontheinflow.WewillreadthelevelusingourUSB-6008DAQdevice(AnalogIn)andwritethecontrolsignal(AnalogOut)totheDAQdevice.

TheAnalogOut(controlsignal)willbeasignalbetween 0 − 5𝑉 andtheAnalogIn(Level)willbea 0 − 5𝑉 signalthatweneedtoscaleto 0 − 20𝑐𝑚.

Wewillcreatethefollowingapplication:

Wewillusea“Slider”tomanuallyadjustthecontrolsignalandaTanktoindicatethelevelintherealprocess.

Inthisexamplewewillusethe“Slide”controland“Tank”controlthatcomeswithMeasurementStudio.

Page 39: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

39 ControlApplication

Tutorial:DataAcquisitioninC#

6.2 CodingStartaNewProjectinVisualStudio:

Selectthe“NIWindowsApplication”Templateinthe“MeasurementStudio”node.

Inthewindowthatappearsnext,selecttheLibrariesyouwanttoinclude:

Page 40: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

40 ControlApplication

Tutorial:DataAcquisitioninC#

WecreatetheUserInterfaceaboveinVisualStudio,anditlookslikethis:

ForthereadandwriteoperationswehavecreatedasimpleClasswithtwomethods:

public class DaqData { public double ReadDaqData() { ... } public void WriteDaqData(double analogDataOut)

Page 41: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

41 ControlApplication

Tutorial:DataAcquisitioninC#

{ ... } }

MoreabouttheReadDaqData()andWriteDaqData()methodsbelow.

6.2.1 ReadLevel

TheReadDaqData()methodhandlesthelogicforreadingfromtheDAQdevice:

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

6.2.2 WriteControlValue

TheWriteDaqData()methodhandlesthelogicforwritingtotheDAQdevice:

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

Page 42: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

42 ControlApplication

Tutorial:DataAcquisitioninC#

6.2.3 UsingaTimer

Inthepreviousexample(“MyFirstDAQApp”)wewasreadingandwritingtotheDAQdevicewhenclickingabutton,butinanordinaryapplicationthisisnotagoodsolution.Inordertoreadandwritedataonregularintervalswewillusea“Timer”.

Inthe“Components”toolboxwefindthe“Timer”Control:

InthePropertieswindowwecanspecifytheInterval(“SamplingTime”)inmilliseconds.

Wecanstartthetimerwiththefollowingcode:

public Form1() { InitializeComponent(); timer1.Start(); }

Page 43: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

43 ControlApplication

Tutorial:DataAcquisitioninC#

IntheTimerEventwecreatethemainlogicinourapplication.WecalltheReadDaqData()andWriteDaqData()methods,updatestheGUI,etc.

private void timer1_Tick(object sender, EventArgs e) { DaqData myDaqData = new DaqData(); //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); }

Page 44: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

44

7 TrendingDataNowwewanttoextendourapplicationwithfunctionalityforviewinghistoricaldatausingatrendplot.

Belowweseethenewuserinterface:

Inthisexamplewewillusethe“WaveformGraph”controlinMeasurementStudio.

Thesourcecodeisthesameasinthepreviousexample,exceptforonenewlineofcodeintheTimerEvent:

waveformGraph.PlotYAppend(analogDataIn);

The“WaveformGraph”controlhaslotsoffunctionalityyoucansetinthePropertieswindoworclickingtheSmartTagAnchor(littlearrowintheupperrightcornerofthecontrol).

BelowweseethePropertieswindow(leftside)andtheSmartTagPanel(rightside)fortheWaveformGraphcontrol:

Page 45: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

45 TrendingData

Tutorial:DataAcquisitioninC#

Page 46: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

46

8 DiscretizationThenextimprovementstoourapplicationwouldbetoimplementaLow-passFilterinordertoremovethenoisefromthesignalwhenreadingthelevel.AnotherimprovementwouldbetoreplacethemanualcontrolwithaPIcontrollerthatdothejobforus.Finallyitwouldbenicetohaveamathematicalmodelofourwatertanksowecansimulateandtestthebehavioroftherealsystemwithoutconnecttoit.

Soweneedtocreatediscreteversionsofthelow-passfilter,thePIcontrollerandtheprocessmodel.Wecan,e.g.,usetheEulerForwarddiscretizationmethod:

𝑥 ≈𝑥*+, − 𝑥*

𝑇.

ortheEulerBackwarddiscretizationmethod:

𝑥 ≈𝑥* − 𝑥*/,

𝑇.

𝑇. istheSamplingTime.

8.1 Low-passFilterThetransferfunctionforafirst-orderlow-passfiltermaybewritten:

𝐻 𝑠 =𝑦(𝑠)𝑢(𝑠)

=1

𝑇8𝑠 + 1

Where 𝑇8 isthetime-constantofthefilter, 𝑢(𝑠) isthefilterinputand 𝑦 𝑠 isthefilteroutput.

Discreteversion:

Itcanbeshownthatadiscreteversioncanbestatedas:

𝒚𝒌 = 𝟏 − 𝒂 𝒚𝒌/𝟏 + 𝒂𝒖𝒌

Where

𝒂 =𝑻𝒔

𝑻𝒇 + 𝑻𝒔

Page 47: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

47 Discretization

Tutorial:DataAcquisitioninC#

Where 𝑇. istheSamplingTime.

Itisagoldenrulethat 𝑇. ≪ 𝑇8 andinpracticeweshouldusethefollowingrule:

𝑇. ≤𝑇85

Proof:

Given:

𝑦𝑢=

1𝑇8𝑠 + 1

Thisgives:

𝑇8𝑠 + 1 𝑦 = 𝑢

𝑇8𝑠𝑦 + 𝑦 = 𝑢

InverseLaplacegives:

𝑇8𝑦 + 𝑦 = 𝑢

WeusetheEulerBackwarddiscretizationmethod, 𝑥 ≈ DE/DEFGHI

,whichgives:

𝑇8𝑦* − 𝑦*/,

𝑇.+ 𝑦* = 𝑢*

Thenweget:

𝑇8 𝑦* − 𝑦*/, + 𝑦*𝑇. = 𝑢*𝑇.

𝑇8𝑦* − 𝑇8𝑦*/, + 𝑦*𝑇. = 𝑢*𝑇.

𝑦*(𝑇8 + 𝑇.) = 𝑇8𝑦*/, + 𝑢*𝑇.

Thisgives:

𝑦* =𝑇8

𝑇8 + 𝑇.𝑦*/, +

𝑇.𝑇8 + 𝑇.

𝑢*

Forsimplicityweset:

𝑇.𝑇8 + 𝑇.

≡ 𝑎

Thisgives:

𝑦* = (1 − 𝑎)𝑦*/, + 𝑎𝑢*

Page 48: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

48 Discretization

Tutorial:DataAcquisitioninC#

𝑎 =𝑇.

𝑇8 + 𝑇.

[EndofProof]

8.2 PIControllerAPIcontrollermaybewritten:

𝑢 𝑡 = 𝑢N + 𝐾P𝑒 𝑡 +𝐾P𝑇R

𝑒𝑑𝜏U

N

Where 𝑢 isthecontrolleroutputand 𝑒isthecontrolerror:

𝑒 𝑡 = 𝑟 𝑡 − 𝑦(𝑡)

Laplace:

𝑢 𝑠 = 𝐾P𝑒 𝑠 +𝐾P𝑇R𝑠

𝑒 𝑠

Discreteversion:

Westartwith:

𝑢 𝑡 = 𝑢N + 𝐾P𝑒 𝑡 +𝐾P𝑇R

𝑒𝑑𝜏U

N

Inordertomakeadiscreteversionusing,e.g.,Euler,wecanderivebothsidesoftheequation:

𝑢 = 𝑢N + 𝐾P𝑒 +𝐾P𝑇R𝑒

IfweuseEulerForwardweget:

𝑢* − 𝑢*/,𝑇.

=𝑢N,* − 𝑢N,*/,

𝑇.+ 𝐾P

𝑒* − 𝑒*/,𝑇.

+𝐾P𝑇R𝑒*

Thenweget:

𝒖𝒌 = 𝒖𝒌/𝟏 + 𝒖𝟎,𝒌 − 𝒖𝟎,𝒌/𝟏 + 𝑲𝒑 𝒆𝒌 − 𝒆𝒌/𝟏 +𝑲𝒑

𝑻𝒊𝑻𝒔𝒆𝒌

Where

𝑒* = 𝑟* − 𝑦*

Page 49: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

49 Discretization

Tutorial:DataAcquisitioninC#

Wecanalsosplittheequationabovein2differentparsbysetting:

∆𝑢* = 𝑢* − 𝑢*/,

ThisgivesthefollowingPIcontrolalgorithm:

𝒆𝒌 = 𝒓𝒌 − 𝒚𝒌

∆𝒖𝒌 = 𝒖𝟎,𝒌 − 𝒖𝟎,𝒌/𝟏 + 𝑲𝒑 𝒆𝒌 − 𝒆𝒌/𝟏 +𝑲𝒑

𝑻𝒊𝑻𝒔𝒆𝒌

𝒖𝒌 = 𝒖𝒌/𝟏 + ∆𝒖𝒌

ThisalgorithmcaneasilybeimplementedinC#.

8.2.1 PIControllerasaState-spacemodel

Given:

𝑢 𝑠 = 𝐾P𝑒 𝑠 +𝐾P𝑇R𝑠

𝑒 𝑠

Weset 𝑧 = ,.𝑒 ⇒ 𝑠𝑧 = 𝑒 ⇒ 𝑧 = 𝑒

Thisgives:

𝑧 = 𝑒

𝑢 = 𝐾P𝑒 +𝐾P𝑇R𝑧

Where

𝑒 = 𝑟 − 𝑦

Discreteversion:

UsingEuler:

𝑧 ≈𝑧*+, − 𝑧*

𝑇.

Where 𝑇. istheSamplingTime.

Thisgives:

𝑧*+, − 𝑧*𝑇.

= 𝑒*

Page 50: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

50 Discretization

Tutorial:DataAcquisitioninC#

𝑢* = 𝐾P𝑒* +𝐾P𝑇R𝑧*

Finally:

𝒆𝒌 = 𝒓𝒌 − 𝒚𝒌

𝒖𝒌 = 𝑲𝒑𝒆𝒌 +𝑲𝒑

𝑻𝒊𝒛𝒌

𝒛𝒌+𝟏 = 𝒛𝒌 + 𝑻𝒔𝒆𝒌

ThisalgorithmcaneasilybeimplementedinC#.

8.3 ProcessModelTheleveltank:

Averysimple(linear)modelofthewatertankisasfollows:

𝐴Uℎ = 𝐾P𝑢−𝐹efU

or

ℎ =1𝐴U

𝐾P𝑢−𝐹efU

Page 51: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

51 Discretization

Tutorial:DataAcquisitioninC#

Where:

• ℎ [cm]isthelevelinthewatertank• 𝑢 [V]isthepumpcontrolsignaltothepump• 𝐴U [cm2]isthecross-sectionalareainthetank• 𝐾P [(cm3/s)/V]isthepumpgain• 𝐹efU [cm3/s]istheoutflowthroughthevalve(thisoutflowcanbemodeledmore

accuratelytakingintoaccountthevalvecharacteristicexpressingtherelationbetweenpressuredropacrossthevalveandtheflowthroughthevalve).

WecanusetheEulerForwarddiscretizationmethodinordertocreateadiscretemodel:

𝑥 ≈𝑥*+, − 𝑥*

𝑇.

Thenweget:

ℎ*+, − ℎ*𝑇.

=1𝐴U

𝐾P𝑢*−𝐹efU

Finally:

𝒉𝒌+𝟏 = 𝒉𝒌 +𝑻𝒔𝑨𝒕

𝑲𝒑𝒖𝒌−𝑭𝒐𝒖𝒕

8.4 FinalApplicationWeextendourControlApplicationwithadiscretePIcontroller,adiscreteLow-passfilterandadiscreteprocessmodel,sowecanswitchbetweentherealprocessandasimulator.

OurUserInterfaceisasfollows:

Page 52: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

52 Discretization

Tutorial:DataAcquisitioninC#

BelowweseetheProjectandSolutioninVisualStudio:

Belowwewillshowanddescribetheimportantpartsofthecode.

PIController:

WecreateanewClassforourPIDalgorithm,byright-clickintheSolutionExplorer(Add→NewItem…)

Page 53: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

53 Discretization

Tutorial:DataAcquisitioninC#

TheAddNewItemwindowappears:

SelecttheClassItemandaproperName,e.g.“PidController”.

ThePidControllerClassisasfollows:

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

Page 54: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

54 Discretization

Tutorial:DataAcquisitioninC#

double u; // Controller Output //PID Algoritm e = r - y; u = Kp * e + (Kp / Ti) * z; z = z + Ts * e; return u; } }

WetheninitializethePidControllerClass:

PidController pidControl = new PidController {

Ts=0.1, r=5, Kp=0.8, Ti=15 };

Finallyweusethecontroller:

private void ControlSystem() {

//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-passFilter:

WecreatetheLow-passFilterasaseparateClassto:

class Filter { public double yk; public double Ts; public double Tf; public double LowPassFilter(double yFromDaq) {

Page 55: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

55 Discretization

Tutorial:DataAcquisitioninC#

double a; double yFiltered; a = Ts / (Ts + Tf); yFiltered = (1 - a) * yk + a * yFromDaq; yk = yFiltered; return yFiltered; } }

Wetheninitializethefilter:

Filter filter = new Filter {

Ts = 0.1, Tf = 2 };

Finallyweusethefilter:

// Lowpass filtering the Measure Value due to noise levelMeasurement = filter.LowPassFilter(levelMeasurement);

DiscreteModel:

Wedothesameforthediscretemodel.

WehavecreatedaClassandaLevelTankModelMethodthatweuseinoursimulation:

levelMeasurement = model.LevelTankModel(controllerOutput);

Page 56: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

56

9 OPCInordertocommunicatewithanOPCServerwecanusetheDataSocketAPIthatispartoftheMeasurementStudio.WeusetheMatrikonOPCSimulationServer.

9.1 ReadOPCDataBelowwewillgothroughaverysimpleexample.WewillreadonevaluefromtheOPCServereachtimeweclickabutton.

VisualStudioProject:

Code:

WedefineaDataSocketobject:

DataSocket dataSocket = new DataSocket();

Next,WeConnecttotheOPCServer:

string opcUrl; opcUrl = "opc://localhost/MATRIKON.OPC.Simulation/Bucket Brigade.Real4";

Page 57: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

57 OPC

Tutorial:DataAcquisitioninC#

if (dataSocket.IsConnected) dataSocket.Disconnect(); dataSocket.Connect(opcUrl, AccessMode.Read);

Finally,weReadOPCData:

private void btnReadOpc_Click(object sender, EventArgs e) { dataSocket.Update(); txtReadOpcValue.Text = dataSocket.Data.Value.ToString(); }

WetesttheApplicationusingtheMatrikonOPCExplorer:

SelectUrl:

WecanusetheSelectUrlmethodifwewanttopicktheOPCitemfromalistofavailableservers(bothlocalserversandnetworkservers)anditems.

dataSocket.SelectUrl();

TheSelctUrlmethodwillpopupthefollowingwindow:

Page 58: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

58 OPC

Tutorial:DataAcquisitioninC#

9.2 WriteOPCDataWeusethesameDataSocketAPIhere.

VisualStudioProject:

Belowwewillgothroughaverysimpleexample.WewillwriteonevaluetotheOPCServereachtimeweclickabutton.

Page 59: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

59 OPC

Tutorial:DataAcquisitioninC#

Code:

WedefineaDataSocketobject:

DataSocket dataSocket = new DataSocket();

Next,WeConnecttotheOPCServer:

string opcUrl; opcUrl = "opc://localhost/MATRIKON.OPC.Simulation/Bucket Brigade.Real4"; if (dataSocket.IsConnected) dataSocket.Disconnect(); dataSocket.Connect(opcUrl, AccessMode.Write);

Finally,weWriteOPCData:

private void btnWriteOpc_Click(object sender, EventArgs e) { double opcValue = 0; opcValue = Convert.ToDouble(txtWriteOpcValue.Text); dataSocket.Data.Value = opcValue; dataSocket.Update(); }

WetesttheApplicationusingtheMatrikonOPCExplorer:

Page 60: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

60 OPC

Tutorial:DataAcquisitioninC#

9.3 UsingaTimerWecanuseatimerinordertoreadvalues“continuously”,i.e.atspecificintervals.

Inthe“Components”toolboxwefindthe“Timer”Control:

InthePropertieswindowwecanspecifytheInterval(“SamplingTime”)inmilliseconds.

Wecanstartthetimerwiththefollowingcode:

public Form1() { InitializeComponent(); timer1.Start(); }

IntheTimerEventwecreatethecodeinordertoreaddataatthisspecificinterval.

Page 61: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

61 OPC

Tutorial:DataAcquisitioninC#

private void timer1_Tick(object sender, EventArgs e) { … … }

Page 62: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

62

10 UsingMeasurementStudioTemplates

InordertousetheNIUSB-TC01ThermocoupleMeasurementdevicewithC#weneedtohavetheDAQmxdriverandtheDAQmxAPIforC#installed.InordertoinstalltheDAQmxAPIforC#,makesuretoselect“.NETSupport”wheninstallingtheDAQmxdriver.

C#isapowerfulprogramminglanguage,buthasfewbuilt-infeaturesformeasurementandcontrolapplications.MeasurementStudioisanadd-ontoVisualStudiowhichmakesiteasiertocreatesuchapplications.WithMeasurementStudiowecanimplementDataAcquisitionandagraphicalHMI.

Youdon’tneedtousetheMeasurementStudiotocreateanapplicationwhereyouusetheNIUSB-TC01ThermocoupleMeasurementdevice,butitiseasier.

HerewewilluseVisualStudioandtheMeasurementStudioAdd-intocreatesomeDAQexampleswherewegettemperaturedatafromtheNIUSB-TC01ThermocoupleMeasurementdevice.

10.1 CreateaNIWindowsApplicationInthisexample,wewillselectthe“NIwindowsApplication”Templateinthe“NewProject”window.

Page 63: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

63 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

Note!The“NewProject”windowmaylookdifferentonyourcomputer,itdependsonwhatfeaturesyouhaveinstalledandwhichversionoreditionofMeasurementStudioyouareusing.

NextweselecttheClassLibrarieswewanttoinclude.Inourcaseweneedatleasttoselectthe“DAQmxLibrary”.

Whenweclick“Finish”anemptyprojectwillbecreatedforus.Wearenowreadytocreateourownapplication.

Page 64: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

64 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

WestartbycreatingasimpleUserInterface:

Whenweclickthe“ReadTemp”button,theTemperaturedatashallbeshowninthe“TempData”TextBox.

IntheeventHandlerforthe“ReadTemp”button,wecreatethefollowingcode:

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

Thenwecantestourapplication:

Page 65: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

65 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

Improvements:Weshouldusea“Timer”inordertoreadTemperaturedataatspecificintervalsinsteadofpushingabuttoneachtimeweneeddata.

WedraginaTimercomponentfromtheToolbox.First,weneedtostarttheTimer:

public Form1() { InitializeComponent(); timer1.Start(); }

Next,weneedtospecifytheinterval.WecandothatinthePropertieswindow:

IntheTimerEventwewritethecodeforreadingtheTemperature:

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

Finally,wetesttheapplication:

Page 66: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

66 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

10.2 CreateaNIDAQWindowsApplicationNote!ThisoptionisonlyavailibleifyoutohaveeithertheProfessionalorEnterpriseversionoftheMeasurementStudiosoftware.

Westartbycreatinga“NewProject”fromVisualStudio.Inthe“NewProject”windowweselect“VisualC#”»“MeasurementStudio”,andthenselectthe“NIDAQWindowsApplication”TemplatethatispartoftheMeasurementStudio.

Note!The“NewProject”windowmaylookdifferentonyourcomputer,itdependsonwhatfeaturesyouhaveinstalledandwhichversionoreditionofMeasurementStudioyouareusing.

Next,weneedtogothroughdifferentstepsinawizard.

Page 67: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

67 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

Inthefirststepweselect“Createanewprojecttask”:

Inthenextstepweselectthemeasurementtype,andsincetheNIUSB-TC01ThermocoupleMeasurementdeviceisforreadingTemperaturevalues,weneedtoselect“AcquireSignals”.

Inthe“AcquireSignals”nodewefirstselect“Temperature”andthenselect“Thermocouple”.

Page 68: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

68 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

Nextweneedtoselectthephysicalchannel(s).SincetheNIUSB-TC01ThermocoupleMeasurementdevicehasonlyonechannelavailable,weneedtoselect“ai0”(AnalogIn,Channel0).

NextwecansetdifferentProperties,suchas“InputRange”,“AcquisitionMode”,“ThermocoupleType”,etc.

Page 69: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

69 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

FinallyweseeaPreviewoftheUserInterfacebeforeitisautomaticallygeneratedbytheMeasurementStudio:

Page 70: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

70 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

Whenweclick“Finish”,theSolution,theProjectandUserInterfacewillbeautomaticallycreated.

Figure1:VisualStudioGeneratedSolution

FinallywecantesttheApplication:

Page 71: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

71 UsingMeasurementStudioTemplates

Tutorial:DataAcquisitioninC#

Withthisapproachwegeta“flyingstart”andwecanchangethecodeasweplease.Thedrawbackwiththisapproachisthatthecodethatisautomaticallygeneratedisalittlebit“messy”.

Soactually,thisisnotamethodIwillrecommendtouse.

Page 72: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

72

AppendixA:SourceCodeInthisAppendixthecompletesourcecodeforalltheexampleswillbelisted.

MyFirstDAQAppThecodeforthisapplicationisasfollows:

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

Page 73: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

73 AppendixA:SourceCode

Tutorial:DataAcquisitioninC#

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

ControlApplicationThecodeforthisapplicationisasfollows:

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

Page 74: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

74 AppendixA:SourceCode

Tutorial:DataAcquisitioninC#

//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",

Page 75: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

75 AppendixA:SourceCode

Tutorial:DataAcquisitioninC#

"myAOChannel", 0, 5, AOVoltageUnits.Volts ); AnalogSingleChannelWriter writer = new AnalogSingleChannelWriter(analogOutTask.Stream); writer.WriteSingleSample(true, analogDataOut); } } }

10.3 OPCReadusing 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 OPCWriteusing NationalInstruments; using NationalInstruments.Net; using System; using System.Collections.Generic;

Page 76: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

76 AppendixA:SourceCode

Tutorial:DataAcquisitioninC#

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

Page 77: Data Acquisition in CSharp - halvorsen.blog · 3 Table of Contents 1 Introduction ..... 6

DataAcquisitioninC#

Hans-PetterHalvorsen

Copyright©2017

E-Mail:[email protected]

Web:https://www.halvorsen.blog

https://www.halvorsen.blog