Consumer in Delphi 8 for .NET to read and write PLC variables
The example explains how to create an ADS-Web Service consumer for reading and writing PLC variables via ADS-HTTP.
Requirements:
- Delphi 8 for Microsoft .NET framework;
- Web service consumer for Windows XP platform (Windows Forms .NET application);
- Web service server was configured on an Embedded PC: CX9000 configured with Windows CE (ARM).
Import into Delphi
The server interface description is published in a WSDL file (Web Service Definition Language). The WSDL description is imported into Delphi and converted by Delphi into Delphi units.
First of all create a new project (Windows Forms application Delphi .NET). Save the project. You can now import the WSDL file. In the Project Manager, right click with the mouse on the project name and select “Add Web Reference”.
A dialog opens showing Web service directories from IBM, Microsoft etc. However, we want to open the WSDL file from the data storage device.
The WSDL files from the TwinCAT ADS Web service can be found in the folder: ..TwinCAT\Ads API\TcAdsWebService\V100\... Navigate to the appropriate folder and select the WSDL file. In our case it is the WSDL file from the folder for the Windows CE (ARM) target platform.
There is no difference between the WSDL files for the XP/CE (X86 or ARM) platforms. I.e. it is always the same WSDL file. You can integrate the WSDL file from the CE/ARM folder in your consumer project and nonetheless still communicate with an ADS Web Service server on an XP platform.
The contents of the WSDL file are displayed in a dialog box.
Select “Add Web Reference”. The required units are generated automatically and added to the project.
Using the web service
In order to be able to use the web service you must integrate the web service unit in the main window unit. You can take the opportunity at the same time to integrate two further units that you will need in your project later: System.Text and System.Web.Services.Protocols
uses
System.Drawing, System.Collections, System.ComponentModel,
System.Windows.Forms, System.Data,
WebReference.TcAdsWebService, System.Text,System.Web.Services.Protocols;
Now you can create an ADS Web service instance.
private
{ Private Declarations }
TcWebService : WebReference.TcAdsWebService.TcAdsWebService;
And in the TwinForm constructor:
TcWebService := WebReference.TcAdsWebService.TcAdsWebService.Create();
The code completion will help you further. Type in TcWebService with a dot and look at the methods which are available.
We use the following methods in our example:
- Read for reading the PLC variables;
- Write for writing the PLC variables;
- ReadState for reading the PLC server status;
- WriteControl to change the PLC server status;
type TArrayOfByte = array of Byte;
procedure Read(netId: string; nPort: Integer; indexGroup: Cardinal; indexOffset: Cardinal; cbLen: Integer; out ppData: TArrayOfByte);
procedure Write(netId: string; nPort: Integer; indexGroup: Cardinal; indexOffset: Cardinal; pData: TArrayOfByte);
procedure ReadState(netId: string; nPort: Integer; out pAdsState: Integer; out pDeviceState: Integer);
procedure WriteControl(netId: string; nPort: Integer; adsState: Integer; deviceState: Integer; pData: TArrayOfByte);
netId: String with the network address of the TwinCAT target system. In our case the TwinCAT AMS NetID of the PC with the PLC runtime system;
nPort: TwinCAT ADS port number of the PLC runtime system;
indexGroup: Index group of the PLC variables to be read;
indexOffset: Index offset (byte-/bit offset) of the PLC variables to be read;
cbLen: Number of bytes which are to be read;
ppData: Variable in which the read data is saved (dynamic byte array);
pData: Variable with the data to be written (dynamic array);
adsState / pAdsState: PLC server status.
deviceState / pDeviceState: PLC device status;
The PLC application
PROGRAM MAIN
VAR
VarBool AT %MX0.0: BOOL := TRUE;
VarInt AT %MB1: INT := 123;
VarString AT %MB3: STRING := 'Hello Automation';
END_VAR
Read PLC variables
procedure TWinForm.ReadData();
var cbLen, nIG, nIO : Integer;
data : TArrayOfByte;
begin
try
// read BOOL at adress AT%MX0.0
nIG := $4021;
nIO := 0;
cbLen := SizeOf(varBool);
TcWebService.Read( sNetID, iPort, nIG, nIO, cbLen, data );
varBool := BitConverter.ToBoolean(data, 0);
// read INT at adress AT%MB1
nIG := $4020;
nIO := 1;
cbLen := SizeOf(varInt);
TcWebService.Read( sNetID, iPort, nIG, nIO, cbLen, data );
varInt := BitConverter.ToInt16(data, 0);
// read STRING at adress AT%MB3
nIG := $4020;
nIO := 3;
cbLen := 81;
TcWebService.Read( sNetID, iPort, nIG, nIO, cbLen, data );
varString := System.Text.Encoding.Default.GetString(data,0, Length(data));
except
On E:SoapException do
HandleSoapException(E.Message, E.HelpLink, E.Detail.InnerText);
end;
end;
Write PLC variables
procedure TWinForm.WriteData();
var data : TArrayOfByte;
cbLen, nIG, nIO : Integer;
begin
try
// write BOOL at adress AT%MX0.0
nIG := $4021;
nIO := 0;
data := BitConverter.GetBytes(varBool);
TcWebService.Write( sNetID, iPort, nIG, nIO, data );
// write INT at adress AT%MB1
nIG := $4020;
nIO := 1;
data := BitConverter.GetBytes(varInt);
TcWebService.Write( sNetID, iPort, nIG, nIO, data );
// write STRING at adress AT%MB3
nIG := $4020;
nIO := 3;
cbLen := System.Text.Encoding.Default.GetByteCount(varString);
// Allocate one byte more! We need it to write the string end delimiter!.
SetLength(data, cbLen + 1);
System.Text.Encoding.Default.GetBytes( varString, 0, cbLen, data, 0);
data[cbLen] := 0;
TcWebService.Write( sNetID, iPort, nIG, nIO, data );
except
On E:SoapException do
HandleSoapException(E.Message, E.HelpLink, E.Detail.InnerText);
end;
end;
Read PLC status
procedure TWinForm.ReadState();
var adsState, deviceState : Integer;
sState : String;
begin
try
TcWebService.ReadState( sNetID, iPort, adsState, deviceState );
case adsState of
PLC_ADSSTATE_RUN:
sState := 'RUN';
PLC_ADSSTATE_STOP:
sState := 'STOP';
else
sState := 'OTHER';
end;
StatusBar1.Panels.Item[0].Text := 'PLC server state: ' + sState;
except
On E:SoapException do
HandleSoapException(E.Message, E.HelpLink, E.Detail.InnerText);
end;
end;
Start/stop PLC
procedure TWinForm.WriteControl(adsState : Integer);
begin
try
TcWebService.WriteControl( sNetID, iPort, adsState, 0, nil );
except
On E:SoapException do
HandleSoapException(E.Message, E.HelpLink, E.Detail.InnerText);
end;
end;
Language / IDE | Extract the sample program |
---|---|
Delphi 8 for .NET |