SNAP 7

Per poter utilizzare questi esempi bisogna aggiungere al progetto "Snap7.PAS" e anche la Snap7.DLL. Volendo la Snap7.DLL si può anche aggiungere in Windows Sistem.
Scarica Snap7.PAS
e Snap7.DLL per la versione a 32 bit per Win32 o Snap7.DLL per la versione a 64 bit per Win64

 

Come scrivere e leggere un valore REAL con SNAP 7

// ESEMPIO SCRITTO da Mauro Rubinetti Sito www.delphiruby.net


unit Snap7_real;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, shellapi, snap7;

type
TForm1 = class(TForm)
LOG1: TMemo;
Legge_DBREAL: TButton;
SCRIVI_REAL: TButton;
Edit_DBD12: TEdit;
VAL_LETTI: TEdit;
Label1: TLabel;
CheckBox1: TCheckBox;
Label2: TLabel;
Label3: TLabel;
Shape1: TShape;
Shape2: TShape;
Edit_DBD16: TEdit;
Button1: TButton;
Edit_DBD20: TEdit;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
DBD: TEdit;
Label9: TLabel;
Label10: TLabel;
Shape3: TShape;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Legge_DBREALClick(Sender: TObject);
procedure SCRIVI_REALClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Label6Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
PLC1 : TS7Client;

implementation

{$R *.dfm}
// Creo il mio client (PLC1)
procedure TForm1.FormCreate(Sender: TObject);
begin
PLC1:=TS7Client.Create;
PLC1.ConnectTo('192.168.0.2',0,2); // indirizzo PLC a cui punto
end;

// alla chiusura del programma distruggo il client creato.
procedure TForm1.FormDestroy(Sender: TObject);
begin
PLC1.Destroy;
end;

procedure TForm1.Legge_DBREALClick(Sender: TObject);
var
// Creiamo il Buffer della grandezza ottimale es. "packed array[0..15] of Byte
// per leggere un real ci voglio 4 byte per cui [0..3] per 2 [0..7] ecc.

DatiPLCREAL: packed array[0..15] of single;
I: Integer;
Errore: Integer;
MyReal: single; // max 4 byte
N_BYTE: Integer;
BYTE_START : Integer;
ValoriLETTURA : Integer;

begin
ValoriLETTURA := strtoint(VAL_LETTI.Text);
N_BYTE := ValoriLETTURA * sizeof(single);
ValoriLETTURA := ValoriLETTURA-1; // Per il calcolo for / next parto da 0


if not Plc1.Connected then // se il PLC non risponde esco
begin
showmessage('PLC NON RISPONDE VERIFICARE INDIRIZZO TCP-IP E CHE IL PLC SIA ACCESO')
end;
BYTE_START := strtoint (DBD.Text);

Errore := Plc1.DBRead(1, // Numero della DB
BYTE_START, // Da byte della DB partimo a leggere
N_BYTE , // Quanti byte vogliamo leggere
@DatiPLCREAL); // Array dove voglio mettere i valori letti

if Errore <> 0 then
begin
Log1.Lines.Add(Trim(CliErrorText(Errore))); // Scrive un eventuale errore
Exit;
end;

// scrivo il valore di ogni singolo bytes dei 4 che compongono un real
if checkbox1.Checked then
begin
Log1.Lines.add( 'Informazione su byte letti:');
for I := 0 to N_BYTE -1 do
begin
Log1.Lines.add('[Byte ' + inttostr(I) + ']: ' + floattostr(DatiPLCREAL[I]));
end;
end;

// Aggiungo al memo i valori convertiti in interi
Log1.Lines.add('Valori reali della nostra DB letta:');
for I := 0 to ValoriLETTURA do
begin
// LEGGIAMO UN VALORE REALE CHE OCCUPA 4 BYTE
// UTILIZZIAMO LA FUNZIONE s7.ValReal
MyReal:= S7.ValReal[@DatiPLCREAL[I]];
Log1.Lines.add('[DB1.DBD' + inttostr (BYTE_START)+' ]: ' + floattostr(MyReal));
BYTE_START := BYTE_START +4;
end;
end;


/////////////////////////////////////////////////////////////////////////////
// TEST SCRITTURA DI UN REAL
////////////////////////////////////////////////////////////////////////////

procedure TForm1.SCRIVI_REALClick(Sender: TObject);
var
// Creiamo il Buffer della grandezza ottimale es. "packed array[0..15] of Byte
DatiPLCREAL: packed array[0..15] of single;
MyReal: single;
N_Byte_write : Integer;
begin
if not Plc1.Connected then // se il PLC non risponde esco
begin
showmessage('PLC NON RISPONDE VERIFICA INDIRIZZO TCP-IP E CHE IL PLC SIA ACCESO')
end;

MyReal:=StrToFloat(edit_DBD12.Text); // Trasformo in float quanto scritto nella EDIT
S7.ValReal[@DatiPLCREAL[0]]:= MyReal; // Metto nell'array il valoire convertito da S7.ValReal
N_Byte_write := SizeOf(MyReal); // calcolo la lunghezza dei byte usati (SizeOf di Real = 4)

Plc1.DBWrite(1, // Numero della DB da scrivere
12, // Da quale byte della DB partimo a leggere
N_Byte_write, // Quanti byte vogliamo scrivere (REAL = 4)
@DatiPLCREAL[0]); // Array dove voglio mettere i valori letti

// PLC1.DBWrite(1,12,N_Byte_write,@DatiPLCREAL[0]);// per scrivere un real N_BYTE_WRITE =4
end;

/////////////////////////////////////////////////////////////////////////////
// TEST SCRITTURA DI 2 REAL
////////////////////////////////////////////////////////////////////////////

procedure TForm1.Button1Click(Sender: TObject);
var
DatiPLCREAL: packed array[0..15] of single;
MyReal1, MyReal2: single;
N_Byte_write : Integer;
begin
if not Plc1.Connected then // se il PLC non risponde esco
begin
showmessage('PLC NON RISPONDE VERIFICA INDIRIZZO TCP-IP E CHE IL PLC SIA ACCESO')
end;
MyReal1:=StrToFloat(edit_DBD16.Text);
MyReal2:=StrToFloat(edit_DBD20.Text);
S7.ValReal[@DatiPLCREAL[0]]:= MyReal1;
S7.ValReal[@DatiPLCREAL[1]]:= MyReal2;
N_Byte_write := SizeOf(MyReal1); // calcolo la lunghezza dei byte usati
PLC1.DBWrite(1,16,N_Byte_write,@DatiPLCREAL[0]);// per scriver un real N_BYTE_WRITE =4
PLC1.DBWrite(1,20,N_Byte_write,@DatiPLCREAL[1]);// per scriver un real N_BYTE_WRITE =4

// con una funzione FOR / NEXT posso scrivere quanti valori voglio

end;
end.

 

Come scrivere e leggere un valore DINT con SNAP 7

// ESEMPIO IN Delphi scritto da Mauro Rubinetti
// www.delphiruby.net

unit Snap7_dint;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, shellapi, snap7;

type
TForm1 = class(TForm)
LOG1: TMemo;
Legge_DBREAL: TButton;
SCRIVI_REAL: TButton;
Edit_DBD0: TEdit;
VAL_LETTI: TEdit;
Label1: TLabel;
CheckBox1: TCheckBox;
Label2: TLabel;
Label3: TLabel;
Shape1: TShape;
Shape2: TShape;
Edit_DBD4: TEdit;
Button1: TButton;
Edit_DBD8: TEdit;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
DBD: TEdit;
Label9: TLabel;
Shape3: TShape;
Label10: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Legge_DBREALClick(Sender: TObject);
procedure SCRIVI_REALClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Label6Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
PLC1 : TS7Client;

implementation


{$R *.dfm}
// Creo il mio client (PLC1)

procedure TForm1.FormCreate(Sender: TObject);
begin
PLC1:=TS7Client.Create;
PLC1.ConnectTo('192.168.0.2',0,2); // indirizzo PLC a cui punto
end;

// alla chiusura del programma distruggo il client creato.
procedure TForm1.FormDestroy(Sender: TObject);
begin
PLC1.Destroy;
end;

procedure TForm1.Legge_DBREALClick(Sender: TObject);
var
// Creiamo il Buffer della grandezza ottimale es. "packed array[0..15] of Byte
// per leggere un real ci voglio 4 byte per cui [0..3] per 2 [0..7] ecc.

DatiPLCDINT: packed array[0..10] of single;
I: Integer;
Errore: Integer;
MyDint: single; // max 4 byte
N_BYTE: Integer;
BYTE_START : Integer;
ValoriLETTURA : Integer;

begin
ValoriLETTURA := strtoint(VAL_LETTI.Text);
N_BYTE := ValoriLETTURA * sizeof(single);
ValoriLETTURA := ValoriLETTURA-1; // Per il calcolo for / next parto da 0


if not Plc1.Connected then // se il PLC non risponde esco
begin
showmessage('PLC NON RISPONDE VERIFICARE INDIRIZZO TCP-IP E CHE IL PLC SIA ACCESO')
end;
BYTE_START := strtoint (DBD.Text);

Errore := Plc1.DBRead(2, // Numero della DB
BYTE_START, // Da byte della DB partimo a leggere
N_BYTE , // Quanti byte vogliamo leggere
@DatiPLCDINT); // Array dove voglio mettere i valori letti

if Errore <> 0 then
begin
Log1.Lines.Add(Trim(CliErrorText(Errore))); // Scrive un eventuale errore
Exit;
end;

// scrivo il valore di ogni singolo bytes dei 4 che compongono un real
if checkbox1.Checked then
begin
Log1.Lines.add( 'Informazione su byte letti:');
for I := 0 to N_BYTE -1 do
begin
Log1.Lines.add('[Byte ' + inttostr(I) + ']: ' + floattostr(DatiPLCDINT[I]));
end;
end;

// Aggiungo al memo i valori convertiti in interi
Log1.Lines.add('Valori reali della nostra DB letta:');
for I := 0 to ValoriLETTURA do
begin
// LEGGIAMO UN VALORE INTERO CHE OCCUPA 4 BYTE
// UTILIZZIAMO LA FUNZIONE s7.ValDint

MyDint:= S7.ValDInt[@DatiPLCDINT[I]];
Log1.Lines.add('[DB1.DBD' + inttostr (BYTE_START)+' ]: ' + floattostr(MyDint));
BYTE_START := BYTE_START +4;
end;
end;


/////////////////////////////////////////////////////////////////////////////
// TEST SCRITTURA DI UN DINT
////////////////////////////////////////////////////////////////////////////

procedure TForm1.SCRIVI_REALClick(Sender: TObject);
var
// Creiamo il Buffer della grandezza ottimale es. "packed array[0..15] of Byte
DatiPLCDINT: packed array[0..15] of single;
MyDint: Longint;
N_Byte_write : Integer;
begin
if not Plc1.Connected then // se il PLC non risponde esco
begin
showmessage('PLC NON RISPONDE VERIFICA INDIRIZZO TCP-IP E CHE IL PLC SIA ACCESO')
end;

MyDint:=StrToInt(edit_DBD0.Text); // Trasformo in float quanto scritto nella EDIT
S7.ValDint[@DatiPLCDINT[0]]:= MyDint; // Metto nell'array il valoire convertito da S7.ValReal
N_Byte_write := SizeOf(MyDint); // calcolo la lunghezza dei byte usati (SizeOf di Real = 4)

Plc1.DBWrite(2, // Numero della DB da scrivere
0, // Da quale byte della DB partimo a leggere
N_Byte_write, // Quanti byte vogliamo scrivere (REAL = 4)
@DatiPLCDINT[0]); // Array dove voglio mettere i valori letti

// PLC1.DBWrite(1,12,N_Byte_write,@DatiPLCREAL[0]);// per scrivere un real N_BYTE_WRITE =4
end;

/////////////////////////////////////////////////////////////////////////////
// TEST SCRITTURA DI 2 DINT
////////////////////////////////////////////////////////////////////////////

procedure TForm1.Button1Click(Sender: TObject);
var
DatiPLCDINT: packed array[0..15] of single;
MyDint1, MyDint2: Int64;
N_Byte_write : Integer;
begin
if not Plc1.Connected then // se il PLC non risponde esco
begin
showmessage('PLC NON RISPONDE VERIFICA INDIRIZZO TCP-IP E CHE IL PLC SIA ACCESO')
end;
MyDint1:=StrToInt64(edit_DBD4.Text);
MyDint2:=StrToInt64(edit_DBD8.Text);
S7.ValDint[@DatiPLCDINT[0]]:= MyDint1;
S7.ValDint[@DatiPLCDINT[1]]:= MyDint2;
N_Byte_write := SizeOf(MyDint1); // calcolo la lunghezza dei byte usati
PLC1.DBWrite(2,4,N_Byte_write,@DatiPLCDINT[0]);// per scriver un real N_BYTE_WRITE =4
PLC1.DBWrite(2,8,N_Byte_write,@DatiPLCDINT[1]);// per scriver un real N_BYTE_WRITE =4

// con una funzione FOR / NEXT posso scrivere quanti valori voglio

end;
end.

 

Demo per testare le potenzialità di SNAP 7




   






Scaricate e testate questo piccolo programmino scritto in Delphi per testare le performance della libreria SNAP 7. Potrebbe tornare utile per fare delle letture di un qualsiasi PLC Siemens S7 300 / 400 oppure per comunicare con qualche PLC Siemens 1200 o 1500 e poi i dati, volendo li si possono salvare.

SCARICA IL PROGRAMMA:

Ricordate di scaricare anche la SNAP7.dll versione 32 o 64 bit a seconda del vostro sistema operativo e di copiarla nella cartella del programma di test oppure di copiarla nel windows/system32.































Note : Per poter leggere con SNAP 7 una DB da un PLC Siemens 1200 o 1500 la DB non dev'essere "ottimizzata" e deve aver abilitata la spunta che permette il "GET" e il "PUT"

 

 

Vai alla pagina:  indice, trucchi, programmi, snap7, esempi , relax .