S7 pointer to an array question

twu026

Lifetime Supporting Member
Join Date
Jan 2008
Location
Auckland
Posts
62
I need a bit of help with pointers in S7. I am a AB and Omron person who has done some simple S7 programming before (but I have avoided STL altogether).

I wanted to implement a simple fault logging code in a S7-300 PLC but did not realise how hard it was going to be!

What I want to achieve is simple.

- Define a 'fault_event' UDT which has a 'faultcode', 'date' and 'time' properties.
- Define an array of 50 'fault_event' UDTs to make up my 'fault_log'.
- Every time there is a new fault I want to write to the 'i' location in my 'fault_log' then increment 'i' (unless it greater than 50 in which case I reset it to 0).

Just goes to show now little I know about S7. I thought I could simply do a move/copy of the current faultcode, date and time to any element in the fault array defined by the index 'i'. Thought it would be something like this:

IF (i < 0) OR (i > 50) THEN

i := 0;

END_IF;

IF new_fault THEN

FaultLog.FaultCode := CurrentFaultCode;
FaultLog.FaultDate := CurrentDate;
FaultLog.FaultTime := CurrentTime;
i := i+1;

END_IF;

(Note, I was intending to implement the above in ladder but only expressed it in structured text so it is easier to post).

After diving into it and attempting to implement the above code in ladder (and failing miserably).
I now realise I need to use STL and instructions such as AR1 and P# etc. But I can not find any examples of indirect addressing related to arrays of UDT.

Anyone out there have sample code I can look at?
 
Last edited:
'FaultCode' is of type INT
'FaultDate' is of type DATE
'FaultTime' is of type TIME_OF_DAY

They are declared in that order in the UDT
 
Hi there !!
See if this helps you or gives you some idea how to do it.
Caution: Code is not checked :D


Code:
FUNCTION_BLOCK "Fault_Date_time"
TITLE =
VERSION : 0.1
CODE_VERSION1


VAR_INPUT
  fault_number : INT ;    
END_VAR
VAR
  fault_code : ARRAY  [1 .. 50 ] OF INT ;    
  Date_time : ARRAY  [1 .. 50 ] OF DATE_AND_TIME ;    
  save_fault_pointer : DWORD ;    
  save_date_time_pointer : DWORD ;    
  iCount : INT ;    
  current_time : DATE_AND_TIME ;    
END_VAR
VAR_TEMP
  return : INT ;    
  ar2_loop : DWORD ;    
  in_count : INT ;    
  save_ar2 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =

      CALL "READ_CLK" (
           RET_VAL                  := #return,
           CDT                      := #current_time);

      TAR2  #save_ar2; 

      AN    M     50.0; 
      JCN   clk1; 
      LAR1  P##fault_code; 
      TAR1  #save_fault_pointer; 

      LAR1  P##Date_time; 
      TAR1  #save_date_time_pointer; 



clk1: A     M     50.1; 
      FP    M     50.2; 
      JCN   clk2; 
      SET   ; 
      S     M     50.0; 

      LAR1  P##save_fault_pointer; 
      L     #fault_number; 
      T     W [AR1,P#0.0]; 
      +AR1  P#2.0; 
      TAR1  #save_fault_pointer; 


      L     #save_date_time_pointer; 
      T     #ar2_loop; 

      LAR1  P##current_time; 
      LAR2  #ar2_loop; 


      L     8; 
m1:   T     #in_count; 
      L     B [AR1,P#0.0]; 
      T     B [AR2,P#0.0]; 
      +AR1  P#1.0; 
      +AR2  P#1.0; 
      L     #in_count; 
      LOOP  m1; 
      LAR2  #save_ar2; 


      LAR1  #save_date_time_pointer; 
      +AR1  P#8.0; 
      TAR1  #save_date_time_pointer; 

      L     #iCount; 
      L     1; 
      +I    ; 
      T     #iCount; 
      L     50; 
      >=I   ; 
      JCN   clk2; 
      L     0; 
      T     #iCount; 
      SET   ; 
      R     M     50.0; 

clk2: NOP   0; 

END_FUNCTION_BLOCK
 
Thanks Manmeet for the code.

I will try my best to understand it. Some comments would help me greatly.
 
As a side comment.

Is it just me or does Siemens make indirect addressing of arrays extremely painful?
 
The whole Siemens philosophy is wrong

As a side comment.

Is it just me or does Siemens make indirect addressing of arrays extremely painful?
I am not a fan.
http://www.plctalk.net/qanda/showthread.php?t=39785&highlight=Siemens
http://www.plctalk.net/qanda/showthread.php?t=47521&highlight=Siemens
These threads are long but cover many advanced topics.

I believe that PLCs are just tools that are used to solve application problems. Siemens believes you should put in at least as much mental energy into using their PLC as what you put into the application. In short Siemens is a mental energy and time sink.

You have demonstrated that you know how to solve the problem. Your pseudo code looks good. It is the tool that is in your way.
 
Here is the commented and checked code.
Copy paste the blocks to your existing blocks.
Error found in code pasted above is rectified.
 
Here's another example showing how to write a UDT into an array of UDTs.

I've coded it so that it automatically adapts to the size of the UDT (if you change the UDT size then of course you have to perform an interface update on the blocks)
 
Since you start with and know structured text, why dont you consider SCL ?
It would be very easy to implement your code, and you can even reuse ST code from other platforms.

🤾
 

Similar Topics

Not sure if this is possible but thought I would put it out there. Using Rockwell Studio 5000, is it possible to shift the address of an array...
Replies
7
Views
2,092
Hello, I'm still fresh in plc programming so I have still many questions to answer. I searched forum/web for similar topic but i didn't anything...
Replies
1
Views
2,673
Must modify / expand a program which is made with a many block move (SFC20) as shown in the attached image. It moves data between array of...
Replies
13
Views
13,994
Hi! I modified some code, probably from member LD, to make a function element := ReadFromArray(firstElement : ANY, offset : INT) It seems...
Replies
2
Views
4,157
Hi all....... someone knows if is possible in S7, using the indirect adressing by means of a pointer L P## to read a data struct defined as...
Replies
5
Views
3,720
Back
Top Bottom