Structured text FOR loop in Controllogix

CRMCC

Member
Join Date
Feb 2011
Location
Bolton
Posts
44
I am trying to learn structured text on the controllogix platform and have managed to fault the processor by creating an infinite loop.
My problem is i cannot understand what is wrong with my code.
Started with the following code:

Code:
FOR y := 1 TO 10 DO
	Lamps := Lamps + 1;

	FOR x := 1 TO 1000 DO
		x := x + 1;
	END_FOR

END_FOR

IF Lamps > 150 THEN
	Lamps := 0;
END_IF

Which function as expected. The "Lamps" tag is then copied to the outputs in a separate routine to switch on the outputs (using a Logix trainer suitcase). both of these routines are called continuously with no conditions for the "JSR".

I then changed the code as follows:

Code:
Lamps := 1;

FOR y := 0 TO 15 DO
	Lamps := Lamps *2;

	FOR x := 1 TO 1000 DO
		x := X + 1;
	END_FOR;

END_FOR;

IF Lamps > 2048 THEN
	Lamps := 0;
ELSE Lamps := Lamps;

END_IF;

which created the infinite loop. I have tried several changes to this code trying to resolve the error but I am still faulting the processor.
I just wanted to create a running lamp going through each output in turn.

can anybody point me at a good resource for Structured text, and critique my code?
 
What's the processor fault? Some have watchdog timers and large loops will trigger them and not necessarily because of an infinite loop.



You are also missing the "BY increment" in your code.



And there's a typo on X with an upper case x.
 
The processor fault is a watchdog timer and infinite loop is mentioned in the text. Typo is from when I have typed it into the code box (I am copying it from a picture I took when I was at work) don't have access to the plc at the moment. I didn't use the BY in either loop and the first one executed ok, my understanding was the default step is 1, but I can try adding the BY when I next have access to the plc.
 
Have you posted all of the code? Your FOR loop using x doesn't do anything unless you are intending that to be a time delay - in which case you need a radical re-think of your implementation.
 
Yes this is all of the code, and the x loop is a delay. Without it everything happens to quickly. My intention was to get it working in a simple way, that I can understand and then add an actual timer in to create the delay. I agree that it is not the best way, but when I looked at timer implementation in ST there were lots of options that I needed to find out how to use.
 
My suggestion would be to use a Timer.
When the timer is done, Reset timer and add 1 to Lamp Tag.
No For Loop Needed.

MyTimer(IN:=TRUE,PT:=X);
IF MyTimer.Q THEN
Lamps:=Lamps+1;
MyTimer(IN:=FALSE); //reset timer
END IF

IF Lamps>TAG THEN
Lamps:=0; //reset Lamps
End IF
 
I put your exact code in my 1769-L30ER, it will not fault the processor. The only thing in the program is that routine, called unconditionally. The max scan time is ~7ms. The default watch dog timer is 500ms. For it to fault, the scan has to exceed the watch dog timer. There has to be more to the story.
 
Possibility 1) x increments by 2 for every pass of the inner loop (for x = 1 to 1000 do), so after 499 passes, x will be 999, and after 500 passes, x will be 1001. So the loop logic never compares a value of 1000 in x against the loop termination criterion of a literal constant 1000. Is it possible that the loop implementation on OP's PLC checks for x equal to 1000, instead of greater than or equal to 1000, and so that inner loop never terminates?

Possibility 2) OP is using an emulator, which runs slower than @dmroeder's 1769-L30ER, and the 5000 passes through the inner loop per scan cycle takes long enough to cause a watchdog timeout in the emulator.

Possibility 3).?
 
Possibility 2) OP is using an emulator, which runs slower than @dmroeder's 1769-L30ER, and the 5000 passes through the inner loop per scan cycle takes long enough to cause a watchdog timeout in the emulator.

Good catch, I missed that detail.
 
One point nobody has mentioned yet is that in the first version there are ten iterations of the outer loop while there are sixteen iterations in the second version. That fact alone means that the second version of the code takes 60 percent longer to execute than the first. Quite likely the source of the watchdog fault.
For debugging, start with, FOR y := 0 TO 9 DO. That makes your second version more nearly the same as the first. Assuming that runs OK, increase the number of iterations until you find out how many it takes to fault the processor.
 
Whoops.


My "Possibility 1" (loop index does not hit 1000+1 exactly, causing loop to become infinite loop) is unlikely, because otherwise something like
Code:
FOR x = 1 TO 10 BY 3
   ...
END_FOR
would never work.
 
Sidebar:

OP is to be very highly commended for what they are doing i.e. they are learning about structured text by poking around writing random tasks in structured text that do not relate to an actual application, and seeing how it behaves.

There seem to me to be a fair number of posts where an OP does not see the code do what they expected it to do, they simply come here and ask a question, instead of investigating the PLC behavior by adding diagnostic code unrelated to the application, or trying to measure performance or timing, or other techniques,
 
P.S. @cardoscea's mention of the x/X typo finally clicked; see below. Also, I originally misread the OP and thought both of the examples were faulting with a watchdog timeout. Finally, to @dmroeder, the idea that OP is using an emulator is a guess/possibility, not something gleaned from OP' posts; I just re-read the thread, and actually they mentioned a Logix trainer suitcase, so now I think that is an actual PLC, not an emulator.

Following @cardoscea's sharp observation: in the second of OP's code example, the FOR x ... inner loop is indeed an infinite loop IFF X (uppercase tag) is a tag with a value less than 999. To wit

  • on the first pass,
    • the loop index x (lowercase tag) starts at 1
    • when the x := X + 1; statement executes, x (lowercase) is assigned a value of X (uppercase) + 1
      • e.g. if X (uppercase) is 998, then x (lowercase) is assigned a value of 999
    • At the end of the loop (END_FOR), x (lowercase) is incremented by the loop logic to 1000, and the loop continues with another pass because the loop index has not exceeded the loop limit of 1000
  • on the second and all succeeding passes,
    • the loop index x (lowercase) starts at 1000
    • when the x = X + 1; statement executes, x (lowercase) is again assigned a value of 999 (X (uppercase) + 1)
    • the logic at the end of the loop is evaluated using the same conditions as in the first pass (x (lowercase) increments from 999 to 1000, and is then compared to see if it exceeded the loop limit of 1000), and the logic again chooses to execute another pass
      • ad infinitum
QED

P.P.S. modifying a loop index is not exactly a best practice; even the x = x + 1; (all lowercase) injects a bit of obfuscation into the code.

P.P.P.S. X (uppercase) is almost certainly declared somewhere, otherwise the compiler would fail to compile the code.
 
Last edited:
P.S. @cardoscea's mention of the x/X typo finally clicked; see below...

Very plausible explanation, and the kind of thing that can trip up new (and experienced) programmers. Problem is, not sure it is possible under the logix platform. As per Logix 5000™ Controllers Structured Text

"Structured text is a textual programming language that uses statements to define what to execute. • Structured text is not case sensitive. • Use tabs and carriage returns (separate lines) to make your structured text easier to read. They have no effect on the execution of the structured text..."

I have to assume the "not case sensitive" applies to tag names, as it does with various ladder elements (e.g., CPT instruction). While there are errors in RA documentation, this would be significant in my opinion.

Would be interesting to know if changing the ST 'X' to 'x' fixes the problem.
 
Last edited:
The processor fault is a watchdog timer and infinite loop is mentioned in the text. Typo is from when I have typed it into the code box (I am copying it from a picture I took when I was at work) don't have access to the plc at the moment. I didn't use the BY in either loop and the first one executed ok, my understanding was the default step is 1, but I can try adding the BY when I next have access to the plc.


Thanks for all your comments guys. The 'X' / 'x' typo was highlighted in the first reply and i tried explain that it was a typo only in the code I had typed into the code box of the web site, in the actual PLC all the 'x' tags are lower case.

Pretty sure that I tried different values for the loops and they all still faulted only on the second code sample, but I will check this in the morning. I will get the Processor type as well.

There is more code running on the PLC but all other routines are disabled when running the structured text routine, with the exception of the routine that updates the I/O.

One thing i did notice was that when running the code the watch window shows the loop values x and y counting up as i would expect but the outputs were not updating (again this is only with the second code sample, the first works perfectly). I will also try putting the loops as the only routine and having no other code on the PLC.

I do appreciate everyone's comments, I thought somebody would immediately spot what I was doing wrong, and stop me making the same mistake again.

I will also try using a timer instead of the inner loop.

Interesting that 'dmroeder' says the watchdog timer is 500mS, as when the program is running it takes quite a while to fault (something else i will get details of in the morning), but it is definitely more than 500mS.
 

Similar Topics

Hey all, Studio v20.05 Background. We are piggy backing another system to record attributes for product travelling down the line and several...
Replies
21
Views
3,418
In structured text, can you decrement in a for loop? I need to shift an array and I can either use while loop or if decrement in for loop works...
Replies
6
Views
4,866
Hi guys, I have a basic problem...when the start relay is activated...I want my derived function block to load a set of values to an array...
Replies
8
Views
2,851
Hello Everyone: I have been able to read value via canopen interface using ADS protocol. Actually my Structured Text Programming is weak. I can...
Replies
5
Views
3,953
I have to write some rslogix 5000 code that will loop through an array, copy each element in the array one at a time to a separate tag and set a...
Replies
19
Views
31,043
Back
Top Bottom