Transmitting structures to/from the PLC

System requirements:

Task

A structure is to be written to or read from the PLC by the Delphi application. The elements in the structure have different data types.

Description

Structure declaration in the PLC

TYPE PLCStruct
STRUCT
    valSmallint     : INT;
    valLongint      : DINT;
    valByte         : BYTE;
    valDouble       : LREAL;
    valSingle       : REAL;
END_STRUCT
END_TYPE

PLC program

PROGRAM MAIN
VAR 
    PLCVar : PLCStruct;
END_VAR
;

Structure declaration in Delphi

Type VBStruct
    TPLCStruct = packed record      // packed == force 1 byte alignment
    valSmallint     : Smallint;     // 2 bytes
    valLongint      : Longint;      // 4 bytes
    valByte         : Byte;         // 1 byte
    valDouble       : Double;       // 8 bytes
    valSingle       : Single;       // 4 bytes// = 19 bytes in memory 
End;

Delphi 7 program

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OleCtrls, ADSOCXLib_TLB, StdCtrls;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    AdsOcx1: TAdsOcx;
    btnWrite: TButton;
    btnRead: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    editSmallint: TEdit;
    editLongint: TEdit;
    editByte: TEdit;
    editDouble: TEdit;
    editSingle: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnWriteClick(Sender: TObject);
    procedure btnReadClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
   TPLCStruct = packed record // packed == force 1 byte alignment
      valSmallint : Smallint; // 2 bytes
      valLongint  : Longint;  // 4 bytes
      valByte     : Byte;     // 1 byte
      valDouble   : Double;   // 8 bytes
      valSingle   : Single;   // 4 bytes// = 19 bytes in memory 
End;

var
  Form1: TForm1;
  hVar : Integer;

  // Create instance and initialize delphi structure members
  PLCStruct : TPLCStruct = ( valSmallint : 1000;
               valLongint : 100000;
               valByte : 100;
               valDouble : 3.1415;
               valSingle : 3.14 );
implementation
{$R *.dfm}

//--- Is called a the start ---
procedure TForm1.FormCreate(Sender: TObject);
var text : String;
begin
   //--- Enable exception ---
   AdsOcx1.EnableErrorHandling := True;
   //--- Set connection ---
   AdsOcx1.AdsAmsServerPort := 801;
   AdsOcx1.AdsAmsServerNetId := AdsOcx1.AdsAmsClientNetId;
   //--- Get PLC variable handle by variable name
   AdsOcx1.AdsCreateVarHandle('Main.PLCVar', hVar);
   //--- View init values ---
   Str( PLCStruct.valSmallint, text );
   editSmallint.Text := text;
   Str( PLCStruct.valLongint, text );
   editLongint.Text := text;
   Str( PLCStruct.valByte, text );
   editByte.Text := text;
   Str( PLCStruct.valDouble : 0 : 15, text );
   editDouble.Text := text;
   Str( PLCStruct.valSingle : 0 : 8, text );
   editSingle.Text := text;
end;

//--- Is called at the end ---
procedure TForm1.FormDestroy(Sender: TObject);
begin
   //--- Release PLC variable handle ---
   AdsOcx1.AdsDeleteVarHandle(hVar);
end;

//--- Is called by the user  ---
procedure TForm1.btnWriteClick(Sender: TObject);
var code : Integer;
begin
   //--- Fill structure ---
   Val( editSmallint.Text, PLCStruct.valSmallint, code );
   Val( editLongint.Text, PLCStruct.valLongint, code );
   Val( editByte.Text, PLCStruct.valByte, code );
   Val( editDouble.Text, PLCStruct.valDouble, code );
   Val( editSingle.Text, PLCStruct.valSingle, code );
   //--- Write structure to the PLC ---
   AdsOcx1.AdsSyncWriteIntegerVarReq( hVar, sizeof(PLCStruct), PLCStruct.valSmallint );
end;

//--- Is called by the user ---
procedure TForm1.btnReadClick(Sender: TObject);
var text : String;
begin
   //--- Read structure from the PLC ---
   AdsOcx1.AdsSyncReadIntegerVarReq( hVar, sizeof(PLCStruct), PLCStruct.valSmallint );
   //--- View read structure data ---
   Str( PLCStruct.valSmallint, text );
   editSmallint.Text := text;
   Str( PLCStruct.valLongint, text );
   editLongint.Text := text;
   Str( PLCStruct.valByte, text );
   editByte.Text := text;
   Str( PLCStruct.valDouble : 0 : 15, text );
   editDouble.Text := text;
   Str( PLCStruct.valSingle : 0 : 8, text );
   editSingle.Text := text;
end;

Initialization
   IsMultiThread := True;// Setting this system variable makes Delphi's memory manager thread-safe

end.

Language / IDE

Unpack sample program

Delphi XE2

Sample08.exe

Delphi 7 or higher (classic)