Loops

[13/03/2023]

1. Introduction

If You look at standard programming languages, let's take C for example, You need to start Your program with main() function. When the program starts, main() is executed and program stops. PLC way of working is different. Of course You need to start Your controller (put it in RUN mode) but it doesn't stop after program is executed. PLC executes its program over and over again. Using C analogy, PLC program would be an infinite loop within main() function.

If You would like to use a micro controller (without operating system) instead of PLC and You would like to the execute You program constantly, You have to use an infinite loop.

Once put to RUN, PLCs start their own infinite loop and all the logic that an engineer creates is being executed within that loop. You need to keep that in mind because it changes a lot.

2. Loops in general

At the beginning it may be confusing when it is required to execute some part of the program in a loop because Your PLC is already looping through the program. So what is the difference?

The difference is basically the moment when You get a result of whatever Your are doing. As PLC is constantly executing its program, it would normally need a proper calculation result every cycle. If You need to sum 100 variables, You would need 99 ADD instructions (which in not time efficient to write that code). You could use a computation instruction like CPT provided in RSLogix 5000 (but it is also not time efficient to write whole expression). Some controllers provide array element sum instruction, like SUM_ARINT in Unity Pro of SE. You could use it, You just need to specify Your set of data as an array.

It may be necessary to do something more complicated than a simple sum. In any case, understanding loops should help.

3. FOR loop

Lets's assume that we need to sum several values. It happens from time to time when it is necessary to display a cumulative diagnostics for alarm quantity or communication failures, etc.

We could create tags, add their values together and store the result in another tag, for example.

Figure 1 - Variable declaration (Rockwell Automation RSLogix 5000)

Figure 2 - Sum with ADD instructions (Rockwell Automation RSLogix 5000 Ladder Diagram)

It will work fine and for small amount of variables it is OK.

Figure 3 - Sum with CPT instructions (Rockwell Automation RSLogix 5000 Ladder Diagram)

Better, one instruction instead of three but still, it is fine for small amount of variables.

Figure 4 - SUM_ARDINT (Schneider Electric Unity Pro)

For Rockwell Automation RSLogix 5000 Ladder Diagram there is no SUM instruction that I know of but there is a FOR instruction. Usage of SUM instruction for Schneider Electric Unity Pro Function Block Diagram example on Figure 4.

Figure 5 - FOR loop (Rockwell Automation RSLogix 5000)

Generally, if I need to use any kind of loop, my first choice would be switching to Structured Text (ST). It is really straight forward in ST.

FOR <first> TO <last> BY <step> DO

<statement>;

END_FOR;

To sum values in our case, we need to configure variables as an array first. Aliasing could be used for that purpose.

Figure 6 - Updated variable declaration (Rockwell Automation RSLogix 5000)

COM1_SENT := 0;

FOR i:=0 TO 3 DO

COM1_SENT := COM1_SENT + COM1_DEV[i];

END_FOR;

As the program executes over and over again, we need to set COM1_SENT to 0 before entering FOR loop. If we don't do it, COM1_SENT would keep incrementing. Keep in mind that normally, it is necessary to create "i" variable which was skipped in this example.

Another thing worth mentioning is that the <last> value can also be a variable. BY <step> is optional - if not used, loop will increment by 1.

From my experience, I can tell that PLC manufacturers try to follow IEC 61131 programming standard but I feel like it is not to most important to them and sometimes they don't take too much care about interpreting Your line of code. You may encounter a problem that would never appear if You choose to use some standard programming languages like C. Here is an example of the code written for SE M340 PLC that made my PLC go "HALT" without any kind of warning or error message (variable declarations skipped):

FOR i:=1 TO max-1 DO

...

END_FOR;

From the point of view of the person who started with any programming language run on PC, there is nothing wrong with that loop. In case of SE M340, the problem is "max-1" which should be put in brackets to execute the code correctly.

4. WHILE loop

Let's assume that we are working with DeviceNet and we obtained 64 element array from DeviceNet Gateway that holds an information about configured devices. We know for sure that this array is being filled according the the physical configuration and contains only configured node numbers. Let's say we have four, non zero address, nodes. Let's say that our array looks like on Figure 7 and as this information is obtained from the gateway, we know exactly the number of nodes we have in the system. We could hard code a variable containing the total number of nodes configured but node quantity can change from time to time and we don't want to remember to update our variable. We want the variable to be updated automatically by PLC.

Figure 7 - Variable declaration (Schneider Electric Unity Pro)

We could use FOR loop and iterate through all 64 elements incrementing dedicated variable every time the value of indexed element is not zero... or we could use WHILE loop.

I have never seen a PLC that allows WHILE loop anywhere else but in ST. The syntax for WHILE loop is:

WHILE <expression> DO

<statement>;

END_WHILE;

The code to find total amount of configured nodes may look like this:

total := 0;

WHILE DnGw_NodeList[total] <> 0 AND total < 64 DO

total := total + 1;

END_WHILE;

It this example, we are checking a result of comparison of indexed element in DnGw_NodeList array with 0. If the element is of non zero value, program goes to the next element. Additionally, we need to take care not to exceed the size of given array so there is another condition: total < 64. If we didn't put it, the program would crash after reaching the last element of the array.

As You can see, unlike FOR loop (for which we know exactly the numbers of iterations), WHILE iteration amount and execution time can be undetermined.

5. DO...WHILE loop

In standard programming languages like C, there is also a third type of loop that we could use but I have never seen a PLC that would give me a possibility to use it.

6. Summary

Some of my fellow automation engineers get scared when I tell them I use loops in my code. Well... I understand their concerns. The code with loops is more difficult to debug, it should be handled care and well thought through. FOR loop can exceed the size of defined array. WHILE loop with wrong conditions, can take more time than PLC allows to take for one cycle or even become infinite loop. In both cases PLC will go to STOP mode.

Some of my fellow automation engineers don't like using ST claiming it is not easily readable and makes troubleshooting more difficult. Well... I don't share that opinion. Generally, I don't put one programming standard over another. I try to choose them depending on needs. Some things are easier to write, read and troubleshoot in FBD. Some things are easier to write and read in ST. Loops are good examples of instructions that are easy to use in ST. For me, a person with programming background, it is a nightmare to use FOR loop in LD, it works fine, but it is unfriendly to program and use.

In modern programming languages, there is not such thing as JUMP instruction. In PLCs, You can still find them along with loops or other sequencial instructions. It is really easy to lose control over the PLC program using them. Please keep in mind that this is something that You can live without. I didn't face a single case in my career where I had no other choice but to use JUMP instruction. Although it's tempting, I believe that it is always possible to design an alternative code which doesn't required JUMP instruction. It is always possible to create a loop exit condition in a way that You don't need to use JUMP instruction.