We help IT Professionals succeed at work.

PRODAVE under Delphi (32-Bit) Example

pr2501
pr2501 asked
on
Medium Priority
2,783 Views
Last Modified: 2011-10-19

The code below needs for comunication with siemens PLC

my question is:
 if I need  to change color  of shape when an input of PLC swich from ziro to one to:
from red to green,

What procedure do i need?
To enable you to use the PRODAVE functions under Delphi, they must be
declared as follows:
function Load_tool ( no:Byte;
name: {pointer} PChar;
adr:{pointer} PChar):Integer;
stdcall;
external ´w95_s7.dll´ name ´load_tool´;
function DB_read ( dbno:Integer;
dwno:Integer;
var amount:Integer;
var buffer):Integer
stdcall;
external ´w95_s7.dll´ name ´db_read´;
function Unload_tool:Integer;
stdcall;
external ´w95_s7.dll´ name ´unload_tool´;
Example:
var
plc_adr_table : array [0..15] of byte;
name:array[0..255] of char;
res ,amount: integer;
buffer : array[0..255] of word;
plc_adr_table[0] := 2; {address}
plc_adr_table[1] := 0; {segment id}
plc_adr_table[2] := 2; {slotno}
plc_adr_table[3] := 0; {rackno}
plc_adr_table[4] := 0;
strcopy(name,'S7ONLINE');
res := Load_tool(1,addr(name),addr(plc_adr_table[0]));
res := DB_read(10,0,amount,buffer);
res := Unload_tool;

Open in new window

Comment
Watch Question

developmentguruPresident

Commented:
 Wow, the question is not really well worded.  I think what you meant to ask is, ' Which function (in the w95_s7.dll) would you need to call in order to change a color?'.  If you need it to change when something changes on the PLC then you first need to get it to fire an event back to your PC for Delphi to catch.  The basic question is how do you change the color, and you would need to ask the company that provided you the DLL.  You would also need to ask them how to get notified when the change takes place.  If the DBRead function returns data to you that would let you make your color change decision, then great.  You will still need to know the function call to make to change color.  If you were to give us a link to the documentation on the DLL then perhaps we could help.

  I spent some time retyping your code to make it easier to read.  Since I took the time to do that I figured it would not hurt to post it.  If my assumptions are wrong, let me know.  If you can link the DLL documentation, let me know.  Without more information I will just have to wait for more from you.
//To enable you to use the PRODAVE functions under Delphi, they must be
//declared as follows:
 
function Load_tool(no : Byte; name : PChar; adr : PChar) : Integer; stdcall; external ´w95_s7.dll´ name ´load_tool´;
 
function DB_read(dbno : Integer; dwno : Integer; var amount : Integer; var buffer) : Integer; stdcall; external ´w95_s7.dll´ name ´db_read´;
 
function Unload_tool : Integer; stdcall; external ´w95_s7.dll´ name ´unload_tool´;
 
procedure Example;
var
  plc_adr_table : array [0..15] of byte;
  name:array[0..255] of char;
  res ,amount: integer;
  buffer : array[0..255] of word;
 
begin
  plc_adr_table[0] := 2; {address}
  plc_adr_table[1] := 0; {segment id}
  plc_adr_table[2] := 2; {slotno}
  plc_adr_table[3] := 0; {rackno}
  plc_adr_table[4] := 0;
  strcopy(name,'S7ONLINE');
  res := Load_tool(1,addr(name),addr(plc_adr_table[0]));
  res := DB_read(10,0,amount,buffer);
  res := Unload_tool;
end;

Open in new window

Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
Simatic S7? if I remember correctly it has built-in OPC server I think it would be a lot easier to use dOPC library and connect to OPC server.
dOPC is paid but woth every penny.

ziolko.

Author

Commented:

From manuall:
In order to make PLC data
available for the PC application you will need a working and cost effective data
link between PLC and PC.
This is where the software package PRODAVE S7 will offer the solution.

And the link:
http://support.automation.siemens.com/WW/llisapi.dll?func=cslib.csinfo&lang=en&objid=21971420&caller=view



read.bmp

Author

Commented:
I have found this hint on the net:

"From Prodave You need to import one dll library in which all functions for connecting and exchaning data with PLC are stored".


lib.bmp
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
I'll take a look at link later this evening

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
ok,
I've looked at this document, first of all did you manage to connect to plc?
after sb_load() check if result is 0 otherwise see appendix of document for error codes,
next thing is reading value of specific signal
DB_read(10,0,amount,buffer);
10 and 0 are just sample values so you must know "address" of variable which value you want to read



ziolko.

Author

Commented:

 now i can monitor the  values.

 But i'm not setisfied because in cyicle read mode i have delay in value changing after state on input change.
Now i need
 to begin to work  with Delphi (my first post).

...to control this delay.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
>>...to control this delay.

what do you mean "control"?

ziolko.

Author

Commented:


  to measure how much time runs from the moment when  request was sent to the moment
when data returns.

now with Prodave i can detect delay (perhaps 1/2 second)
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
ok, so whats your next step that you need help with?

ziolko.

Author

Commented:


For oreintattion look at my first post.

now when i can work  with Prodave (siemens) i know that conection can be estabilished and data can be retrived.
 I recive byte:

exsample:
 01010101
   i woud like to monitor this bits  one by one: conect them with function  that  changes the color
of shape
 0 = red
 1=  green
 and refresh the monitoring in shorter time posible.

later i'll draw graph.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
ok,

lets say your return value is stored in  returnvalue variable of type: Byte;

procedure TForm1.Button6Click(Sender: TObject);
var returnvalue: Byte;
    f_bit: Byte;
    s_bit: Byte;
    t_bit: Byte;
    fr_bit: Byte;
    fi_bit: Byte;
    six_bit: Byte;
    sev_bit: Byte;
    e_bit: Byte;
begin
  fi_bit := 1;
  s_bit := 2;
  t_bit := 4;
  fr_bit := 8;
  fi_bit := 16;
  six_bit := 32;
  sev_bit := 64;
  e_bit := 128;

  if returnvalue and f_bit = f_bit then
    ShowMessage('first bit set');
  if returnvalue and s_bit = s_bit then
    ShowMessage('second bit set');
  if returnvalue and t_bit = t_bit then
    ShowMessage('third bit set');
  if returnvalue and fr_bit = fr_bit then
    ShowMessage('fourth bit set');
  if returnvalue and fi_bit = fi_bit then
    ShowMessage('fifth bit set');
  if returnvalue and six_bit = six_bit then
    ShowMessage('sixth bit set');
  if returnvalue and sev_bit = sev_bit then
    ShowMessage('seventh bit set');
  if returnvalue and e_bit = e_bit then
    ShowMessage('eight bit set');

end;

note that bits are numbered in reverse order, so
01010101  >> 8thbit = 1;7thbit = 1;6thbit = 0;5thbit =1;4thbit = 0;3rdbit = 1;2ndbit = 0;1stbit = 1
 
ziolko.

Author

Commented:


But how to inport dll?

Author

Commented:
I'll try to make all code from the code in my first post.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
import routine below, everytime you start your application w95_s7.dll will be loaded automatically,
note that w95_s7.dll must be in in same place as your exe file or in  \Windows\system32 folder

so once app starts succesfully you can use those function whereever you need

interface
...

function Load_tool ( no:Byte;name: PChar;adr:PChar):Integer;stdcall;
function DB_read ( dbno:Integer;dwno:Integer;var amount:Integer;var buffer):Integerstdcall;stdcall;
function Unload_tool:Integer;stdcall;

implementation

{$R *.dfm}

function Load_tool;external 'w95_s7.dll' name 'load_tool';
function DB_read;external 'w95_s7.dll' name 'db_read';
function Unload_tool;external 'w95_s7.dll' name 'unload_tool';

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
function DB_read ( dbno:Integer;dwno:Integer;var amount:Integer;var buffer):Integerstdcall;stdcall;
should be:
function DB_read ( dbno:Integer;dwno:Integer;var amount:Integer;var buffer):Integer;stdcall;

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
..btw
var returnvalue: Byte;
    f_bit: Byte;
    s_bit: Byte;
    t_bit: Byte;
    fr_bit: Byte;
    fi_bit: Byte;
    six_bit: Byte;
    sev_bit: Byte;
    e_bit: Byte;
begin
  f_bit := 1; // not fi_bit := 1;

ziolko.

Author

Commented:

i have copyed w95_s7.dll  in  \Windows\system32 folder

With code below
If i click on button i always get the same answer no mater if am connected or not:
 'sixth bit set'    
 'eight bit set'

unit Unit1;
 
interface
 
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1  ;
 
function Load_tool ( no:Byte;name: PChar;adr:PChar):Integer;stdcall;
function DB_read ( dbno:Integer;dwno:Integer;var amount:Integer;var buffer):Integer;stdcall;
function Unload_tool:Integer;stdcall;
 
implementation
 
{$R *.dfm}
 
function Load_tool;external 'w95_s7.dll' name 'load_tool';
function DB_read;external 'w95_s7.dll' name 'db_read';
function Unload_tool;external 'w95_s7.dll' name 'unload_tool';
 
 
 
procedure TForm1.Button1Click(Sender: TObject);
var returnvalue: Byte;
    f_bit: Byte;
    s_bit: Byte;
    t_bit: Byte;
    fr_bit: Byte;
    fi_bit: Byte;
    six_bit: Byte;
    sev_bit: Byte;
    e_bit: Byte;
  begin
f_bit := 1;
  s_bit := 2;
  t_bit := 4;
  fr_bit := 8;
  fi_bit := 16;
  six_bit := 32;
  sev_bit := 64;
  e_bit := 128;
 
  if returnvalue and f_bit = f_bit then
    ShowMessage('first bit set');
  if returnvalue and s_bit = s_bit then
    ShowMessage('second bit set');
  if returnvalue and t_bit = t_bit then
    ShowMessage('third bit set');
  if returnvalue and fr_bit = fr_bit then
    ShowMessage('fourth bit set');
  if returnvalue and fi_bit = fi_bit then
    ShowMessage('fifth bit set');
  if returnvalue and six_bit = six_bit then
    ShowMessage('sixth bit set');
  if returnvalue and sev_bit = sev_bit then
    ShowMessage('seventh bit set');
  if returnvalue and e_bit = e_bit then
    ShowMessage('eight bit set');
 
end;
 
end.

Open in new window

Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
where do you set value of: returnvalue?
returnvalue must be set to value returned by call to PLC,
when you call DB_Read() it will be probably in buffer param (4th parameter passed to db_read function)

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
for instance:

var
  ammount: LongInt;
  buffer: array[0.255] of Word;

Load_tool(1,addr(name),addr(plc_adr_table[0]));
DB_read(, , amount, buffer);
retrunvalue := buffer[0];
Unload_tool;


note that this is only pseudocode, to gei it working you must know:
Number of the data block to read
Start number of the first data word to be read

also size (so you can set ammount properly)

ziolko.

Author

Commented:

  I'll continue my work next week.
 thank you again.

Author

Commented:

  With shapes that a added i'll monitor the inputs on PLC.

 Now on with conection.

  if returnvalue and f_bit = f_bit then
    shape1.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and s_bit = s_bit then
     shape2.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and t_bit = t_bit then
  shape3.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and fr_bit = fr_bit then
   shape4.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and fi_bit = fi_bit then
     shape5.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and six_bit = six_bit then
   shape6.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and sev_bit = sev_bit then
     shape7.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if returnvalue and e_bit = e_bit then
 shape8.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;

Open in new window

changeShapeColor.bmp

Author

Commented:

from the picture (atached files)
i need help to set next parameters.
From the "read" picture i can see that my conections work.
I read binary : 00010101

        Load_tool ( 0,0,2);
        DB_read ( 1,0,2,255);

function Load_tool ( no:Byte;name: PChar;adr:PChar):Integer;stdcall;
function DB_read ( dbno:Integer;dwno:Integer;var amount:Integer;var buffer):Integer;stdcall;

load.bmp
read.bmp

Author

Commented:
 To be clear.

The conections was estabilished and data read from Prodave.
In Delphi i get errors while traying to work in next two lines:

         Load_tool ( 0,0,2);
        DB_read ( 1,0,2,255);


Author

Commented:

And this are the errors:

[Pascal Warning] Unit1.pas(74): W1013 Constant 0 converted to NIL
[Pascal Error] Unit1.pas(74): E2010 Incompatible types: 'Integer' and 'PAnsiChar'
[Pascal Error] Unit1.pas(75): E2033 Types of actual and formal var parameters must be identical
[Pascal Fatal Error] Project1.dpr(5): F2063 Could not compile used unit 'Unit1.pas'
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
Load_tool ( 0,0,2);
>>[Pascal Warning] Unit1.pas(74): W1013 Constant 0 converted to NIL
>>[Pascal Error] Unit1.pas(74): E2010 Incompatible types: 'Integer' and 'PAnsiChar'

well Load_tool function takes 3 parameters Integer and two PChar, and you pass 3 Integers that's why you get those errors look at sample you posted in question:

Load_tool(1,addr(name),addr(plc_adr_table[0]));
  addr(name) - is pointer (PChar) to
  addr(plc_adr_table[0]) - is pointer to address table

documentation states that as second param (pstrAccessPoint) you can pass 0 as parameter but "0" pointer in delphi is nil.



when it comes to second parameter (pConTable) well I haven't worked with Prodave and this documentation is not realy clear so I suggest to try it like in sample.


DB_read ( 1,0,2,255);
>>[Pascal Error] Unit1.pas(75): E2033 Types of actual and formal var parameters must be identical

third and fourth parameters are var params this mean you can't pass constatnt values like 2 or 255
again reffer to sample you posted in you question

btw. you wrote "The conections was estabilished and data read from Prodave."
post some code how did you do this

ziolko.

Author

Commented:


"To be clear.
The conections was estabilished and data read from Prodave."

this is my fast ansver.
i need some time to work on othe r things (parameters).

Author

Commented:
in last picture you may  see value which was read from PLC with Prodave: 00010101
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
yes, I can see it but how did you read this value if your code

Load_tool ( 0,0,2);
DB_read ( 1,0,2,255);

does not compile?

ziolko.

Author

Commented:

With:

var:
plc_adr_table : array [0..15] of byte;
  name:array[0..255] of char;
  res ,amount: integer;
  buffer : array[0..255] of word;

I have to use next two functions:

function Load_tool ( no:Byte;name: PChar;adr:PChar):Integer;stdcall;
Load_tool(?)

function DB_read ( dbno:Integer;dwno:Integer;var amount:Integer;var buffer):Integer;stdcall;
DB_read(?)

On my atached pictures are ilustrated parameters which works with prodave.
What number must i insert into brakets to make it work?
Load_tool(?)
DB_read(?)



Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
>>On my atached pictures are ilustrated parameters which works with prodave.
>>What number must i insert into brakets to make it work?

use same parameters as you used to make it work like on pictuers.

I don't understand what is your problem if you managed to connect and get values (like on picuters) why do you have problem now?
which functions did you use to make it work as on attached pictures?

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
on picture read.bmp there's value 00010101 where did it come from and how did you read this value?
if you did it once do it exactly same way but instead displaying it check value of bits you are interested in and change color of shapes or whatever you need

ziolko.

Author

Commented:
yes, I can see it but how did you read this value if your code

Load_tool ( 0,0,2);
DB_read ( 1,0,2,255);

does not compile?

ziolko.

 Anwer:
With Prodave:
prodave.bmp
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
ahh so you didn't do it with your delphi app?
ok so try this one:

type
  adr_table_type = packed record
    cAdr: Byte;
    cSegmentId: Byte;
    cSlotNo: Byte;
    cRackNo: Byte;
  end;

...

var add: adr_table_type;
    ammount: Integer;
    buff: array[0..1] of Word;
begin
  add.cAdr := 2;
  add.cSegmentId := 0;
  add.cSlotNo := 2;
  add.cRackNo := 2;
  Load_tool(1, 'S7ONLINE', PChar(@add));
  ammount := 2;
  DB_read(1, 0, ammount, buff);
  if buff[0] and 1 = 1 then
    ShowMessage('first bit is set');
end;


ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
should be:
add.cRackNo := 0;

ziolko.

Author

Commented:
I have attached error file:
Where must i insert next code :

type
  adr_table_type = packed record
    cAdr: Byte;
    cSegmentId: Byte;
    cSlotNo: Byte;
    cRackNo: Byte;
  end;

error.txt
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
this should be in initialization section of unit
type
  adr_table_type = packed record
    cAdr: Byte;
    cSegmentId: Byte;
    cSlotNo: Byte;
    cRackNo: Byte;
  end;

at which point error occurs?

ziolko.

Author

Commented:


  When i click on Run.


can you show me where to insert "Type" code


type
  TForm1 = class(TForm)
    Button1: TButton;
    Shape1: TShape;
    Shape2: TShape;
    Shape3: TShape;
    Shape4: TShape;
    Shape5: TShape;
    Shape6: TShape;
    Shape7: TShape;
    Shape8: TShape;
    i: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
 
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
 
 
  end;

Open in new window

Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
>>When i click on Run.
are you sure that w95_s7.dll is in windows\system32 directory or in folder where your exe is?

type
  TForm1 = class(TForm)
    Button1: TButton;
    Shape1: TShape;
    Shape2: TShape;
    Shape3: TShape;
    Shape4: TShape;
    Shape5: TShape;
    Shape6: TShape;
    Shape7: TShape;
    Shape8: TShape;
    i: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
 
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  adr_table_type = packed record
    cAdr: Byte;
    cSegmentId: Byte;
    cSlotNo: Byte;
    cRackNo: Byte;
  end;

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
make sure that komfort.dll is also in same place as w95_s7.dll

ziolko.

Author

Commented:


Yes my dll is:
w95_s7m.dll

and not
w95_s7.dll

Now i can compile.

Tomorrow i'll go on with work.
Thank you.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
compilation is not everything:)
such errors on application startup are caused by:
1. missing .dll file
2. dll does not export functions you want to use

in this case I guess it's something wrong with .dll location

ziolko.
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
btw. if DLL name is w95_s7m.dll not w95_s7.dll

change this also:
function Load_tool;external 'w95_s7m.dll' name 'load_tool';
function DB_read;external 'w95_s7m.dll' name 'db_read';
function Unload_tool;external 'w95_s7m.dll' name 'unload_tool';

ziolko.

Author

Commented:
 I have attached print screen of my app.
The shape color doesnt changes like my PLC input changes.



And I cant understand how

fi_bit := 1;

and:

if returnvalue and f_bit = f_bit then
    ShowMessage('first bit set');


are connected.

What does need :
returnvalue  variable

myApp.bmp
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
first of all did  you manage to connect to PLC with delphi app?
if so what was value returned in buff?

>>And I cant understand how...

db_read() returns values from PLC then you have to check returned value if interesting bits are set,
value returned by PLC is stored in buff[0] so you have to test this value by using and operator on buff[0] or assigning buff[0] value to returnvalue variable in toher words you can do it like this:

if buff[0] and ... = ... then

or

returnvalue := buff[0]
if returnvalue and ... = ... then

where did xx_bit values come from? it's pretty easy

f_bit = 1 which in bit representation is 00000001
s_bit = 2     00000010
t_bit = 4      00000100
fr_bit = 8     00001000
fi_bit =16     00010000
six_bit = 32  00100000
sev_bit = 64 01000000
e_bit = 128   10000000

now if value returned from PLC (lets call it returnvalue) is 00010101 you can do boolean operator on this value:

        00010101  <- returnvalue
and
        00000001  <- this is decimal value of 1 (f_bit)
--------------------
=      00000001  <- this result of: returnvalue and f_bit

as you can see: returnvalue and f_bit = f_bit, this indicates that first bit is set

now if you want check second bit:

        00010101  <- returnvalue
and
        00000010  <- this is decimal value of 2 (s_bit)
--------------------
=      00000000  <- this result of: returnvalue and s_bit

here you can see that: returnvalue and s_bit <> s_bit, this means second bit is NOT set
and in same way let's check third bit:

        00010101  <- returnvalue
and
        00000100  <- this is decimal value of 4 (t_bit)
--------------------
=      00000100  <- this result of: returnvalue and f_bit

again returnvalue and t_bit = t_bit and indeed third bit is set

ziolko.

Author

Commented:
If I consider that  I have to read data in my app: in this point I get affirmation that Im connected if  the data is equal to real data on PLC.
 
 When I click on load  Prodave needs something like 5 seconds to establish connection.  
 After that I can proceed with read.  

So should I do with my app the same  ( two button one for load and other for read) ?

 Thank you for clear explanation of Boolean operation.

Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
well I haven't worked with prodave but I excpect that this 5 sec delay is coused by load_tool() function, so if you debug your application and reach load_tool() your application should freeze for 5 or so seconds until connection is established, in theory you could read right after connection is done but I strongly recommend that you use not two but three buttons:

first button will establish connection (load_tool)
second button will do reading (db_read)
third button will end connection (unload_tool)

initially make buttons 2 and 3 disabled and in button 1 OnClick() do something like this

procedure TForm1.Button1Click(Sender: TObject);
begin
  load_tool(your_parameters);
  Button1.Enabled := False;
  Button2.Enabled := True;
  Button3.Enabled := True;
end;

this way once connection is made buttons for reading and closing connection are enabled

so you can do:

procedure TForm1.Button2Click(Sender: TObject);
begin
   db_read(your_parameters);
   // do the testing of return value here
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  unload_tool;
  Button1.Enabled := True;
  Button2.Enabled := False;
  Button3.Enabled := False;
end;

ziolko.

Author

Commented:


    Now i get positive results.

1.But i can't figure out  (my attached picture) whay shape1 is red  and other are yellow or white.
Yellow (like on PLC) is right but white and red not.


if buff [0] and f_bit = f_bit then
    shape1.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0]  and s_bit = s_bit then
     shape2.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0] and t_bit = t_bit then
  shape3.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0]  and fr_bit = fr_bit then
   shape4.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0] and fi_bit = fi_bit then
     shape5.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0]  and six_bit = six_bit then
   shape6.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0]  and sev_bit = sev_bit then
     shape7.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
  if buff [0]  and e_bit = e_bit then
 shape8.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;

2. How to make read function go cyclic (every 100 mS) and refresh  color of shapes?
   

positiveResults.bmp
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
if buff [0]  and s_bit = s_bit then
     shape2.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;

if second bit is set you change color of shape2 otherwise you change color of shape1
i gouess it should be:
buff [0] and f_bit = f_bit then
    shape1.Brush.Color:=clYellow else shape1.Brush.Color:=clRed;
if buff [0]  and s_bit = s_bit then
     shape2.Brush.Color:=clYellow else shape2.Brush.Color:=clRed;
  if buff [0] and t_bit = t_bit then
  shape3.Brush.Color:=clYellow else shape3.Brush.Color:=clRed;
  if buff [0]  and fr_bit = fr_bit then
   shape4.Brush.Color:=clYellow else shape4.Brush.Color:=clRed;
  if buff [0] and fi_bit = fi_bit then
     shape5.Brush.Color:=clYellow else shape5.Brush.Color:=clRed;
  if buff [0]  and six_bit = six_bit then
   shape6.Brush.Color:=clYellow else shape6.Brush.Color:=clRed;
  if buff [0]  and sev_bit = sev_bit then
     shape7.Brush.Color:=clYellow else shape7.Brush.Color:=clRed;
  if buff [0]  and e_bit = e_bit then
 shape8.Brush.Color:=clYellow else shape8.Brush.Color:=clRed;

ziolko.

Author

Commented:


And for:

 How to make read function go cyclic (every 100 mS) and refresh  color of shapes?
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
oops sorry missed that:)

the best way would be Timer, instead of button.
put TTimer on your form set .Enabled to False and .Interval to 100

and your code would be something like this:

procedure TForm1.Button1Click(Sender: TObject);
begin
  load_tool(your_parameters);
  Button1.Enabled := False;
  Timer1.Enabled := True;
  Button3.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   db_read(your_parameters);
   // do the testing of return value here
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  unload_tool;
  Button1.Enabled := True;
  Timer1.Enabled := False;
  Button3.Enabled := False;
end;

ziolko.
software developer
CERTIFIED EXPERT
Top Expert 2008
Commented:
..or even better:
procedure TForm1.Button3Click(Sender: TObject);
begin
  Timer1.Enabled := False;
  unload_tool;
  Button1.Enabled := True;
  Button3.Enabled := False;
end;

ziolko.

Author

Commented:
thank you wery much
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
does it work?

ziolko.

Author

Commented:
Yes
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
that's great! have fun with PLC:)

ziolko.