Consumer in C# to read and write PLC variables
This sample explains how to create an ADS-WebService-Consumer to read and write PLC-Variables via ADS-HTTP.
Creating a WebService-Consumers within the Microsoft VisualStudio.NET
In Visual Studio select "New Project" and create a new C# - Windows Application.
- By selecting the template "Windows-Application" the new application is only running on .NET-platforms.
- By selecting the template "Smart Device Application" the new application is running on .NET-platforms and on .NET-CompactFramework (CE-) platforms.
By selecting the .NET-CompactFramework (CE-) platform restrictions may occure.
After creating the projects go to "Projects" "Add Web Reference...".
In the following dialog you may insert the URL of the WebService-WSDL-file or you can browse for it by clicking on "Web services on the local machine".
Name the reference and click the button "Add Reference" to complete .
To catch SOAP-Exceptions add the following line to the first lines of the source-code:
using System.Web.Services.Protocols;
To create a WebService-object insert the following line after "public class NameOfYourForm: System.Windows.Forms.Form":
TcAdsWebService.TcAdsWebService TcWebService = new TcAdsWebService.TcAdsWebService();
Add the following line in the constructor ("public NameOfYourForm") after "InitializeComponent();":
TcWebService.Url = "http://localhost/TcAdsWebService/TcAdsWebService.dll";
// Sample 1 :
TcWebService.Url = "http://192.168.0.2/TcAdsWebService/TcAdsWebService.dll";
// Sample 2 :
TcWebService.Url = "http://CX_xxxxxx/TcAdsWebService/TcAdsWebService.dll";
The address must be the URL of your TwinCAT ADS WebService-DLL-file.
Converting variables to byte-arrays
Variables must be converted to byte-arrays if they should be used with the ADS-WebService. Therefore it is necessary to be able to convert variables to byte-arrays and vice versa:
This could be realized with the BitConverter-class:
byte[] abDataBool = new byte[1];
abDataBool = BitConverter.GetBytes(bValueBool);
byte[] abDataInt = new byte[2];
abDataInt = BitConverter.GetBytes((Int16)iValueInt)
In this example a "bool"- and an "int"-variable were converted to byte-arrays.
To convert a byte-array back to a variable use the BitConverter-class as followed:
byte[] abDataBuffer = new byte[3];
bool bVarBool = BitConverter.ToBoolean(abDataBuffer,0);
int iVarInt = BitConverter.ToInt16(abDataBuffer,1);
Strings are converted with the the "ASCII-Encoder":
string szValueString;
byte[] abDataString = new byte[81];
System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();
encoder.GetBytes(szValueString, 0, encoder.GetByteCount(szValueString), abDataString, 0);
To convert a byte-array back to a string use the following code:
byte[] abDataBuffer = new byte[81];
System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();
string VarString = encoder.GetString(abDataBuffer, 3, 81);
You can get more detailed information about this methods and classes in literature for C#-Application-Developement.
Reading PLC-variables
To read a PLC-Variable use the "read"-method of the WebService-object:
WebService.Read(string netId, int nPort,
System.UInt32 indexGroup, System.UInt32 indexOffset, int cblen, out
System.Byte[] ppData);
- string netId: String indicating the AMS-Net-Id of the PLC
- int nPort: Port-number of the Runtime-System
- System.UInt32 indexGroup: IndexGroup of the variables to read
- System.UInt32 indexOffset: First byte to read
- int cblen: Number of bytes to read
- out System.Byte[] ppData: Byte-array to save the PLC-data into
Example:
try
{
TcWebService.Read("192.168.0.2.1.1", 801, 0x4020, 0, 84, out abDataBuffer);
}
catch (SoapException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Writing PLC-variables
To write a PLC-Variable use the "write"-method of the WebService-object:
WebService.Write(string netId, int nPort,
System.UInt32 indexGroup, System.UInt32 indexOffset, System.Byte[]
pData);
- string netId: String indicating the AMS-Net-Id of the PLC
- int nPort: Port-number of the Runtime-System
- System.UInt32 indexGroup: IndexGroup of the variable
- System.UInt32 indexOffset: First byte to write to
- System.Byte[] pData: Byte-array containing the data to write
Example:
byte[] Data = new byte[10];
try
{
TcWebService.Write("192.168.0.2.1.1", 801, 0x4020, 0, Data);
}
catch (SoapException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Sample-Application:
PLC-program, IEC1131 declaration of the variables
PROGRAM MAIN
VAR
PlcVarBool AT %MX0.0 : BOOL := TRUE;
PlcVarInt AT %MW1 : INT := 1234;
PlcVarString AT %MD3 : STRING := 'Hello Automation';
END_VAR
C#-Application, the layout :
The source-code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Web.Services.Protocols; // Catches the SoapExceptions
namespace WebServiceTestConsumer
{
public class frmWebServiceTestConsumer : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
#region forms
private System.Windows.Forms.Label lblBool;
private System.Windows.Forms.Label lblInt;
private System.Windows.Forms.Label lblString;
private System.Windows.Forms.TextBox txtBool;
private System.Windows.Forms.TextBox txtInt;
private System.Windows.Forms.TextBox txtString;
private System.Windows.Forms.Button btnRead;
private System.Windows.Forms.Button btnWrite;
#endregion
#region variables and instances
// Encodes byte-array to Strings and vice versa
private System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();
// Instance of the TcAdsWebService
private TcAdsWebService.TcAdsWebService TcWebService = new TcAdsWebService.TcAdsWebService();
private string szWebServiceUrl = "http://192.168.0.2/TcAdsWebService/TcAdsWebService.dll";
public string szAmsNetId = "192.168.0.2.1.1";
public int iPort = 801;
public UInt32 iIndexGroup = 0x4020;
#endregion
public frmWebServiceTestConsumer()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// Links the WebService with its library
TcWebService.Url = szWebServiceUrl;
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.lblBool = new System.Windows.Forms.Label();
this.lblInt = new System.Windows.Forms.Label();
this.lblString = new System.Windows.Forms.Label();
this.txtBool = new System.Windows.Forms.TextBox();
this.txtInt = new System.Windows.Forms.TextBox();
this.txtString = new System.Windows.Forms.TextBox();
this.btnRead = new System.Windows.Forms.Button();
this.btnWrite = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// lblBool
//
this.lblBool.Location = new System.Drawing.Point(40, 24);
this.lblBool.Name = "lblBool";
this.lblBool.TabIndex = 0;
this.lblBool.Text = "VarBool:";
//
// lblInt
//
this.lblInt.Location = new System.Drawing.Point(40, 80);
this.lblInt.Name = "lblInt";
this.lblInt.TabIndex = 1;
this.lblInt.Text = "VarInt:";
//
// lblString
//
this.lblString.Location = new System.Drawing.Point(40, 136);
this.lblString.Name = "lblString";
this.lblString.TabIndex = 2;
this.lblString.Text = "VarString:";
//
// txtBool
//
this.txtBool.Location = new System.Drawing.Point(152, 24);
this.txtBool.Name = "txtBool";
this.txtBool.TabIndex = 3;
this.txtBool.Text = "";
//
// txtInt
//
this.txtInt.Location = new System.Drawing.Point(152, 80);
this.txtInt.Name = "txtInt";
this.txtInt.TabIndex = 4;
this.txtInt.Text = "";
//
// txtString
//
this.txtString.Location = new System.Drawing.Point(152, 136);
this.txtString.Name = "txtString";
this.txtString.TabIndex = 5;
this.txtString.Text = "";
//
// btnRead
//
this.btnRead.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnRead.Location = new System.Drawing.Point(48, 216);
this.btnRead.Name = "btnRead";
this.btnRead.TabIndex = 6;
this.btnRead.Text = "&Read";
this.btnRead.Click += new System.EventHandler(this.btnRead_Click);
//
// btnWrite
//
this.btnWrite.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnWrite.Location = new System.Drawing.Point(168, 216);
this.btnWrite.Name = "btnWrite";
this.btnWrite.TabIndex = 7;
this.btnWrite.Text = "&Write";
this.btnWrite.Click += new System.EventHandler(this.btnWrite_Click);
//
// frmWebServiceTestConsumer
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.lblBool);
this.Controls.Add(this.lblInt);
this.Controls.Add(this.lblString);
this.Controls.Add(this.txtBool);
this.Controls.Add(this.txtInt);
this.Controls.Add(this.txtString);
this.Controls.Add(this.btnRead);
this.Controls.Add(this.btnWrite);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmWebServiceTestConsumer";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "WebServiceTestConsumer";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new frmWebServiceTestConsumer());
}
#region Event-Methods
private void btnRead_Click(object sender, System.EventArgs e)
{
Read();
}
private void btnWrite_Click(object sender, System.EventArgs e)
{
Write();
}
#endregion
#region Worker-Methods
private void Read()
{
// DataBuffer for the incoming data
byte[] abDataBuffer = new byte[84]; //1 byte for "PlcVarBool", 2 bytes for "PlcVarInt" and 81 bytes for "PlcVarString" = 84 bytes
try
{
TcWebService.Read( szAmsNetId, iPort, iIndexGroup, 0, 84, out abDataBuffer);
// Converts the first byte of the buffer to bool
bool bVarBool = BitConverter.ToBoolean(abDataBuffer, 0);
// Converts the second and third byte of the buffer to int
int iVarInt = BitConverter.ToInt16(abDataBuffer, 1);
// Converts the other bytes of the buffer to string
string szVarString = encoder.GetString(abDataBuffer, 3, 81);
// Writes values into the text-boxes
txtBool.Text = bVarBool.ToString();
txtInt.Text = iVarInt.ToString();
txtString.Text = szVarString;
}
catch (SoapException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Write()
{
try
{
// byte-arrays for the variables
byte[] abDataBool = new byte[1];
byte[] abDataInt = new byte[2];
byte[] abDataString = new byte[81];
// Gets values for the text-boxes
bool bValueBool = Convert.ToBoolean(txtBool.Text);
int iValueInt = Convert.ToInt16(txtInt.Text);
string szValueString = txtString.Text;
// Converting variables to byte-arrays
abDataBool = BitConverter.GetBytes(bValueBool);
abDataInt = BitConverter.GetBytes((Int16)iValueInt);
encoder.GetBytes( szValueString, // Source
0, // Position of the first character to convert
encoder.GetByteCount(szValueString), // Gets the length of the source
abDataString, // Byte-array to save the conversion to
0); // First byte in the array to save the conversion to
// Writing values to PLC
TcWebService.Write(szAmsNetId, iPort, iIndexGroup, 0, abDataBool);
TcWebService.Write(szAmsNetId, iPort, iIndexGroup, 1, abDataInt);
TcWebService.Write(szAmsNetId, iPort, iIndexGroup, 3, abDataString);
}
catch (SoapException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
}
}
Language / IDE | Extract the sample program |
---|---|
Visual C# |