I have a 3D-layout with some hydraulic cylinders that is controlled via OPC-UA communication from an external PLC. The signals from the PLC trigger some calculations that is using the actual Simulation time. My problem is that the plugin-update time differs too much for me to have enough accurate results from the calculations. I really want to stay with the OPC-UA protocol if it is possible.
So, is there a way to get a handle of the “Average update time”, and “Average plugin time” so I can compensate for it in a python script?
Thanks in advance.
As far as I know, there is no Python API for connectivity plugins like OPC UA and TwinCAT ==> the GUI itself should be sufficient to compensate by changing the update modes and sync times. Might be there in .NET API, but others know best. Sorry
So basically you want to know the communication delay between your PLC and simulation?
If you can modify the PLC program, create a ping-pong type loop between a script in simulation and the PLC program and measure the time it takes to get a response from the PLC. Note that the delay usually varies so you may want to calculate a rolling average.
You could e.g. create 2 integer signals or properties in simulation, one for output and one for input, and similarly 2 variables on the PLC. Then connect them together in connectivity and have simulation script get “wall time” with time.clock() and increment the output signal’s value. Then have the PLC detect the value change coming from simulation and assign that value to its output going back to simulation. Then when your simulation script gets response from the PLC, calculate the difference between current time.clock() value and the time when you sent the previous value to the PLC, start over.
This will of course measure total roundtrip time instead of just one-way delay, but its better than nothing.
There is also undocumented .NET API for getting the raw variable synchronization operation timing info from which the “plugin time” and “total time” values in the UI are calculated, but its not that easy to access or use.
After some consideration I came to the conclusion that OPC would not be enough for my application this time. So I have tried to implement the python snap7, as it is a Siemens PLC Im having on the other end. It works like a charm so far, with reading and writing data and the data amount that is possible to transfer is on a whole other level, just what I need.
But, as I start reading word and float numbers from the PLC the VC-layout becomes kind of sluggish, it still works fine though and all the values get registrated as they should.
Is there a way around this? I was thinking to run an external python interpreter and let that interpreter collect the values from the PLC running from the windows command promter, and from VC import that script and read the variable, bit I dont get the variable to update once I have imported the external script in VC, so Im kind of stuck at the moment, any idea or sugestions is mighty appreciated.
The red sinwave is generated and sent to the PLC, the green one is the answer back from the PLC.
Thanks for your time//
I’m very interested in your implementation of Snap7. Is it possible to share it?
Thanks in advance,
I assume you are doing synchronous (blocking) communication with the PLC using the Snap7 library. While this can ensure that you send and receive values at desired interval in simulation time, it is usually very inefficient and can easily desync your simulation clock from the real-time operation / clock of the PLC as that doesn’t operate using the simulation time unless you specifically implement all your PLC code to do so.
Threading / multiprocess with Python isn’t supported, so if the communication library doesn’t directly support non-blocking operations you are pretty much out of luck. With blocking communication you are wasting maybe 95% of the processor time just waiting for a reply from the PLC and thus performance with any more complex simulation layout will be very poor. Since there has been some example of using non-blocking socket communication using Python in the forum, I guess you could make a separate application (with e.g. Python) that does your communication with the PLC and then communicates with VC using a separate socket connection, but that is quite a hack.
The Connectivity feature always does its communication asyncronously, which gives much better overall performance but brings its own issues - primarily that the update interval is not tied to simulation time but real time and thus varies.
mschamp, I did implement the snap7 library, and as TSy says, when it is done synchronous it does mess up the real-time clock of the simulation, and for at least me that was a problem as I do need that time to be accurate. So what I did was to run a separete python interpreter outside VC, that handels all the communication with the PLC, and from that separate python interpreter I transfered the data via TCP/IP with the recieving socket in VC set to non blocking( socket.setblocking(0) ).
It does work like a charm for me. But for other reasons I changed to UDP-protocol between the “external” python interpereter, and PLC, and from the external pyhton interpreter I send the data to VC with the TCP/IP sockets.