Program Structure

Jieve

Member
Join Date
Feb 2012
Location
USA
Posts
274
I am a mechanical engineer with a mechatronics background working closely with a co-worker learning to program Siemens S7-300/400 series PLCs. My co-worker was trained as an electrician/programmer here in Germany and worked in industry programming PLCs for something like 5 years where he programmed a Daimler Chrysler assembly line, and I think Volkswagen as well. I come from a different background, having programmed microcontrollers in C and some assembly. Due to his training he has a very specific procedure which he follows when programming and he sometimes has difficulty explaining why when I ask him why things are done a certain way. Sometimes he can explain the reasoning behind his methodology, other times “that’s just the way I learned it”. While my questions may be someone basic, I was hoping some of you with experience could fill in the why gaps and give me some insight.

1) Is it better to structure your program so that every rung of your entire program is read every program cycle? Or is it better to structure it so that certain portions are skipped (jumps) if unnecessary. For example, say you have different machine modes, manual and automatic. Should the code always run through every network, or is it ok to include a condition “if Automatic Mode – jump over Manual code”.

2) He says that only function calls should be made in OB1 (Organization Block 1, Siemens S7-300) and no code, and no conditions for calling code. Is this reasonable and why?

3) All of his variables are included in data blocks. All inputs from the machine are written to data block bits in a separate FC called at the beginning of the program, and all outputs are associated with data block bits as well, which are then assigned to the outputs in an FC called at the end of the program. In other words, all program processing on inputs/outputs is done on data block bits instead of the actual input/outputs from the process image table. He says this is done in case sensors or actuators physical locations are changed, so that you only need to change 1 bit in the assignment FC of the program and not everywhere you used I1.0 for example. Makes sense, any comments?

4) For every machine mode, he has a separate bit for each actuator. For example, if there are 3 machine modes, there are 3 output bits for the same actuator. This is so that bits don’t get overwritten by a network in manual mode when the machine is in auto mode, but auto mode is called first. The creation of the data blocks required for this takes FOREVER in my experience when you have a lot of I/Os. Is this common practice?

If it were me, as a simple example, I would program an FC that checks the machine mode, call it in OB1, then use logic conditions further down within OB1 that call the mode specific code only if the mode switch is in that mode. He frowns on this approach, but can’t really give me a good reason why, except, “that’s not how it’s done in industry”. In my opinion, my code organization is far easier to read and follow. Regardless, he feels his method is easier for maintenance to troubleshoot or modify later on. Can anyone comment on these things?

Sorry for the long post, any comments would be appreciated.
 
1) Is it better to structure your program so that every rung of your entire program is read every program cycle? Or is it better to structure it so that certain portions are skipped (jumps) if unnecessary. For example, say you have different machine modes, manual and automatic. Should the code always run through every network, or is it ok to include a condition “if Automatic Mode – jump over Manual code”.

Unless you need the reduced scan time by making your scan shorter then using jumps should be avoided. Jumps can create unpredictable conditions when used incorrrectly. If a bit is in a bypassed section of code then it is not updated in the scan. This could lead to things staying on or off when they shouldn't. From your background you know that if you turn something on then you need to turn it off. The beauty with Ladder Logic is it is turned off when the conditions are false so writing code is easier. Writing jumps can bypass this feature.

2) He says that only function calls should be made in OB1 (Organization Block 1, Siemens S7-300) and no code, and no conditions for calling code. Is this reasonable and why?

It is generally accepted that OB1 should only call subroutines so this is what people expect to see. It also makes it easier for the people following you to see what is going on. Since after a call you go right back to where you made the call it is easier to see how things are organized. Things get messy fast when you create conditional jumps.



3) All of his variables are included in data blocks. All inputs from the machine are written to data block bits in a separate FC called at the beginning of the program, and all outputs are associated with data block bits as well, which are then assigned to the outputs in an FC called at the end of the program. In other words, all program processing on inputs/outputs is done on data block bits instead of the actual input/outputs from the process image table. He says this is done in case sensors or actuators physical locations are changed, so that you only need to change 1 bit in the assignment FC of the program and not everywhere you used I1.0 for example. Makes sense, any comments?

Common practice. It allows you to make use of the spare i/o left on the machine when it was originally built without making major changes to the program. It also makes debugging easier since all of your I/O are grouped together.

4) For every machine mode, he has a separate bit for each actuator. For example, if there are 3 machine modes, there are 3 output bits for the same actuator. This is so that bits don’t get overwritten by a network in manual mode when the machine is in auto mode, but auto mode is called first. The creation of the data blocks required for this takes FOREVER in my experience when you have a lot of I/Os. Is this common practice?

Yes it is common to have bits that energize an actual output for various modes. It is also common to group these based on tasks. In PLC code you should never use an output twice in a program unexpected results will occur.

If it were me, as a simple example, I would program an FC that checks the machine mode, call it in OB1, then use logic conditions further down within OB1 that call the mode specific code only if the mode switch is in that mode. He frowns on this approach, but can’t really give me a good reason why, except, “that’s not how it’s done in industry”. In my opinion, my code organization is far easier to read and follow. Regardless, he feels his method is easier for maintenance to troubleshoot or modify later on. Can anyone comment on these things?

See above. Remember what you may think is easier to follow is based on your background this may not be true for the guys actually following you. While a PLC has the same hardware as a PC it does not work exactly the same. What is called "the scan" is really important to understand. Once you understand this you will see why his methods make so much sense.


If you can get a hold of a PLC to test with. Try writing code the way you want and see if it is truly better than what you are being shown. I will bet you will find some surprises.
 
A couple comments in additon to Clay B.'s excellent post.

The key difference between the PC and PLC world is:

In the PC world, you read code in an offline evironment, you make changes and download with the entire program stopped.

In the PLC world, you read code as it is executing, you make changes while it is executing, you download incrementally while it is executing.

This seems simple but it takes time to fully grasp the impact it has on how you do things.

You may not find it too suprising that many new PLC programmers go through the same process and have much the same questions as you do. Also, some of these "standards" have evolved over time. If you look at older PLC programs, you will see some of the techniques you suggest. If a technique seems overly complex, the complexity is obvious, the benefits not so much.

You may find it more elegant to conditionally execute a block of code, but the technician that pulls up a section of code to monitor and finds that it is not reflecting actual status because of a condition that is not shown on the screen he is looking at will curse you. You will occasionally find a good reason to use a jump, but it will probably be very limited scope.
 
Thank you guys for the informative responses.

We have a number of machines solely created for educational purposes that are controlled with S7-300’s, as well as some others with S7-400’s and 1200’s. I programmed the first module of one of our 300 systems using his method, and while it worked fine, creating the data block bits with comments and symbolic names for all inputs/outputs was incredibly tedious and the entire process seemed inefficient to me. While I understand your point about people who don’t know what they’re doing using jumps or other program flow control functions improperly having catastrophic consequences, if following a very carefully laid out structure (in my case using a very clean task/state structure developed my one of my professors from a while back) there is really little room for error, programs turn out more easy to read and debug, and structure is straight-forward. Without boring everyone with excessive details of the method, each state has an entry (single scan), action (repeated), test for exit condition (repeated) and an exit (single scan). In the exit network, you switch off the outputs that were turned on during that state. States can be denoted by integers or by bit combinations. This guaranteed switching off of the bits during exit also allows re-use of the data block bits assigned to the outputs. I have begun to reprogram the first module using this method, but only just began developing the structure so nothing is finished yet. If using an integer in a register to denote a mode, mode troubleshooting, for example, is as simple as going online and looking at the integer, to see if the mode is correct.

My plan was to call all the functions with no logic conditions, just calls in OB1. Then at the beginning of each mode function, say auto, manual, jog, whatever, check the mode switch value. If that mode isn’t selected, jump to the end of the function and move to the next one. Nothing is set or reset, so if power goes out in a specific mode no bits stay set. I understand the American perspective, where in typical factories electricians act somewhat as jacks-of-all-trades, and therefore will be the ones fixing bugs should they come up later. This may be ignorance on my part, and I don’t want to step on anyone’s toes here, but it just seems to me, that intentionally not using all of the options available to the programmer just because there may be electricians on staff who are not well versed in programming isn’t the best way to go, although it may be the reality of the situation. Interestingly, my co-worker only programs in STL with rare occasional FBD, so the technicians who are reading his programs need to have some idea about what they are doing, considering it’s not as easy to troubleshoot as ladder (in my limited experience).

My co-worker’s comment on my method above was that each network in each mode should have a check for mode number, instead of one check at the beginning with a jump. Again, this just seems to me like excessive code, but again, maybe I’m missing something here. I guess my question is: assuming the code works properly, really how frowned on is it to program something “unconventially”, if it turns out that it is easy for technicians to read and debug when the time comes, and assuming descriptive comments exist in each network?

Ahhh, one other thing that just came to mind, he said not to use memory bits, only data block bits. Any idea why this might be? Does this have something to do with the memory location of one vs. the other? The load memory is on an SD card on the S7-300, so I was thinking maybe this had something to do with it.

Thanks again for your knowledge and input.
 

Similar Topics

Hello all, Just to give you an idea of my background, I'm new to the PLC world with a background in IT and currently pursuing my MSEE. I have...
Replies
3
Views
728
OK, (some of) you guys know by now that I'm not a PLC programmer, so I'm not really familiar with how a well-structured PLC program is typically...
Replies
2
Views
1,466
Program structure - s7-1200 MODBUS RTU Master with multiple slaves & multiple registe I'm having problem to make a appropriate structure of my...
Replies
7
Views
11,227
Hello, I am creating a PLC program for a fresh water pump station which will be based on downstream and upstream pressures. There will be several...
Replies
5
Views
2,098
hi guys I have recently completed a basic S7 course and have started creating my own little programs/solutions to small problems using stl. So...
Replies
1
Views
1,219
Back
Top Bottom