- Beiträge
- 9.191
- Reaktionspunkte
- 2.936
-> Hier kostenlos registrieren
Welcher Index/Subindex wird denn gelesen, wenn du mit RDREC aus dem SPS-Programm aufrufst? Du verwendest ja nur die CAP Kennung.
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
Aber woher weiß der nackte RDREC, dass du Index 18, Subindex 0 lesen willst?
Was stehen bei der RDREC-Antwort noch für Bytes vor dem eigentlichen String, bestehen dort Ähnlichkeiten zu denen die auf dem Netzwerk zu sehen sind?
IO_LINK_MASTER_4Du hast bei deiner AWL-Quelle vermutlich den IO_LINK_MASTER gepostet, von dem liefert Siemens auch die SCL-Quelle mit.
(*---------------------------------------------------------------------------------------------------------------------
SIEMENS AG
©Copyright 2015. All Rights Reserved.
-----------------------------------------------------------------------------------------------------------------------
Limitation of liability
This software was developed with largest care. However, the author can not guarantee, that the software runs under
each version of STEP7 on each PLC flawlessly.
There is no warranty for the software, to the extent permitted by applicable law. The copyright holder provides the
software "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance
of the software is with you. Should the software prove defective, you assume the cost of all necessary servicing,
repair or correction. In no event unless required by applicable law will the copyright holder be liable to you for
damages, including any general, special, incidental or consequential damages arising out of the use or inability to
use the software (including but not limited to loss of data or data being rendered inaccurate or losses sustained by
you or third parties or a failure of the software to operate with any other programs), even if such holder or other
party has been advised of the possibility of such damages.
Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are
retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above
notices are retained, and a notice that the code was modified is included with the above copyright notice.
-----------------------------------------------------------------------------------------------------------------------
Functionality provided by this source (short description):
Function block IO_LINK_DEVICE - used to read and write of acyclic data records on devices with IO-Link.
Note:
To read data records, the IO-Link master modules needs to know which data record is required. Therefore it is necessary
to send at first a request via write data record (only header of 8 byte). As response the IO-Link master module
will send the required data record.
Status: Released (tested)
File name: IO_LINK_DEVICE
System : SIMATIC S7-300/400
Version : 3.0
-----------------------------------------------------------------------------------------------------------------------
Script to be stored on level ... in project (mark appropriate levels with [x] below)
[ ] External
[ ] All levels possible
[x] Project level
[ ] Controller level
[ ] Device level
[ ] Subobject level
-----------------------------------------------------------------------------------------------------------------------
Restrictions, known limitations:
The limitation of 240 byte is based on PROFIBUS DP protocol. With PROFINET IO there wouldn't no limit but because of
compatibility reason it wasn't changed.
- header = 8 byte
- data = 232 byte
-----------------------------------------------------------------------------------------------------------------------
Requirements, prerequisites, External resources used: nothing
-----------------------------------------------------------------------------------------------------------------------
Change log table (latest change is at the bottom OF the list):
Version Date Changes applied
V2.0.0 <2013-09-30> First created with TIA Portal V12 SP1
V2.1.0 <2014-03-14> Upgrade system function 'WRREC' from V1.0 to V1.1 and released for TIA Portal V13
V3.0.0 <2015-02-28> Upgrade and released for TIA Portal V13 SP1 (without backup/restore master parameter)
V3.0.1 <2015-07-07> Change of #IOL_INDEX and #Port lower boundry to 0
---------------------------------------------------------------------------------------------------------------------*)
(*---------------------------------------------------------------------------------------------------------------------
Description of programmed IO-Link error codes
8000 = time out
8001 = wrong port
8002 = wrong index
8003 = wrong subindex
8005 = wrong length for write data record
8006 = wrong length for read data record
8052 = error during reading data record
8053 = error during writing data record
All other codes are coming from a higher level!
---------------------------------------------------------------------------------------------------------------------*)
(*---------------------------------------------------------------------------------------------------------------------
NEW REQUEST
---------------------------------------------------------------------------------------------------------------------*)
// detection rising edge of "REQ"
#R_TRIG_REQ := #REQ = TRUE AND #R_TRIG_REQ_old = FALSE;
#R_TRIG_REQ_old := #REQ = TRUE;
// start new request if not busy
IF #R_TRIG_REQ = TRUE AND #sequencecontrol = 0 THEN
// Freeze record ID and CAP
#WRREC_Function.ID := #ID;
#WRREC_Function.INDEX := #CAP;
#RDREC_Function.ID := #ID;
#RDREC_Function.INDEX := #CAP;
// Initialize outputs
#DONE_VALID := FALSE;
#BUSY := TRUE;
#ERROR := FALSE;
#STATUS := DW#16#00000000;
#IOL_STATUS := DW#16#00000000;
#RD_LEN := INT#0;
// Initialize data area
#read.header."CALL"."Port" := B#16#0;
#read.header.IOL.Index_LowByte := B#16#0;
#read.header.IOL.Index_HighByte := B#16#0;
#read.header.IOL.Subindex := B#16#0;
#i := INT#0; // initialize loop counter
FOR #i := 0 TO 231 DO
#write.data[#i] := B#16#0;
#read.data[#i] := B#16#0;
END_FOR;
(*---------------------------------------------------------------------------------------------------------------------
Setup IO-LINK Call needs a specific header
---------------------------------------------------------------------------------------------------------------------*)
// setup CALL header
#write.header."CALL".Extended_Function_Num := 16#08; // extended function number (fix coded 08h)
#write.header."CALL"."Port" := INT_TO_BYTE(#PORT); // 1..63 = PORT number, 64..255=reserved
#write.header."CALL".FI_Index := 65098; // IOL-Header is following (fix coded 65098)
// setup IOL header
// CONTROL = please see below at BODY
// INDEX
#write.header.IOL.Index_LowByte := INT_TO_BYTE(#IOL_INDEX);
#tmpWORD := INT_TO_WORD(#IOL_INDEX);
#tmpWORD := SHR(IN := #tmpWORD, N := 8);
#write.header.IOL.Index_HighByte := WORD_TO_BYTE(#tmpWORD);
// SUBINDEX
#write.header.IOL.Subindex := INT_TO_BYTE(#IOL_SUBINDEX);
// BODY (data max. 232 Byte, Array 0..231 of Byte)
IF #RD_WR = TRUE THEN
// IO-Link write data record requested, copy data from "RECORD_IOL_DATA"
#write.header.IOL.Control := B#16#02; // CONTROL B#16#02 = write data record
#wrrec.length := #LEN + INT#8; // data length header + data = IO-Link write data record
#typeofrequest := 2; // write data record
// copy IOL_RECORD_DATA in working area
#i := INT#0; // initialize loop counter
FOR #i := 0 TO #LEN - 1 DO
#write.data[#i] := #RECORD_IOL_DATA[#i];
END_FOR;
ELSE
// IO-Link read data record requested
#write.header.IOL.Control := 16#03; // CONTROL 16#03 = read data record
#wrrec.length := INT#8; // data length only header = IO-Link read data record
#typeofrequest := 1; // read data record
END_IF;
#sequencecontrol := 1; // Start sequence
ELSE
;
END_IF;
(*---------------------------------------------------------------------------------------------------------------------
SEQUENCE CONTROL
---------------------------------------------------------------------------------------------------------------------*)
CASE #sequencecontrol OF
1: // Check input parameter
IF #PORT < INT#0 OR #PORT > INT#63 THEN // PORT (Wrong port address = 0x8001)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80010000;
#sequencecontrol := 99; // aborting function with error
ELSIF #IOL_INDEX < INT#0 OR #IOL_INDEX > INT#32767 THEN // INDEX (Wrong index = 0x8002)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80020000;
#sequencecontrol := 99; // aborting function with error
ELSIF #IOL_SUBINDEX < INT#0 OR #IOL_SUBINDEX > INT#255 THEN // SUBINDEX (Wrong subindex = 0x8003)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80030000;
#sequencecontrol := 99; // aborting function with error
ELSIF #typeofrequest = 2 AND (#LEN < 1 OR #LEN > 232) THEN // LEN (wrong length for write data record = 0x8004)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80050000;
#sequencecontrol := 99; // aborting function with error
ELSIF #typeofrequest = 1 AND (#LEN < 0 OR #LEN > 232) THEN // LEN (wrong length for read data record = 0x8005)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80060000;
#sequencecontrol := 99; // aborting function with error
ELSE // all input parameter are right
#sequencecontrol := 2;
END_IF;
2: (*-------------------------------------------------------------------------------------------------------------
WRREC = Write Data Record
Note:
To read data records, the IO-Link master modules needs to know which PORT is required. Therefore it is necessary
to send at first a request via write data record (header, 8 byte). As response the IO-Link master module will
send the required data record.
-------------------------------------------------------------------------------------------------------------*)
#WRREC_Function(REQ := TRUE,
LEN := #wrrec.length,
DONE => #wrrec.done,
BUSY => #wrrec.busy,
ERROR => #wrrec.error,
STATUS => #wrrec.status,
RECORD := #write);
// output status during write data record
IF #wrrec.busy THEN
#STATUS := #wrrec.status;
#IOL_STATUS := DW#16#00020000; // 0002 = writing in progress
ELSIF #wrrec.error THEN
#tmpDWORD := #wrrec.status AND DW#16#00FFFF00; // filter status
IF #tmpDWORD = DW#16#0080C200 THEN // if resource #BUSY (#STATUS=80C2), then ...
#sequencecontrol := 3; // ... repeat write data record
ELSE
#ERROR := TRUE;
#STATUS := #wrrec.status; // ... otherwise output error status of "WRREC"
#IOL_STATUS := DW#16#80530000; // ... with note '8053' = error status of "WRREC"
#sequencecontrol := 99; // aborting function with error
END_IF;
ELSIF #wrrec.done = TRUE THEN // wait for write data record finish without error
#TP_poll(IN := TRUE,
PT := T#100ms); // poll for response
#sequencecontrol := 4;
ELSE
;
END_IF;
3: // repeat write data record because resource was busy
#WRREC_Function(REQ := FALSE);
#sequencecontrol := 2;
4: // wait and poll for response = Read Data Record (RDREC)
#WRREC_Function(REQ := FALSE);
#TP_poll(IN := TRUE,
PT := T#100ms);
// if poll rate executed then start read data record (on falling edge)
#F_TRIG_poll := #TP_poll.Q = FALSE AND #F_TRIG_poll_old = TRUE;
#F_TRIG_poll_old := #TP_poll.Q = TRUE;
// RDREC = Read Data Record
#RDREC_Function(REQ := #F_TRIG_poll,
MLEN := INT#232, // max. length = 232 = read all data which are available
VALID => #rdrec.valid,
BUSY => #rdrec.busy,
ERROR => #rdrec.error,
STATUS => #rdrec.status,
LEN => #rdrec.length,
RECORD := #read);
// output status during read data record
IF #rdrec.busy THEN
#STATUS := #rdrec.status;
#IOL_STATUS := DW#16#00030000; // 16#0003 = reading in progress
ELSIF #rdrec.error = TRUE THEN
#tmpDWORD := #rdrec.status AND DW#16#00FFFF00; // filter status
IF #tmpDWORD = DW#16#0080C200 THEN // if resource busy (status=80C2), then ...
#sequencecontrol := 5; // ... repeat read data record / continue polling
ELSE
#ERROR := TRUE;
#STATUS := #rdrec.status; // ... otherwise output error code of "RDREC"
#IOL_STATUS := DW#16#80520000; // ... with note '8052' = error status of "RDREC"
#sequencecontrol := 99; // aborting function with error
END_IF;
ELSIF #rdrec.valid THEN
IF // check the response wether it matches the request (compare PORT, INDEX and SUBINDEX)
(#write.header."CALL"."Port" <> #read.header."CALL"."Port") OR
(#write.header.IOL.Index_HighByte <> #read.header.IOL.Index_HighByte) OR
(#write.header.IOL.Index_LowByte <> #read.header.IOL.Index_LowByte) OR
(#write.header.IOL.Subindex <> #read.header.IOL.Subindex)
THEN // read data record don't match the request
#ERROR := TRUE;
#STATUS := #rdrec.status;
#IOL_STATUS := DW#16#70000000; // output status '7000', no consistent data
#sequencecontrol := 99; // aborting function with error
ELSIF #read.header.IOL.Control = B#16#80 THEN // check the response for IO-Link errors
// State 0x80 = IOL_CALL_RES PDU shows IO-Link error detect
#ERROR := TRUE;
#STATUS := DW#16#00000000;
#AT_IOL_STATUS[3] := #read.data[3]; // IO-Link master error code
#AT_IOL_STATUS[2] := #read.data[2]; // IO-Link master error code
#AT_IOL_STATUS[1] := #read.data[1]; // IO-Link device error code
#AT_IOL_STATUS[0] := #read.data[0]; // IO-Link device additional error code
#IOL_STATUS := #tmpDWORD;
#sequencecontrol := 99; // aborting function with error
ELSE // read data are valid = output
#DONE_VALID := TRUE;
#BUSY := FALSE;
#ERROR := FALSE;
#STATUS := DW#16#00000000;
#IOL_STATUS := DW#16#00000000; // request finished
IF #typeofrequest = 1 THEN
#RD_LEN := #rdrec.length - INT#8; // device parameter cover header and data,
// only data will be output
#i := INT#0; // initialize loop counter
FOR #i := 0 TO #rdrec.length - INT#8 - INT#1 DO
#RECORD_IOL_DATA[#i] := #read.data[#i];
END_FOR;
ELSE
;
END_IF;
#sequencecontrol := 98;
END_IF;
ELSE
;
END_IF;
5: // poll again for response because resource was busy
#TP_poll(IN := FALSE,
PT := T#100ms);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
#sequencecontrol := 4; // ... repeat read data record / continue polling
98: // request done successfully
#TP_poll(IN := FALSE,
PT := T#100ms);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
IF #REQ = FALSE THEN
#DONE_VALID := FALSE;
#BUSY := FALSE;
#ERROR := FALSE;
#RD_LEN := INT#0;
#STATUS := DW#16#00000000;
#IOL_STATUS := DW#16#00010000; // ready for new request
#sequencecontrol := 0;
#typeofrequest := 0;
ELSE
;
END_IF;
99: // Function aborted with error
#TP_poll(IN := FALSE,
PT := T#100ms);
#WRREC_Function(REQ := FALSE);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
#DONE_VALID := FALSE;
#BUSY := FALSE;
#RD_LEN := INT#0;
#sequencecontrol := 0;
#typeofrequest := 0;
ELSE // no relevant case, ready for new request
#WRREC_Function(REQ := FALSE);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
#TP_poll(IN := FALSE,
PT := T#100ms);
#TON_monitoring(IN := FALSE,
PT := T#20s);
#sequencecontrol := 0;
#typeofrequest := 0;
END_CASE;
(*---------------------------------------------------------------------------------------------------------------------
MONITORING
---------------------------------------------------------------------------------------------------------------------*)
#TON_monitoring(IN := #sequencecontrol > 0 AND #sequencecontrol < 98,
PT := T#20s);
IF #TON_monitoring.Q THEN
#ERROR := TRUE;
#IOL_STATUS := DW#16#80000000; // request time out
#sequencecontrol := 99; // aborting function with error
END_IF;
(*---------------------------------------------------------------------------------------------------------------------
SIEMENS AG
©Copyright 2015. All Rights Reserved.
-----------------------------------------------------------------------------------------------------------------------
Limitation of liability
This software was developed with largest care. However, the author can not guarantee, that the software runs under
each version of STEP7 on each PLC flawlessly.
There is no warranty for the software, to the extent permitted by applicable law. The copyright holder provides the
software "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance
of the software is with you. Should the software prove defective, you assume the cost of all necessary servicing,
repair or correction. In no event unless required by applicable law will the copyright holder be liable to you for
damages, including any general, special, incidental or consequential damages arising out of the use or inability to
use the software (including but not limited to loss of data or data being rendered inaccurate or losses sustained by
you or third parties or a failure of the software to operate with any other programs), even if such holder or other
party has been advised of the possibility of such damages.
Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are
retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above
notices are retained, and a notice that the code was modified is included with the above copyright notice.
-----------------------------------------------------------------------------------------------------------------------
Functionality provided by this source (short description):
Function block IO_LINK_DEVICE - used to read and write of acyclic data records on devices with IO-Link.
Note:
To read data records, the IO-Link master modules needs to know which data record is required. Therefore it is necessary
to send at first a request via write data record (only header of 8 byte). As response the IO-Link master module
will send the required data record.
Status: Released (tested)
File name: IO_LINK_DEVICE
System : SIMATIC S7-1200/1500
Version : 3.0
-----------------------------------------------------------------------------------------------------------------------
Script to be stored on level ... in project (mark appropriate levels with [x] below)
[ ] External
[ ] All levels possible
[x] Project level
[ ] Controller level
[ ] Device level
[ ] Subobject level
-----------------------------------------------------------------------------------------------------------------------
Restrictions, known limitations:
The limitation of 240 byte is based on PROFIBUS DP protocol. With PROFINET IO there wouldn't no limit but because of
compatibility reason it wasn't changed.
- header = 8 byte
- data = 232 byte
-----------------------------------------------------------------------------------------------------------------------
Requirements, prerequisites, External resources used: nothing
-----------------------------------------------------------------------------------------------------------------------
Change log table (latest change is at the bottom OF the list):
Version Date Changes applied
V2.0.0 <2013-09-30> First created with TIA Portal V12 SP1
V2.1.0 <2014-03-14> Upgrade system function 'WRREC' from V1.0 to V1.1 and released for TIA Portal V13
V3.0.0 <2015-02-28> Upgrade and released for TIA Portal V13 SP1 (without backup/restore master parameter)
V3.0.2 <2015-07-07> Change of #IOL_INDEX and #Port lower boundry to 0
---------------------------------------------------------------------------------------------------------------------*)
(*---------------------------------------------------------------------------------------------------------------------
Description of programmed IO-Link error codes
8000 = time out
8001 = wrong port
8002 = wrong index
8003 = wrong subindex
8005 = wrong length for write data record
8006 = wrong length for read data record
8052 = error during reading data record
8053 = error during writing data record
All other codes are coming from a higher level!
---------------------------------------------------------------------------------------------------------------------*)
(*---------------------------------------------------------------------------------------------------------------------
NEW REQUEST
---------------------------------------------------------------------------------------------------------------------*)
// detection rising edge of "REQ"
#R_TRIG_REQ := #REQ = TRUE AND #R_TRIG_REQ_old = FALSE;
#R_TRIG_REQ_old := #REQ = TRUE;
// start new request if not busy
IF #R_TRIG_REQ = TRUE AND #sequencecontrol = 0 THEN
// Freeze record ID and CAP
#WRREC_Function.ID := #ID;
#WRREC_Function.INDEX := #CAP;
#RDREC_Function.ID := #ID;
#RDREC_Function.INDEX := #CAP;
// Initialize outputs
#DONE_VALID := FALSE;
#BUSY := TRUE;
#ERROR := FALSE;
#STATUS := DW#16#00000000;
#IOL_STATUS := DW#16#00000000;
#RD_LEN := INT#0;
// Initialize data area
#read.header."CALL"."Port" := B#16#0;
#read.header.IOL.Index_LowByte := B#16#0;
#read.header.IOL.Index_HighByte := B#16#0;
#read.header.IOL.Subindex := B#16#0;
#i := INT#0; // initialize loop counter
FOR #i := 0 TO 231 DO
#write.data[#i] := B#16#0;
#read.data[#i] := B#16#0;
END_FOR;
(*---------------------------------------------------------------------------------------------------------------------
Setup IO-LINK Call needs a specific header
---------------------------------------------------------------------------------------------------------------------*)
// setup CALL header
#write.header."CALL".Extended_Function_Num := 16#08; // extended function number (fix coded 08h)
#write.header."CALL"."Port" := INT_TO_BYTE(#PORT); // 1..63 = PORT number, 64..255=reserved
#write.header."CALL".FI_Index := 65098; // IOL-Header is following (fix coded 65098)
// setup IOL header
// CONTROL = please see below at BODY
// INDEX
#write.header.IOL.Index_LowByte := INT_TO_BYTE(#IOL_INDEX);
#tmpWORD := INT_TO_WORD(#IOL_INDEX);
#tmpWORD := SHR(IN := #tmpWORD, N := 8);
#write.header.IOL.Index_HighByte := WORD_TO_BYTE(#tmpWORD);
// SUBINDEX
#write.header.IOL.Subindex := INT_TO_BYTE(#IOL_SUBINDEX);
// BODY (data max. 232 Byte, Array 0..231 of Byte)
IF #RD_WR = TRUE THEN
// IO-Link write data record requested, copy data from "RECORD_IOL_DATA"
#write.header.IOL.Control := B#16#02; // CONTROL B#16#02 = write data record
#wrrec.length := INT_TO_UINT(#LEN) + UINT#8; // data length header + data = IO-Link write data record
#typeofrequest := 2; // write data record
// copy IOL_RECORD_DATA in working area
#i := INT#0; // initialize loop counter
FOR #i := 0 TO #LEN - 1 DO
#write.data[#i] := #RECORD_IOL_DATA[#i];
END_FOR;
ELSE
// IO-Link read data record requested
#write.header.IOL.Control := 16#03; // CONTROL 16#03 = read data record
#wrrec.length := UINT#8; // data length only header = IO-Link read data record
#typeofrequest := 1; // read data record
END_IF;
#sequencecontrol := 1; // Start sequence
ELSE
;
END_IF;
(*---------------------------------------------------------------------------------------------------------------------
SEQUENCE CONTROL
---------------------------------------------------------------------------------------------------------------------*)
CASE #sequencecontrol OF
1: // Check input parameter
IF #PORT < INT#0 OR #PORT > INT#63 THEN // PORT (Wrong port address = 0x8001)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80010000;
#sequencecontrol := 99; // aborting function with error
ELSIF #IOL_INDEX < INT#0 OR #IOL_INDEX > INT#32767 THEN // INDEX (Wrong index = 0x8002)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80020000;
#sequencecontrol := 99; // aborting function with error
ELSIF #IOL_SUBINDEX < INT#0 OR #IOL_SUBINDEX > INT#255 THEN // SUBINDEX (Wrong subindex = 0x8003)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80030000;
#sequencecontrol := 99; // aborting function with error
ELSIF #typeofrequest = 2 AND (#LEN < 1 OR #LEN > 232) THEN // LEN (wrong length for write data record = 0x8004)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80050000;
#sequencecontrol := 99; // aborting function with error
ELSIF #typeofrequest = 1 AND (#LEN < 0 OR #LEN > 232) THEN // LEN (wrong length for read data record = 0x8005)
#ERROR := TRUE;
#IOL_STATUS := DW#16#80060000;
#sequencecontrol := 99; // aborting function with error
ELSE // all input parameter are right
#sequencecontrol := 2;
END_IF;
2: (*-------------------------------------------------------------------------------------------------------------
WRREC = Write Data Record
Note:
To read data records, the IO-Link master modules needs to know which PORT is required. Therefore it is necessary
to send at first a request via write data record (header, 8 byte). As response the IO-Link master module will
send the required data record.
-------------------------------------------------------------------------------------------------------------*)
#WRREC_Function(REQ := TRUE,
LEN := #wrrec.length,
DONE => #wrrec.done,
BUSY => #wrrec.busy,
ERROR => #wrrec.error,
STATUS => #wrrec.status,
RECORD := #write);
// output status during write data record
IF #wrrec.busy THEN
#STATUS := #wrrec.status;
#IOL_STATUS := DW#16#00020000; // 0002 = writing in progress
ELSIF #wrrec.error THEN
#tmpDWORD := #wrrec.status AND DW#16#00FFFF00; // filter status
IF #tmpDWORD = DW#16#0080C200 THEN // if resource #BUSY (#STATUS=80C2), then ...
#sequencecontrol := 3; // ... repeat write data record
ELSE
#ERROR := TRUE;
#STATUS := #wrrec.status; // ... otherwise output error status of "WRREC"
#IOL_STATUS := DW#16#80530000; // ... with note '8053' = error status of "WRREC"
#sequencecontrol := 99; // aborting function with error
END_IF;
ELSIF #wrrec.done = TRUE THEN // wait for write data record finish without error
#TP_poll(IN := TRUE,
PT := T#100ms); // poll for response
#sequencecontrol := 4;
ELSE
;
END_IF;
3: // repeat write data record because resource was busy
#WRREC_Function(REQ := FALSE);
#sequencecontrol := 2;
4: // wait and poll for response = Read Data Record (RDREC)
#WRREC_Function(REQ := FALSE);
#TP_poll(IN := TRUE,
PT := T#100ms);
// if poll rate executed then start read data record (on falling edge)
#F_TRIG_poll := #TP_poll.Q = FALSE AND #F_TRIG_poll_old = TRUE;
#F_TRIG_poll_old := #TP_poll.Q = TRUE;
// RDREC = Read Data Record
#RDREC_Function(REQ := #F_TRIG_poll,
MLEN := UINT#0, // length = 0 = read all data which are available
VALID => #rdrec.valid,
BUSY => #rdrec.busy,
ERROR => #rdrec.error,
STATUS => #rdrec.status,
LEN => #rdrec.length,
RECORD := #read);
// output status during read data record
IF #rdrec.busy THEN
#STATUS := #rdrec.status;
#IOL_STATUS := DW#16#00030000; // 16#0003 = reading in progress
ELSIF #rdrec.error = TRUE THEN
#tmpDWORD := #rdrec.status AND DW#16#00FFFF00; // filter status
IF #tmpDWORD = DW#16#0080C200 THEN // if resource busy (status=80C2), then ...
#sequencecontrol := 5; // ... repeat read data record / continue polling
ELSE
#ERROR := TRUE;
#STATUS := #rdrec.status; // ... otherwise output error code of "RDREC"
#IOL_STATUS := DW#16#80520000; // ... with note '8052' = error status of "RDREC"
#sequencecontrol := 99; // aborting function with error
END_IF;
ELSIF #rdrec.valid THEN
IF // check the response wether it matches the request (compare PORT, INDEX and SUBINDEX)
(#write.header."CALL"."Port" <> #read.header."CALL"."Port") OR
(#write.header.IOL.Index_HighByte <> #read.header.IOL.Index_HighByte) OR
(#write.header.IOL.Index_LowByte <> #read.header.IOL.Index_LowByte) OR
(#write.header.IOL.Subindex <> #read.header.IOL.Subindex)
THEN // read data record don't match the request
#ERROR := TRUE;
#STATUS := #rdrec.status;
#IOL_STATUS := DW#16#70000000; // output status '7000', no consistent data
#sequencecontrol := 99; // aborting function with error
ELSIF #read.header.IOL.Control = B#16#80 THEN // check the response for IO-Link errors
// State 0x80 = IOL_CALL_RES PDU shows IO-Link error detect
#ERROR := TRUE;
#STATUS := DW#16#00000000;
#IOL_STATUS.%B3 := #read.data[0]; // IO-Link master error code
#IOL_STATUS.%B2 := #read.data[1]; // IO-Link master error code
#IOL_STATUS.%B1 := #read.data[2]; // IO-Link device error code
#IOL_STATUS.%B0 := #read.data[3]; // IO-Link device additional error code
#sequencecontrol := 99; // aborting function with error
ELSE // read data are valid = output
#DONE_VALID := TRUE;
#BUSY := FALSE;
#ERROR := FALSE;
#STATUS := DW#16#00000000;
#IOL_STATUS := DW#16#00000000; // request finished
IF #typeofrequest = 1 THEN
#RD_LEN := UINT_TO_INT(#rdrec.length - UINT#8); // device parameter cover header and data,
// only data will be output
#i := INT#0; // initialize loop counter
FOR #i := 0 TO UINT_TO_INT(#rdrec.length - UINT#8 - UINT#1) DO
#RECORD_IOL_DATA[#i] := #read.data[#i];
END_FOR;
ELSE
;
END_IF;
#sequencecontrol := 98;
END_IF;
ELSE
;
END_IF;
5: // poll again for response because resource was busy
#TP_poll(IN := FALSE,
PT := T#100ms);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
#sequencecontrol := 4; // ... repeat read data record / continue polling
98: // request done successfully
#TP_poll(IN := FALSE,
PT := T#100ms);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
IF #REQ = FALSE THEN
#DONE_VALID := FALSE;
#BUSY := FALSE;
#ERROR := FALSE;
#RD_LEN := INT#0;
#STATUS := DW#16#00000000;
#IOL_STATUS := DW#16#00010000; // ready for new request
#sequencecontrol := 0;
#typeofrequest := 0;
ELSE
;
END_IF;
99: // Function aborted with error
#TP_poll(IN := FALSE,
PT := T#100ms);
#WRREC_Function(REQ := FALSE);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
#DONE_VALID := FALSE;
#BUSY := FALSE;
#RD_LEN := INT#0;
#sequencecontrol := 0;
#typeofrequest := 0;
ELSE // no relevant case, ready for new request
#WRREC_Function(REQ := FALSE);
#RDREC_Function(REQ := FALSE,
RECORD := #read);
#TP_poll(IN := FALSE,
PT := T#100ms);
#TON_monitoring(IN := FALSE,
PT := T#20s);
#sequencecontrol := 0;
#typeofrequest := 0;
END_CASE;
(*---------------------------------------------------------------------------------------------------------------------
MONITORING
---------------------------------------------------------------------------------------------------------------------*)
#TON_monitoring(IN := #sequencecontrol > 0 AND #sequencecontrol < 98,
PT := T#20s);
IF #TON_monitoring.Q THEN
#ERROR := TRUE;
#IOL_STATUS := DW#16#80000000; // request time out
#sequencecontrol := 99; // aborting function with error
END_IF;
Was einen Test mit S7-PCT und Siemens CPUs angeht, könnte ich schon was probieren aber ich hab halt nur eine altes S7-PCT V3.2 von ca. 2013 zur Hand.
Online Schalten gemacht, sie Screenshot, Wireshark. Kommunikation über Ethernet direkt zu CPU P1, PN-Device hängt an P2,
so dass die PN_IO Telegramme nicht im wireshark enthalten sind.
Hier als Zip.
Code:SET SAVE = L 26.1 U #R_TRIG_REQ_old NOT U #REQ = #R_TRIG_REQ U #REQ = #R_TRIG_REQ_old L #sequencecontrol L 0 ==I U #R_TRIG_REQ SPBN A7d0 CLR = #DONE_VALID SET = #BUSY CLR = #ERROR L DW#16#0 T #STATUS T #SF_STATUS L L#0 T #LENGTH T #segment T #address T #totallength U #RD_WR SPBN A7d1 L 2 T #typeofrequest L DW#16#10022800 T LD 32 L DIW [AR2,P#22.0] T LW 36 L DID [AR2,P#24.0] T LD 38 L DW#16#10022800 T LD 42 L DINO T LW 46 TAR2 + L#6544 T LD 48 TAR2 LD 28 UC SFC 20 P#L 32.0 P#L 0.0 P#L 42.0 LAR2 LD 28 L #RetVal_BLKMOV SPA A7d2 A7d1: L 1 T #typeofrequest L 0 T #i A7d3: L #i L 10239 <=I SPBN A7d2 L #i ITD L L#0 +D L L#8 *D TAR2 +D L B#16#0 TAK LAR1 TAK T DIB [AR1,P#818.0] L #i L 1 +I T #i SPA A7d3 A7d2: L 1 T #sequencecontrol SPA A7d5 A7d0: CLR A7d5: L #sequencecontrol L 1 TAK ==I T LW 32 SPB A7d7 SPA A7d8 A7d7: L B#16#1 T #rec.reset.ExtendedFunctionNum L DW#16#FFFFFFFF T #rec.reset.SequenceNo L DW#16#FF T #STATUS L 2 T #sequencecontrol SPA A7d6 A7d8: L 2 L LW 32 ==I SPB A7d9 SPA A7da A7d9: SET = #WRREC_Function.REQ L #ID T #WRREC_Function.ID L #index T #WRREC_Function.INDEX L 6 T #WRREC_Function.LEN L DW#16#100200F0 T DID [AR2,P#72.0] L DINO T DIW [AR2,P#76.0] TAR2 + L#784 T DID [AR2,P#78.0] +AR2 P#56.0 UC SFB 53 +AR2 P#8136.0 U #WRREC_Function.DONE = #wrrec_if.done U #WRREC_Function.BUSY = #wrrec_if.busy U #WRREC_Function.ERROR = #wrrec_if.error L #WRREC_Function.STATUS T #wrrec_if.status U #wrrec_if.done SPBN A7db L #wrrec_if.status T #SF_STATUS L 3 T #sequencecontrol SPA A7d6 A7db: CLR U #wrrec_if.error L #rdrec_if.status L DW#16#DF80B000 = L 26.2 ==D U L 26.2 SPBN A7dd SET = #ERROR L DW#16#30000 T #STATUS L #rdrec_if.status T #SF_STATUS L 99 T #sequencecontrol SPA A7d6 A7dd: CLR U #wrrec_if.error SPBN A7de SET = #ERROR L DW#16#30000 T #STATUS L #wrrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A7de: SPA A7d6 A7da: L 3 L LW 32 ==I SPB A7df SPA A7e0 A7df: CLR = #WRREC_Function.REQ L #ID T #WRREC_Function.ID L #index T #WRREC_Function.INDEX L 6 T #WRREC_Function.LEN L DW#16#100200F0 T DID [AR2,P#72.0] L DINO T DIW [AR2,P#76.0] TAR2 + L#784 T DID [AR2,P#78.0] +AR2 P#56.0 UC SFB 53 +AR2 P#8136.0 U #WRREC_Function.DONE = #wrrec_if.done U #WRREC_Function.BUSY = #wrrec_if.busy U #WRREC_Function.ERROR = #wrrec_if.error L #WRREC_Function.STATUS T #wrrec_if.status U #wrrec_if.done NOT SPBN A7e1 L DW#16#FF T #STATUS L 4 T #sequencecontrol SPA A7d6 A7e1: CLR U #wrrec_if.error SPBN A7e3 SET = #ERROR L #wrrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A7e3: SPA A7d6 A7e0: L 4 L LW 32 ==I SPB A7e4 SPA A7e5 A7e4: L #typeofrequest L 1 ==I SPBN A7e6 L DW#16#100FF T #STATUS L 10 T #sequencecontrol SPA A7d6 A7e6: L #typeofrequest L 2 ==I SPBN A7e8 L DW#16#200FF T #STATUS L 20 T #sequencecontrol SPA A7d6 A7e8: SET = #ERROR L DW#16#300FF T #STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A7e5: L 10 L LW 32 ==I SPB A7e9 SPA A7ea A7e9: SET = #RDREC_Function.REQ L #ID T #RDREC_Function.ID L #index T #RDREC_Function.INDEX L 240 T #RDREC_Function.MLEN L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 U #RDREC_Function.VALID = #rdrec_if.valid U #RDREC_Function.BUSY = #rdrec_if.busy U #RDREC_Function.ERROR = #rdrec_if.error L #RDREC_Function.STATUS T #rdrec_if.status L #RDREC_Function.LEN T #rdrec_if.length U #rdrec_if.valid SPBN A7eb L #rdrec_if.length L 6 >I L #rec.backup.ExtendedFunctionNum L B#16#2 = L 26.2 ==I U L 26.2 SPBN A7ec L DW#16#10000 L #rec.backup.SequenceNo OD T #STATUS L #rdrec_if.status T #SF_STATUS L #rec.backup.SequenceNo T #segment L #rdrec_if.length L 6 -I T #tmplength L DW#16#100200EA T LD 34 L DINO T LW 38 TAR2 + L#2752 T LD 40 L LD 34 T LD 4 L LD 38 T LD 8 L LW 42 T LW 12 L #tmplength T #ANYsource.length L #address L L#0 +D L L#8 *D TAR2 +D LAR1 L DIB [AR1,P#818.0] TAK T LD 44 TAK L DW#16#10020001 T LD 34 L DINO T LW 38 L LD 44 + L#6544 OD DW#16#84000000 T LD 40 L LD 34 T LD 14 L LD 38 T LD 18 L LW 42 T LW 22 L #tmplength T #ANYdestination.length L LD 4 T LD 34 L LD 8 T LD 38 L LW 12 T LW 42 L LD 14 T LD 48 L LD 18 T LD 52 L LW 22 T LW 56 TAR2 LD 28 UC SFC 20 P#L 34.0 P#L 0.0 P#L 48.0 LAR2 LD 28 L #RetVal_BLKMOV L #RetVal_BLKMOV L 0 <>I SPBN A7ed SET = #ERROR L DW#16#110FF T #STATUS L #RetVal_BLKMOV UD DW#16#FFFF T #SF_STATUS L 99 T #sequencecontrol SPA A7ee A7ed: CLR A7ee: L #tmplength ITD L #totallength +D T #totallength L #tmplength ITD L #address +D T #address SPA A7d6 A7ec: L #rdrec_if.length L 6 ==I SPBN A7f0 L DW#16#10022800 T LD 34 L DINO T LW 38 TAR2 + L#6544 T LD 40 L LD 34 T LD 4 L LD 38 T LD 8 L LW 42 T LW 12 L W#16#2800 T #ANYsource.length L DW#16#10022800 T LD 34 L DIW [AR2,P#22.0] T LW 38 L DID [AR2,P#24.0] T LD 40 L LD 34 T LD 14 L LD 38 T LD 18 L LW 42 T LW 22 L W#16#2800 T #ANYdestination.length L LD 4 T LD 34 L LD 8 T LD 38 L LW 12 T LW 42 L LD 14 T LD 48 L LD 18 T LD 52 L LW 22 T LW 56 TAR2 LD 28 UC SFC 20 P#L 34.0 P#L 0.0 P#L 48.0 LAR2 LD 28 L #RetVal_BLKMOV L #RetVal_BLKMOV L 0 <>I SPBN A7f1 SET = #ERROR L DW#16#110FF T #STATUS L #RetVal_BLKMOV UD DW#16#FFFF T #SF_STATUS L 99 T #sequencecontrol SPA A7f2 A7f1: CLR A7f2: SET = #DONE_VALID CLR = #BUSY = #ERROR L DW#16#10000 L #rec.backup.SequenceNo OD T #STATUS L #rdrec_if.status T #SF_STATUS L #totallength T #LENGTH L 11 T #sequencecontrol SPA A7d6 A7f0: SPA A7d6 A7eb: CLR U #rdrec_if.error SPBN A7f4 CLR = #DONE_VALID = #BUSY SET = #ERROR L #rdrec_if.status T #SF_STATUS L #rdrec_if.length ITD T #LENGTH L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A7f4: SPA A7d6 A7ea: L 11 L LW 32 ==I SPB A7f5 SPA A7f6 A7f5: CLR = #RDREC_Function.REQ L #ID T #RDREC_Function.ID L #index T #RDREC_Function.INDEX L 240 T #RDREC_Function.MLEN L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 U #RDREC_Function.VALID = #rdrec_if.valid U #RDREC_Function.BUSY = #rdrec_if.busy U #RDREC_Function.ERROR = #rdrec_if.error L #RDREC_Function.STATUS T #rdrec_if.status L #RDREC_Function.LEN T #rdrec_if.length U #rdrec_if.valid NOT SPBN A7f7 L 98 T #sequencecontrol SPA A7d6 A7f7: CLR U #rdrec_if.error SPBN A7f9 CLR = #DONE_VALID = #BUSY SET = #ERROR L #rdrec_if.status T #SF_STATUS L #rdrec_if.length ITD T #LENGTH L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A7f9: SPA A7d6 A7f6: L 20 L LW 32 ==I SPB A7fa SPA A7fb A7fa: L B#16#1 T #rec.restore.ExtendedFunctionNum L #segment T #rec.restore.SequenceNo L DW#16#20000 L #rec.restore.SequenceNo OD T #STATUS L #address L L#0 +D L L#8 *D TAR2 +D LAR1 L DIB [AR1,P#818.0] TAK T LD 48 TAK L DW#16#10020001 T LD 34 L DINO T LW 38 L LD 48 + L#6544 OD DW#16#84000000 T LD 40 L LD 34 T LD 4 L LD 38 T LD 8 L LW 42 T LW 12 L W#16#EA T #ANYsource.length L DW#16#100200EA T LD 34 L DINO T LW 38 TAR2 + L#4672 T LD 40 L LD 34 T LD 14 L LD 38 T LD 18 L LW 42 T LW 22 L W#16#EA T #ANYdestination.length L LD 4 T LD 34 L LD 8 T LD 38 L LW 12 T LW 42 L LD 14 T LD 52 L LD 18 T LD 56 L LW 22 T LW 60 TAR2 LD 28 UC SFC 20 P#L 34.0 P#L 0.0 P#L 52.0 LAR2 LD 28 L #RetVal_BLKMOV L #RetVal_BLKMOV L 0 <>I SPBN A7fc SET = #ERROR L #RetVal_BLKMOV UD DW#16#FFFF T #SF_STATUS L 99 T #sequencecontrol SPA A7d6 A7fc: L 21 T #sequencecontrol SPA A7d6 A7fb: L 21 L LW 32 ==I SPB A7fe SPA A7ff A7fe: SET = #WRREC_Function.REQ L #ID T #WRREC_Function.ID L #index T #WRREC_Function.INDEX L 240 T #WRREC_Function.LEN L DW#16#100200F0 T DID [AR2,P#72.0] L DINO T DIW [AR2,P#76.0] TAR2 + L#4624 T DID [AR2,P#78.0] +AR2 P#56.0 UC SFB 53 +AR2 P#8136.0 U #WRREC_Function.DONE = #wrrec_if.done U #WRREC_Function.BUSY = #wrrec_if.busy U #WRREC_Function.ERROR = #wrrec_if.error L #WRREC_Function.STATUS T #wrrec_if.status U #wrrec_if.done SPBN A800 L #totallength L L#234 +D T #totallength L #wrrec_if.status T #SF_STATUS L 22 T #sequencecontrol SPA A7d6 A800: CLR U #wrrec_if.error SPBN A802 SET = #ERROR L #wrrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A802: SPA A7d6 A7ff: L 22 L LW 32 ==I SPB A803 SPA A804 A803: CLR = #WRREC_Function.REQ L #ID T #WRREC_Function.ID L #index T #WRREC_Function.INDEX L 240 T #WRREC_Function.LEN L DW#16#100200F0 T DID [AR2,P#72.0] L DINO T DIW [AR2,P#76.0] TAR2 + L#4624 T DID [AR2,P#78.0] +AR2 P#56.0 UC SFB 53 +AR2 P#8136.0 U #WRREC_Function.DONE = #wrrec_if.done U #WRREC_Function.BUSY = #wrrec_if.busy U #WRREC_Function.ERROR = #wrrec_if.error L #WRREC_Function.STATUS T #wrrec_if.status U #wrrec_if.done NOT SPBN A805 L #wrrec_if.status T #SF_STATUS L 23 T #sequencecontrol SPA A7d6 A805: CLR U #wrrec_if.error SPBN A807 SET = #ERROR L #wrrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A807: SPA A7d6 A804: L 23 L LW 32 ==I SPB A808 SPA A809 A808: SET = #RDREC_Function.REQ L #ID T #RDREC_Function.ID L #index T #RDREC_Function.INDEX L 240 T #RDREC_Function.MLEN L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 U #RDREC_Function.VALID = #rdrec_if.valid U #RDREC_Function.BUSY = #rdrec_if.busy U #RDREC_Function.ERROR = #rdrec_if.error L #RDREC_Function.STATUS T #rdrec_if.status L #RDREC_Function.LEN T #rdrec_if.length U #rdrec_if.valid L #rec.backup.ExtendedFunctionNum L B#16#2 = L 26.2 ==I U L 26.2 SPBN A80a L #rec.backup.SequenceNo L DW#16#FFFFFF01 ==D SPBN A80b L #segment L L#1 +D T #segment L #address L L#234 +D T #address L DW#16#FFFFFF01 T #STATUS L 24 T #sequencecontrol SPA A7d6 A80b: L #rec.backup.SequenceNo L DW#16#FFFFFF02 ==D SPBN A80d L #segment L L#1 +D T #segment L #address L L#234 +D T #address L DW#16#FFFFFF02 T #STATUS L 24 T #sequencecontrol SPA A7d6 A80d: L #rec.backup.SequenceNo L DW#16#FFFFFF03 ==D SPBN A80e T #STATUS L 25 T #sequencecontrol SPA A7d6 A80e: L #rec.backup.SequenceNo L DW#16#FFFFFF04 ==D SPBN A80f SET = #ERROR T #STATUS L 99 T #sequencecontrol SPA A7d6 A80f: L #rec.backup.SequenceNo L DW#16#FFFFFF05 ==D SPBN A810 SET = #ERROR T #STATUS L 99 T #sequencecontrol SPA A7d6 A810: L #rec.backup.SequenceNo L DW#16#FFFFFF06 ==D SPBN A811 SET = #ERROR T #STATUS L 99 T #sequencecontrol SPA A7d6 A811: L #rec.backup.SequenceNo L DW#16#FFFFFF07 ==D SPBN A812 SET = #ERROR T #STATUS L 99 T #sequencecontrol SPA A7d6 A812: SPA A7d6 A80a: CLR U #rdrec_if.error SPBN A814 SET = #ERROR L #rdrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A814: SPA A7d6 A809: L 24 L LW 32 ==I SPB A815 SPA A816 A815: CLR = #RDREC_Function.REQ L #ID T #RDREC_Function.ID L #index T #RDREC_Function.INDEX L 240 T #RDREC_Function.MLEN L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 U #RDREC_Function.VALID = #rdrec_if.valid U #RDREC_Function.BUSY = #rdrec_if.busy U #RDREC_Function.ERROR = #rdrec_if.error L #RDREC_Function.STATUS T #rdrec_if.status L #RDREC_Function.LEN T #rdrec_if.length U #rdrec_if.valid NOT SPBN A817 L 20 T #sequencecontrol SPA A7d6 A817: CLR U #rdrec_if.error SPBN A819 SET = #ERROR L #rdrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A819: SPA A7d6 A816: L 25 L LW 32 ==I SPB A81a SPA A81b A81a: CLR = #RDREC_Function.REQ L #ID T #RDREC_Function.ID L #index T #RDREC_Function.INDEX L 240 T #RDREC_Function.MLEN L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 U #RDREC_Function.VALID = #rdrec_if.valid U #RDREC_Function.BUSY = #rdrec_if.busy U #RDREC_Function.ERROR = #rdrec_if.error L #RDREC_Function.STATUS T #rdrec_if.status L #RDREC_Function.LEN T #rdrec_if.length U #rdrec_if.valid NOT SPBN A81c SET = #DONE_VALID CLR = #BUSY = #ERROR L #rdrec_if.status T #SF_STATUS L #totallength T #LENGTH L 98 T #sequencecontrol SPA A7d6 A81c: CLR U #rdrec_if.error SPBN A81e SET = #ERROR L #rdrec_if.status T #SF_STATUS L #sequencecontrol T #errorTrigger L 99 T #sequencecontrol SPA A7d6 A81e: SPA A7d6 A81b: L 98 L LW 32 ==I SPB A81f SPA A820 A81f: CLR = #RDREC_Function.REQ L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 CLR = #WRREC_Function.REQ +AR2 P#56.0 UC SFB 53 +AR2 P#8136.0 U #REQ NOT SPBN A7d6 CLR = #DONE_VALID L DW#16#0 T #STATUS T #SF_STATUS L L#0 T #LENGTH L 0 T #sequencecontrol T #typeofrequest SPA A7d6 A820: L 99 L LW 32 ==I SPB A822 SPA A823 A822: CLR = #RDREC_Function.REQ L DW#16#100200F0 T DID [AR2,P#46.0] L DINO T DIW [AR2,P#50.0] TAR2 + L#2704 T DID [AR2,P#52.0] +AR2 P#28.0 UC SFB 52 +AR2 P#8164.0 CLR = #WRREC_Function.REQ +AR2 P#56.0 UC SFB 53 +AR2 P#8136.0 CLR = #DONE_VALID = #BUSY L L#0 T #LENGTH L 0 T #sequencecontrol T #typeofrequest SPA A7d6 A823: CLR A7d6: CLR U L 26.1 SAVE BE
Du hast bei deiner AWL-Quelle vermutlich den IO_LINK_MASTER gepostet, von dem liefert Siemens auch die SCL-Quelle mit.
Wenn man aber in den IO_LINK_DEVICE reinschaut, dann sieht man zumindest in den STAT-Variablen in der Struct "read.header" den Aufbau des Datenteils das auch übers Netzwerk geht. Glücklicherweise mit Kommentar Leider fehlt hier die SCL-Quelle, müsste man sich anfertigen wenn das weiterhilft.
Wir verwenden essentielle Cookies, damit diese Website funktioniert, und optionale Cookies, um den Komfort bei der Nutzung zu verbessern.
Siehe weitere Informationen und konfiguriere deine Einstellungen