I define a PLCCLASS class (PLCCLASS pas), class contains OPC read and write functions:
The function plc_read_byte () : integer;
The function plc_write_word (ym: an array of word) : integer;
The function Tplc. Plc_read_byte () : integer;
Var
I: integer;
The begin
Result:=1;
For I:=0 to 5 do
The begin
HR:=ReadOPCGroupItemValue (GroupIf, jubinr [I], ItemValuer [I], ItemQuality);
end;
HR:=0;
If Succeeded (HR) then
The begin
Result:=1;
End
The else
The begin
Result:=1;
The exit;
end;
end;
The function Tplc. Plc_write_word (ym: an array of word) : integer;
Var
I: integer;
The begin
Result:=1;
HR:=WriteOPCGroupItemValue (GroupIf, jubinw [0], ym [0]).
If Succeeded (HR) then
The begin
Result:=1;
Showmessage (' write success);
End
The else
The begin
Result:=1;
The exit;
end;
end;
Variables in a synchronous read and synchronous write function and interface definition (GOLBALVAR. Pas) in the global variable, because a different of the read and write, I'm on a form (st. pas) produced in the two button link to read and write, call opcutils. The various functions in the pas, respectively;
Procedure Tst_form. BitBtnCWClick (Sender: TObject);
Var
I: integer;
The begin
Xiangnamew [0] :='S7: S7 connection_1 DB1, WORD0';
Xiangnamew [1] :='S7: S7 connection_1 DB1, WORD2';
Xiangnamew [2] :='S7: S7 connection_1 DB1, WORD4';
Xiangnamew [3] :='S7: S7 connection_1 DB1, WORD6';
HR:=GroupAddItem (GroupIf, xiangname [0], 0, VT_EMPTY, Item0Handle, ItemType);//function in OPCutils.
in the pasFor I:=0 to 3 do
The begin
HR:=GroupAddItem (GroupIf, xiangnamew [I], 0, VT_EMPTY, Item0Handle, ItemType);//function
end;
If Succeeded (HR) then
The begin
Memo1. Lines. The add (' add data item success! ');
End
The else
The begin
Memo1. Lines. The add (' add data item failed! ');
The Exit;
end;
Jubinw [I] :=Item0Handle;
end;
end;
Procedure Tst_form. BitBtnCRClick (Sender: TObject);
Var
I: integer;
The begin
Xiangnamer [0] :='S7: S7 connection_3 DB1, byte0';
Xiangnamer [1] :='S7: S7 connection_3 DB1, byte2';
Xiangnamer [2] :='S7: S7 connection_3 DB1, byte4';
Xiangnamer [3] :='S7: S7 connection_3 DB1, byte6';
Xiangnamer [4] :='S7: S7 connection_3 DB1, byte8';
Xiangnamer [5] :='S7: S7 connection_3 DB1, byte10';
HR:=GroupAddItem (GroupIf, xiangname [0], 0, VT_EMPTY, Item0Handle, ItemType);//function in OPCutils.
in the pasFor I:=0 to 5 do
The begin
HR:=GroupAddItem (GroupIf, xiangnamer [I], 0, VT_EMPTY, Item0Handle, ItemType);//function in OPCutils.
in the pasJubinr [I] :=Item0Handle;
end;
If Succeeded (HR) then
The begin
Memo1. Lines. The add (' add data item success! ');
End
The else
The begin
Memo1. Lines. The add (' add data item failed! ');
The Exit;
end;
end;
Can successfully connect to read and write, write after a successful connection, I created a thread, the function call plcclass Tplc. Plc_write_word (ym: an array of word) : integer; , the data can be written to success,
After close the program, to run, only connect to read, read the success and connect the same thread, the function call plcclass plc_write_word (ym: an array of word) : integer; Will be an error, roughly means " EintfCastError with message 'Interface not supported' , program stop below the red place (in OPCutiIs) :
The function ReadOPCGroupItemValue (GroupIf: IUnknown; ItemServerHandle: OPCHANDLE;
Var ItemValue: string; Var ItemQuality: Word) : HResult;
Var
SyncIOIf: IOPCSyncIO;
Errors: PResultList;
ItemValues: POPCITEMSTATEARRAY;
The begin
Result:=E_FAIL;
Try
SyncIOIf:=GroupIf as IOPCSyncIO;
Except,
SyncIOIf:=nil;
end;
If SyncIOIf & lt;> Nil then
The begin
Result:=SyncIOIf. Read (OPC_DS_CACHE, 1, @ ItemServerHandle ItemValues,
Errors).
If Succeeded (Result) then
The begin
Result:=Errors [0];
CoTaskMemFree (Errors);
ItemValue:=VarToStr (ItemValues [0]. VDataValue);
ItemQuality:=ItemValues [0]. WQuality;
VariantClear (ItemValues [0]. VDataValue);
CoTaskMemFree (ItemValues);
end;
end;
end;
Later, I add a button in the Form, in the only connection reflection, click this button to direct call function ReadOPCGroupItemValue (GroupIf: IUnknown; ItemServerHandle: OPCHANDLE;
Var ItemValue: string; Var ItemQuality: Word) : HResult;
To original data of OPC,
the problem now have 2:
1. The same is implemented in the thread, why synchronous write success, synchronous read at less than data (synchronous read and synchronous write is tested separately)?
2. The same is synchronous read, in the thread for complains, placed in button click trigger can to read the data?
Then I think there are two possible,
1. Delphi6 environment problem, I see a lot of online OPC case is implemented in delphi7 environment, don't know what a player out to teach?
2. Doubt is the time to add the server out of wrong, call the same Groupif, appear the interface does not support this kind of situation, but I only tests a single reading or writing, don't have contact between the read and write?
Hope which ace glad!!!!!!
CodePudding user response:
The building Lord, this problem can you solve it, how to solveCodePudding user response:
Feel you this problem is not the OPC server problem, use the thread has to do with you?OPC now use less, especially based on COM, practical application of OPC will produce panic error, make you stunned,
If you can, if Siemens PLC side is your own doing, can use a serial port, PPI, PROFIBUS, etc.