Loop Problem

sparkysliderz

Member
Join Date
Feb 2005
Location
Posts
68
I'm still really trying to get to terms with S7 indirect addressing and I found a piece of code that I thought would help with a practical example, i can go online in OB1 with no problem but whenever I go online to FB100 the plc faults with "STOP caused by priority class system" and "Cycle time exceeded" so I'm guessing its getting stuck in the loop somewhere, but I dont know where!

Here is the code for FB100

FUNCTION_BLOCK FB 100
TITLE =
VERSION : 0.1

VAR_INPUT
x0 : BOOL ;
x1 : BOOL ;
x2 : BOOL ;
x3 : BOOL ;
x4 : BOOL ;
x5 : BOOL ;
x6 : BOOL ;
x7 : BOOL ;
x8 : BOOL ;
x9 : BOOL ;
x10 : BOOL ;
x11 : BOOL ;
x12 : BOOL ;
x13 : BOOL ;
x14 : BOOL ;
x15 : BOOL ;
x16 : BOOL ;
x17 : BOOL ;
x18 : BOOL ;
x19 : BOOL ;
x20 : BOOL ;
x21 : BOOL ;
x22 : BOOL ;
x23 : BOOL ;
x24 : BOOL ;
x25 : BOOL ;
x26 : BOOL ;
x27 : BOOL ;
x28 : BOOL ;
x29 : BOOL ;
x30 : BOOL ;
x31 : BOOL ;
tV_TIMER : TIMER ;
tV_LAST : S5TIME ;
END_VAR
VAR_OUTPUT
y0 : BOOL ;
y1 : BOOL ;
y2 : BOOL ;
y3 : BOOL ;
y4 : BOOL ;
y5 : BOOL ;
y6 : BOOL ;
y7 : BOOL ;
y8 : BOOL ;
y9 : BOOL ;
y10 : BOOL ;
y11 : BOOL ;
y12 : BOOL ;
y13 : BOOL ;
y14 : BOOL ;
y15 : BOOL ;
y16 : BOOL ;
y17 : BOOL ;
y18 : BOOL ;
y19 : BOOL ;
y20 : BOOL ;
y21 : BOOL ;
y22 : BOOL ;
y23 : BOOL ;
y24 : BOOL ;
y25 : BOOL ;
y26 : BOOL ;
y27 : BOOL ;
y28 : BOOL ;
y29 : BOOL ;
y30 : BOOL ;
y31 : BOOL ;
END_VAR
VAR
hsp : BOOL ;
END_VAR
VAR_TEMP
SLZ : INT ;
END_VAR
BEGIN
NETWORK
TITLE =
L P##x0;
TAR2 ;
SLD 8;
SRD 8;
+D ;
LAR1 ;
L #tV_LAST;
A #tV_TIMER;
R #hsp;
A #hsp;
SE #tV_TIMER;
L 32;
xyz0: T #SLZ;
T #SLZ;
A [AR1,P#0.0];
AN [AR1,P#8.0];
AN #hsp;
S #hsp;
S [AR1,P#8.0];
AN [AR1,P#0.0];
R [AR1,P#8.0];
+AR1 P#0.1;
L #SLZ;
LOOP xyz0;
SET ;
SAVE ;
END_FUNCTION_BLOCK

Thanks (again!) for your help guys
 
Well, I guess I'm not much further on than you when it comes to playing with indirect addressing, so maybe we can both learn something together from this Thread.

First point I would ask is what you're trying to do right at the start, with Address Reg 2 - I haven't fully understood when and for what AR2 is used yet, other than in FB instances (amongst others) and since I don't understand it, I stay well away from it! You are loading your local variable address x0, which transfers it into AKKU1, then, before doing anything with it, you're overwiting the contents of AKKU1 immediately with the Contents of AR2 - so now you've lost your P##x0!

I assume with your SLD 8 and SRD 8 you're just trying to strip out the Operand (memory area) description Bits, but I'm not certain that that's necessary in this case.

In order to get much further, it would be useful if you could tell us what you're trying to achieve, it's not easy trying fathom it all out from a few cryptic Symbolic names! For that matter it would be very helpful for us if you would comment every operation (for you too, in six months time!), then it would be a lot easier to see if what you're actually doing is the same as what you intended to do. I have the feeling that in the case of AR2, it's not!

OK, let's get this show on the road!
 
Are saying that cycle time is only exceeded if you monitor FB100, but if you just leave the plc alone it doesn't fault out on cycle time ?

Which plc are you using ? (313,315,317 ?)
 
Well, RMA! I certainly think your further up the "ladder" than me when it comes to understanding indirect addressing!

the code I posted comes from an application (that I aquired somewhere!) that delays the starting of upto 32 things, in OB1 if "x0" is true then after a value of delay passed in as MW10 the corresponding "y0" is true, I then used "y0" to set "x1" true on the function call and then cascade down until all the "y's" are true.

Because I dont fully understand indirect addressing then I thought I could use this code to monitor FB100 while it was running to try to see HOW it worked! as for "stripping out the operand" and overwriting "P##x0" to be honest I dont really understand them anyway!

Simon I just spotted your post!
Im using a CPU314 at the moment and yes everytime I open FB100 online the cpu stops on the error I mentioned earlier in my post.
 
There are two "T #SLZ" instructions right after each other at the loop start at "xyz0:". That cant be right. Unfortunately it shouldnt be harmful either so it cannot be the explanation.

I would comment out all the indirect addressing stuff, and then see if the loop will execute correctly.
If thats OK, then you can go on to find out how the indirect addressing must work.
 
Although this piece of code is not something I would use as an example for "learning" indirect addressing, it will not get stuck in a loop. Your cycle time problem sounds like it is due to the monitoring taking place, not a coding error.
 
Just a follow-up question for Simon, since you seem to be pretty familiar with this stuff, can you explain what's being done in the first few lines of the program:

L P##x0; //This I'm pretty sure loads the pointer into AKKU1
TAR2 ; //Unless I've misunderstood the instruction this then overwrites AKKU1 with the current value in AR2
SLD 8; //These two lines appear to be stripping out the memory area Bits
SRD 8; //but is it really necessary?
+D ;
LAR1 ;

Can you briefly explain when and how you use AR2 in something like this.

Hope I'm not being too much of a pain!

Cheers

Roy
 
I created an FB101 with two instances of FB100 declared in the static data area and then called
instance 1 and then instance 2 from within FB101.
I called FB101 from OB1 supplying the instance DB number.

Here is the decription for the first instance of FB100 being called:

L P##x0; //As X0 is the first input parameter, Accu1=85000000 i.e. Instance data area, address=0
TAR2 ; //Ar2 points to this FB's instance data block. As its the first instance, Accu1=84000000, i.e. global DB, adress=0
//Note that Accu2=85000000 so it has not been lost
SLD 8; //Accu1 = 0, yes the memory area has been cleared
SRD 8; //Accu1 = 0, the accu1 now has the correct offset to X0 from the start of the instance data
+D ; //Accu1 = 85000000
LAR1 ; //AR1= 85000000 i.e. instance data, address offset 0, i.e. AR1 points to parameter X0 in the first instance

Now for the second instance:

L P##x0; //As X0 is the first input parameter, Accu1=85000000 i.e. Instance data area, address=0
TAR2 ; //Ar2 points to this FB's instance data. As its the second instance, Accu1=84000070, i.e. global DB, adress=byte 14
//Note that Accu2=85000000 so it has not been lost
SLD 8; //Accu1 = 7000, yes the memory area has been cleared
SRD 8; //Accu1 = 70, the accu1 now has the correct offset to X0 from the start of the instance data
+D ; //Accu1 = 85000070
LAR1 ; //AR1= 85000070 i.e. instance data, address offset to byte 14, i.e. AR1 points to parameter X0 in the second instance.

Other comments:

(1) If you added another parameter in front of x0, the L P##x0 ensures that you will point to the correct area in the instance data

(2) in the code example, it just so happens that y0 is located 8 bytes further down the instance data (look in the instance DB to check). This bit of code will work as long as this fact remains true.

A [AR1,P#0.0] //this is A x
AN [AR1,P#8.0] //this is AN y

If another parameter was added the the block, y0 would now not be located 8 bytes away and the results would be messy!
To code this block properly, referencing of the y0 area should be done in the same way as the x0 area.

Hope this peels back another layer of the onion.
 
Thanks Simon, that explanation was up to Ron Beaufort's standards of clarity and he sets the bar pretty high!

I think I've now got a pretty good grip on it, let's hope sparkysliderz can manage to swallow it as well. With a bit of luck there will be quite a few others benefiting from this Thread.

Once again many thanks for your time and trouble.

Cheers

Roy

PS I was definitely having an off moment forgetting that the contents of AKKU1 were being moved into AKKU2 on the TAR2 instruction. That much should be second nature by now!
 
Last edited:
Sparky.
About the CPU going into fault by Cycle Time Exceeded:

Maybe this is because the scantime is just below the limit, and when going online with the the PC, the scan time is extended a little bit because it has to service the extra communication.

It would be nice to know what cycle time you have when you are offline.
Here is how to:
As the last thing in OB1, copy the scantime (#OB1_last_cycletime or something, I am writing this from an airport lounge, so bear with me) to an intermediary word.
You can then investigate the word even if the CPU is in STOP.
The word will contain the scantime before the fault.
 
Sorry Jesper, maybe I'm being a bit thick this morning, but why do you emphasise doing the copy as the last command in OB1? Surely the value in OB1_PREV_CYCLE is loaded when OB1 is started (it is the time of the previous cycle, after all) and will remain constant for the whole of the current cycle. I would have thought you could copy the value at any point in the cycle - but as I say, maybe I'm slower on the uptake than usual today!
 
The method for getting AR1 to point to the correct instance of x0 from Sparky's code is :

L P##x0
TAR2
SLD 8
SRD 8
+D
LAR1

The more recognised coding (i.e. from Berger) is as follows:

TAR2 //Instance base address to Acc1
OD DW#16#FFFFFF //mask off area bits
LAR1 P##x0 //ar1 contains offset to x0
+AR1 //ar1 contains address of this instance of x0

Even thought the latter code has 2 fewer lines of instruction, they both occupy the same amount of code space.

Concerning Jespers suggestion for storing the scan time, be wary of how you monitor this. If you do write the scan time to a marker word, the act of monitoring the marker word will actually increase the scan time ! For monitoring scan times, I store the scan time in a DB containing an array of values, incrementing the index each scan (another example of indirect addressing!). A bit controls whether the scan is stored or not. I can turn the monitoring on then off and then inspect the DB and see the scan times under different conditions.
 
The more recognised coding (i.e. from Berger) is as follows:



I was going to say that I thought Sparky's version was easier to follow, then I looked at the Berger quote again and now I'm doubly puzzled! Either I don't understand Boolean algebra, despite working it for more than 35 years, or I don't understand how Siemens implements it. Reading the STL manual didn't really make things any clearer either (a second reading turned up a detailed example for the OW command which seems to support my view)! Surely the "OD DW#16#FFFFFF" command is going to leave FFFFFF in AKKU1 afterwards. At first I thought it was supposed to be XOD, but that gives the opposite of what you want.

Having gone and made myself a second cup of tea (and coming to the conclusion that I really am a bit slow this morning) I realise that of course it should be "AD DW#16#FFFFFF" (assuming I've got the English mnemonic right).

I still think Sparky's version is easier to follow though!

As far as monitoring the cycle time is concerned, while I can see the advantages of having a permanent built-in setup which you can enable and disable at will, since even a 312C has WORD operation time of 2µs, and the cycle time has a resolution of 1ms (I assume - that's what it says in the comment at any rate) I don't see a single load and store operation is going to be very significant. I suppose theoretically it could be the straw that broke the camel's back and pushed you from 3(.998)ms to 4(.002)ms, but I reckon the chances of that being the case are small enough to discount.
 
RMA said:
Sorry Jesper, maybe I'm being a bit thick this morning, but why do you emphasise doing the copy as the last command in OB1? Surely the value in OB1_PREV_CYCLE is loaded when OB1 is started (it is the time of the previous cycle, after all) and will remain constant for the whole of the current cycle. I would have thought you could copy the value at any point in the cycle - but as I say, maybe I'm slower on the uptake than usual today!
No, it is me that is confused (downing too many free drinks in that lounge - this is from another lounge in the next step of my journey).
It doesnt matter where the copying is done.
 

Similar Topics

Just to check my sanity even though I think I found the solution. So, for this loop with long lag time we got 2 PID loops with the Outer Loop...
Replies
1
Views
1,162
Hello friends, I am trying to establish communication from Concept PLC to Vijeo Designer (version 5) via a TSXCUSBMBP in a MODBUS PLUS loop...
Replies
0
Views
1,957
Hi, I am facing loop variation problem in my slitter line, actually problem is when in uncoiler last 20 to 25 % coil remain either from starting...
Replies
0
Views
1,078
Hi, Is ground loop problem on multiple current analog signals depend on the hardware (i.e. PLC) or on the signal generator (i.e. pressure...
Replies
11
Views
6,501
Hi, i've got a serious looping problem over a fc input bool variables list - it should be easy but the heat makes me a heavy-thinker. The...
Replies
10
Views
5,721
Back
Top Bottom