I tested it with a CLX L18ER and a HP ZBook G3 15 with a Core i7. The PLC has no code, only the tags. It takes 1.5 seconds to read all the data after the fist read. But when i tested it on site in a L36ERM with 12 programs, 23 Ethernet IP devices (robocilinders, 2d scanners, vision sensors, an SCARA, communication units, and some RS232 devices), 5 HMI, and an industrial PC to log the data (iTac)
What you are seeing is the sharing of your processor time slice between program logic and communications. Your communication speed bottleneck comes from how fast the processor can process and respond to the read request. If there is no PLC program and the processor is in program mode, then it can have the maximum amount of CPU time dedicated to servicing communications. From my testing in this scenario, response time averaged around 2.5ms. I did a further test with a single rung and the processor in run mode. This took away from the CPU being able to process communications and it then took an average of 5ms. So any bit of processor time that has to be used for program processing will be time taken away from communication processing.
So then how can you optimize this? Each request requires a header packet of about 24 bytes, but more importantly requires the CPU to process it and put the response on the wire. By reducing the number of requests, you increase the overall communication response. This can be done in several ways.
One is to read part or all of the UDT in one request. Since AdvancedHMI is unaware of UDT structures, it's only option is to return an array of raw bytes, then it is up to you to parse into the elements. This take a fairly in depth understanding of the way elements are packed into memory. If you UDT contains only 4 byte elements, such as DINTs and REALs, then it become very easy. But if you have mixed elements, then it can be quite complex.
Let's take your example with a few assumptions. I will make the assumption your UDT elements of Valor and Codigo_Falla are both DINT and are the only elements in the NestNum UDT. Based on those assumptions, let's read the complete UDT like this:
Dim b() as string=EIPforCLX1.Read("Nido[" & NumNido & "].NestNum")
Let's assume the scenario where Valor=1 and Codigo_Falla=2. I will also make the assumption Valor is the first element in the UDT definition. With all of those assumptions, the read above will return this:
0100000002000000
What does all that mean? Well it is the raw bytes in hex. We know that a DINT uses 4 bytes, so the first 4 bytes are:
01 00 00 00
If you take those 4 bytes and convert from hex to decimal, store it in a byte array, then convert it to an Iint32, you will get the result of Valor. This now leaves the last 4 bytes which will be the raw data for the value of Codigo_Falla
Using this method we will decrease our read time in almost half, but will require some additional code for parsing.
This post is becoming long so I won't go into the specific code for doing all of this parsing.