Accessing an array in the PLC
Download
Language / IDE | Unpack the example program |
---|---|
Visual C# | |
Visual Basic (for .NET Framework) | |
Delphi Prism (Embarcadero Prism XE2, Oxygene for .NET) | |
Delphi for .NET (Borland Developer Studio 2006) |
Task
The PLC contains an array that is to be read by the .Net application using a read command.
Description
The PLC contains an array of 100 elements of type integer (2 bytes). The array in the PLC is to be filled with the values from 3500 to 3599.
In the Form1_Load event method a new instance of the class TcAdsClient is created. Then the method TcAdsClient.Connect of the TcAdsClient object is called to establish a connection to the port 801. Finally the method TcAdsClient.CreateVariableHandle is used to fetch the handle of the PLC variable. When the program finishes, this handle is released in the Form1_Closing event method and the Dispose method of the TcAdsClient object is called.
When the user clicks the button on the form, the entire array is read from the PLC into the AdsStream dataStream by means of the TcAdsClient.Read method. The stream should be of the same size as the data in the SPS. Because we want to read 100 INTs (each 2 Bytes), the stream must be able to hold at least 2 * 100 Bytes.
The class System.IO.BinaryReader is necessary to read the individual fields of the array. First the position of the stream has to be set to 0. Then the individual fields of the array can be read by calling the method BinaryReader.ReadInt16 in a for loop. The position pointer of the stream is incremented automatically by the bytes ( in this case 2) that have been read.
C# program
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using TwinCAT.Ads;
using System.IO;
namespace Sample01
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnRead;
private System.ComponentModel.Container components = null;
private System.Windows.Forms.ListBox lbArray;
private int hVar;
private TcAdsClient tcClient;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing ) ...
private void InitializeComponent() ...
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
// Create instance of class TcAdsClient
tcClient = new TcAdsClient();
// Connect to local PLC - Runtime 1 - TwinCAT2 Port=801, TwinCAT3 Port=851
tcClient.Connect(801);
try
{
hVar = tcClient.CreateVariableHandle("MAIN.PLCVar");
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}
private void btnRead_Click(object sender, System.EventArgs e)
{
try
{
// AdsStream which gets the data
AdsStream dataStream = new AdsStream(100 * 2);
BinaryReader binRead = new BinaryReader(dataStream);
//read comlpete Array
tcClient.Read(hVar,dataStream);
lbArray.Items.Clear();
dataStream.Position = 0;
for(int i=0; i<100; i++)
{
lbArray.Items.Add(binRead.ReadInt16().ToString());
}
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
//enable resources
try
{
tcClient.DeleteVariableHandle(hVar);
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
tcClient.Dispose();
}
}
}
PLC program
PROGRAM MAIN
VAR
PLCVar : ARRAY [0..99] OF INT;
Index: BYTE;
END_VAR
FOR Index := 0 TO 99 DO
PLCVar[Index] := 3500 + INDEX;
END_FOR