From: Zbynek Zahradnik
Sent: Sunday, March 25, 2012 5:16 PM
To: P.
Subject: RE: MultipleItem Write - Delay Code
P.,
thank you.
I think that with high likeliness, the delays are simply the time that it takes the OPC server to access the data for the first time. If necessary (but I do not think that it is), this can be proven either by using some other OPC client for test, or by special tool (OPC Analyzer) that I can send to you.
QuickOPC keeps connection to OPC servers, and OPC items added to OPC groups etc. for some time (“hold period”) after they are accessed by “one-shot” methods such ReadXXXX or WriteXXXX. This is what likely causes the subsequent accesses be fast. The hold periods are configurable by properties on the EasyDAClient object, if you need to adjust that.
For scenarios where you cannot allow such variations in processing times, subscriptions would be a better option. This of course would require different application logic.
Best regards,
Zbynek Zahradnik, OPC Labs
From: P.
Sent: Sunday, March 25, 2012 8:37 AM
To: Zbynek Zahradnik
Subject: Re: MultipleItem Write - Delay Code
Zbynek
The delays on subsequent reopening of a form after using the this.close command on the form are negligible.
Regards
P.
On 25 Mar 2012, at 06:35, "Zbynek Zahradnik" <ZbynekZ@opclabs.com> wrote:
P.,
The long delays can be caused by the OPC Server, or the client (our component). It would be a bug in the component if the OPC server has delivered all the data quickly, but somehow it got delayed in the component. On the OPC server side, there is no “hard” specification that would tell how fast it must supply the data.
With OPC Servers that access PLCs over some kind of relatively slow connection, it is not uncommon, however, that it takes them quite long to get the data initially. This is not much of a problem if you need to subscribe to the data and watch it continuously (such as on HMI screens), but if you just “come in” initially and ask for the data, the delay may appear too long.
There is caching both in OPC Server and in QuickOPC, but if we are talking about a very first access, obviously there could be nothing in the caches to be used. In addition, the very first access could require starting up the OPC server, and other initialization tasks.
Can you measure the delays if you open the form second time, relatively shortly after the first opening (and without closing the application)?
Best regards,
Zbynek Zahradnik, OPC Labs
From: P.
Sent: Saturday, March 24, 2012 10:43 AM
To: Zbynek Zahradnik
Subject: MultipleItem Write - Delay Code
Zbynek
Please ignore my previous email. I thought it might be easier for me to send you the method I am using to read multiple items. This method is called once on form opening and takes approx. 3s to complete (if the connection to the plc is good) or 14s (if the connection to the PLC is disconnected) this method which seems a long time considering there are so few values. Any comments?
public void ReadPlcBatchData()
{
// Set up private fields
int totalItems = 9; // Total Number Items to be read
var opcClient = new EasyDAClient(); // Declare opc interface
var itemDescriptors = new DAItemDescriptor[totalItems]; // Declare array to hold item descriptors.
// Setup Item descriptors for Multiple Item Read
itemDescriptors[0] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.totalPressCycles");
itemDescriptors[1] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.palletNumber");
itemDescriptors[2] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.pieces");
itemDescriptors[3] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.maxToolMovement");
itemDescriptors[4] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.totalBlanksStacked");
itemDescriptors[5] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.minStackHeight");
itemDescriptors[6] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.totalCoilLength");
itemDescriptors[7] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.grossWeight");
itemDescriptors[8] = new DAItemDescriptor("SIMATIC 300 Station.CPU 317-2 PNDP(1).PLC TO BCS.maxStackHeight");
// Perform Multiple Item OPC Read of PLC Batch Data
// If .Succeeded property returns true then there is no exception and data can be considered ok.
DAVtqResult[] vtqResults = opcClient.ReadMultipleItems("OPC.SimaticNET.1", itemDescriptors);
if (vtqResults[0].Succeeded)
{
totalPressCycles = Convert.ToDouble(vtqResults[0].Vtq.Value);
totalPressCyclesStatus = true;
}
else
{
totalPressCycles = 0.0D;
totalPressCyclesStatus = false;
}
if (vtqResults[1].Succeeded)
{
palletNumber = Convert.ToInt32(vtqResults[1].Vtq.Value);
palletNumberStatus = true;
}
else
{
palletNumber = 0;
palletNumberStatus = false;
}
if (vtqResults[2].Succeeded)
{
pieces = Convert.ToInt32(vtqResults[2].Vtq.Value);
piecesStatus = true;
}
else
{
pieces = 0;
piecesStatus = false;
}
if (vtqResults[3].Succeeded)
{
maxToolMovement = Convert.ToInt32(vtqResults[2].Vtq.Value);
maxToolMovementStatus = true;
}
else
{
maxToolMovement = 0;
maxToolMovementStatus = false;
}
if (vtqResults[4].Succeeded)
{
totalBlanksStacked = Convert.ToDouble(vtqResults[4].Vtq.Value);
totalBlanksStackedStatus = true;
}
else
{
totalBlanksStacked = 0.0D;
totalBlanksStackedStatus = false;
}
if (vtqResults[5].Succeeded)
{
minStackheight = Convert.ToInt32(vtqResults[5].Vtq.Value);
minStackheightStatus = true;
}
else
{
minStackheight = 0;
minStackheightStatus = false;
}
if (vtqResults[6].Succeeded)
{
totalCoilLength = Convert.ToDouble(vtqResults[6].Vtq.Value);
totalCoilLengthStatus = true;
}
else
{
totalCoilLength = 0.0D;
totalCoilLengthStatus = false;
}
if (vtqResults[7].Succeeded)
{
grossWeight = Convert.ToInt32(vtqResults[7].Vtq.Value);
grossWeightStatus = true;
}
else
{
grossWeight = 0;
grossWeightStatus = false;
}
if (vtqResults[8].Succeeded)
{
maxStackheight = Convert.ToInt32(vtqResults[8].Vtq.Value);
maxStackheightStatus = true;
}
else
{
maxStackheight = 0;
maxStackheightStatus = false;
}
}
Regards
P.