The classic way to communicate with a PLC is to exchange tags with it. The tags are handled on each PLC cycle. This implies that tags can change periodically and the PLC reacts to these changes thanks to its internal cyclic nature. In Process Simulate it is pretty much the same. We execute scripts periodically using a well known sampling time (LB update rate). Now imagine that you need to exchange data not on a periodical basis but every once in a while when a user clicks a button for example. This is the typical use case for devices like: barcode scanners, imaging devices, RFID readers etc. Having such a mechanism would save a lot of processing time on both sides of the communication since tag handling won't be involved. Also we can exchange bigger chunks of data since theoretically performance won't be such a big concern. To address this need PLCSIM Advanced supports the so called acyclic services. In essence these are callbacks that the client application provides via the PLCSIM Advanced API. The callbacks are invoked when a read/write request is initiated by the PLC.
In Process Simulate we handle these request as part of a SCL script. We rely on the cyclic execution of the script to check for any such requests and handle them accordingly.
To do so we have introduced a number of SCL functions:
READ_RECORD_PENDING - checks for a pending read request from the PLC
READ_RECORD_DONE - acknowledges a pending read request
WRITE_RECORD_PENDING - checks for a pending write request from the PLC
WRITE_RECORD_DONE - acknowledges a pending write request
As it is obvious by the definitions in Process Simulate we can handle up to 4KB of data a-cyclically. Usually this would be structured data of some sort. Unfortunately our implementation relies on raw bytes for now (v2402) since we are missing SCL functions like MOVE_BLK_VARIANT. This by itself makes it hard to process the records on our side of the communication. Still if you are aware of the structure you can index the bytes and interpret them using bitwise/bit index operators.
I think you get the overall idea. In Process Simulate all you need a script to monitor every acyclic request you expect. e.g. something like this:
FUNCTION_BLOCK "MAIN"
VAR
RCDATA:ARRAY[0..4095] OF BYTE; // record data buffer
RCSIZE:UDINT; // record data size
END_VAR
BEGIN
// listen for acyclic PLC read requests
IF READ_RECORD_PENDING(CN:='AcyclicTest', // connection name
HWID:=265, // hardware identifier
RCID:=1, // record identifier
RCSIZE=>#RCSIZE) THEN
// provide record specific data here
#RCDATA[0] := 16#CF;
#RCDATA[1] := 16#00;
// ...
// acknowledge it to the PLC
READ_RECORD_DONE(CN:='AcyclicTest', // connection name
HWID:=265, // hardware identifier
RCID:=1, // record identifier
RCSIZE:=#RCSIZE, // record size
RCDATA:=#RCDATA, // record data
SCODE:=0); // status code (success)
END_IF;
END_FUNCTION_BLOCK
The same pattern can be applied for write requests.
It is important to mention that PLCSIM Advanced can handle only one acyclic request at a time. You must explicitly make sure requests are not triggered concurrently because this confuses the PLC.
Now lets take a look at the PLC side of things. As you might expect the code running on the PLC should trigger the requests. The standard RDREC and WRREC blocks in TIA Portal do this. The code should be something like this:
#RDREC(ID := 265, // hardware identifier
INDEX := 1, // record identifier
MLEN := 10, // maximum length in bytes
REQ := #RTRIG.Q, // trigger the request on RE of the input
BUSY => #BUSY, // request in progress
ERROR => #ERROR,
LEN => #LEN, // record size
STATUS => #STATUS, // status code
RECORD := #RCDATA, // record data
VALID => #VALID);
// retrieve record specific data
// #RCDATA[0];
// #RCDATA[1];
// ...
END_IF;
Hardware identifiers are important for the communication to work. They can be found in TIA portal - in the properties of the acyclic device. Record identifiers are specific to the actual device used.
RDREC and WRREC blocks are asynchronous which means that the execution extends over multiple calls. You can check the documentation in TIA Portal for more information since I am not an expert.
So far so good. Now you know how acyclic calls work.
Hopefully in future versions well have time to revisit this and introduce move functions in SCL. Then you'll be able to work with UDTs instead of raw bytes.
Thank you for your time and have a wonderful day!
Comments