Sub-routines - general question

burnerman

Member
Join Date
Nov 2005
Location
Huddersfield
Posts
212
Reading another thread recently, someone advised upon not making subroutine jumps conditional, i.e. call them every scan, due to the fact that you can't predict what happens to coils and timers when you stop calling a subroutine.

This is generally how I tend to program but this is just a way of dividing the program into neatly managed blocks and that the true power of a subroutine is not being used.

I'm a self taught programmer and as such don't have any formal training in structured programming. I've often wondered what happens to coils, counters, timers etc. within a subroutine if you call that subroutine and then don't call it. Do the bits that were switched on the last time that subroutine was called stay on when you stop calling it? Are timer values retained? Do different PLC manufacturers/types work differently?

I've often thought of streamlining some of my programs by using conditional jumps but always shyed away due to the uncertainties mentioned above. Usually end up copying and pasting alot of code and changing addresses.

What's the general/educated view?

BTW I've worked on most of the popular PLC's except Siemens, I guess they will be different to most others - hell, I don't even understand most of the Siemens threads I read!!
 
I have done it both ways and either will work if you are careful how you use "conditional" JSR's. If I had a system that had Local (PanelView on the machine) and Remote (PC based HMI), I would use the input of a selector switch to determine which sub to execute. This is very handy if the logic is identical, and the only differences are the addresses of control devices (i.e. PanelView pushbutton vs. HMI pushbutton). This can also work for Auto/Manual logic, or infrequent modes of operation (like clean-in-place). As far as how stuff behaves in the scenario you describe:
If a sub is called and you turn stuff on, then the sub is no longer called while those outputs are still energized - they will remain energized. This is one of the pitfalls you have to avoid. If you are going to do conditional subs, then you should have a sub that is always being scannned that will actually energize/deenergize the outputs, based on logic from the other subroutines.
 
Conditional subroutines are perfectly fine, IF they are required. A typical case, might be executing an averaging routine every tenth scan. Or only executed on a fault. Or only in setup.

If the subroutines are used to organize the program however, and not for 'special cases', then conditionally calling them is usually a bad thing.

When not active, outputs in a subroutine generally remain in their last state (including non-latching outputs). Imagine a 'seal in' start/stop circuit, called only when a line is 'Stopped'. Well, pressing the 'Start' button will indeed put the line in run, but now the 'Stopped' sub isn't running, so you can't unseal the run contact.

Sub's usually differ from MCR's, as an inactive MCR zone will generally kill all non-latched outputs. An inactive sub won't change it's outputs.

Timers are handled differently by different manufacturers, you need to consult your documentation (or experiment) to see how they are handled.
 
In GE Fanuc PLCs any Subroutine (or Block) that has coils will leave each coil in the position that it was in the last time the Block was scanned.

Conditional Blocks work very well for math routines that you do not need each scan and that have no or few coils.
 
I think that the use of conditional JSRs is just fine. The programmer has the responsibility to know that everything in the sbr will remain in its last state and adjust the program accordingly.

I usually group my outputs in order in unconditional outputs subroutine(s).

I once set up a program where there was logic to post scan several subroutines one more time for reset after the conditional permissives went false - that was messy and in hindsight I didn't like doing it that way.
 
Last edited:
I only remember using one conditional JSR where output divices were controlled. I have used conditional JSR's for very specific functions. I started a STI or interupt, to fire four valves within a very short time span. In this case, a limit switch triggered the STI. Timing was critical, and regular scan time would not allow the control we needed.

I did use a lot of conditional Sub's for math other functions. For instance, we gave our operators a lot of power with HMI's. They could set timer presets, and lots of integers, that affected the machine operation. From time to time, they would get the "numbers" so far out that the machine would not run well. I waited until a typical run was running at record pace, and copied all of the good numbers.

I then set up a subroutine that could be called to replace existing numbers with the copied set. One scan was all this sub needed, and then only when the machine was not running as it should.

I set it up so that I could run it from RsView, via a code. This always gave us a known set of conditions for troubleshooting, and more often than not solved the troubles with the machine.

I also used subs, to do all the math and recording of data for our production sheets. A few of these were only run at shift end. Again called from RsView, or a PB on the operator panel.
 
burnerman said:
BTW I've worked on most of the popular PLC's except Siemens, I guess they will be different to most others - hell, I don't even understand most of the Siemens threads I read!!

I use both depending on the application.

Just done an extruder project, on 5/05 multiple racks and some rio & dnet and i used unconditional jumps for breaking the program down to make easier reading and understanding............

And believe me Siemens is a Big jump from the norm........ But once there you kinda get used to it!
 
In my last control logix program i used a conditional sub routine..(I am self taught to)..I did not relise that the outputs stayed on when the routine wasnt called..I didnt want to put the logix from the routine in my main routine (Wanting to keep things somewhat neat) so i used an MCR for the logic..when the routine was running the MCR was on when the routine finished it shut off the outputs..

(Lord..i hope this dosnt start a MCR argument!! :) )

D
 
Here is a good example of where a condition call to a subroutine is needed from the AB HSCE2 (High speed counter) manual:


HSCEStart.JPG
 
If a sub-routine is called, unconditionally, on every scan... then, why make it a sub-routine?
Shouldn't it be part of the mainbody? What is the benefit of putting that into a sub-routine?

The primary purpose, and benefit, of using sub-routines is that, in total, you can have an awful lot of code, but only that code which is necessary for a particular scan (based on conditions) runs on that scan. The benefit being that scan-time is minimized, as much as possible, on all scans.

If you have a process where any one of a million possible situations might occur, and you have a unique sub-routine function to handle each of those possible situations, all you need to do is determine what the particular situation is, then... call only that particular sub-routine which applies to the current situation. There is no need to continuously run all of the sub-routines... it only increases scan-time!

If all sub-routines are called, all the time, unconditionally, then there is no saving in scan-time.

Now, before I gone on...
I do use Special-Function Programming for Real-Math kinda stuff... but only when it is needed.

Now, regarding sub-routines... I don't use any sub-routines... none... nada... zilch... goose-egg!

I do, however, use SKIP (to Label-X) and LABEL-X. The SKIP instruction is controlled by a set of conditions. If I have a large section of code that is used only on a now-and-then basis, I develop a conditional-combination that determines whether or not that section of code is needed on that particular scan. If conditions indicate that the code is NOT needed, then I envoke the "SKIP to Label". When envoked, the processor skips to the specified label (located at a point after the large section of code - this means that the code must be modular) and resumes processing code from that point.

Otherwise, the code in the large section is executed. This means... if I don't KNOW that the code is not needed, then the code is executed (a little bit of double-negative, reverse-logic in there...). That is, I only skip the code if I KNOW, for sure, that it is not needed at this time. Once that section of code begins running, it continues running, scan after scan, until, once again, I KNOW that the code is not needed.

Most larger processes have a lot of Stop-n-Go aspects. The larger the process, the more critical the scan-time. A well designed process (the code, that is) will have many complete, contiguous sections that are idle now and then. If they are idle at the time, they are not needed at the time. By simply skipping that section of code you reduce your over-all scan-time. This might be critical for some fast-acting/fast-clearing conditions that are not tied into some sort of Interrupt handler. As far as I know, Interrupt handling can be accomplished ONLY on those inputs at the base-station - where the processor is installed.

Essentially, my sub-routine-type functions are built into the mainbody of my code.

It takes careful planning to make this work... successfully. But then, that's what process developing is all about. Careful Planning! If you can't do this... well... maybe you're not really a process developer.

Now, in some OEM situations (I was an OEM... so I KNOW!), there is a perceived benefit in providing "canned functionality" for a particular device or function to a process.

However, you can't just simply throw a bunch of sub-routines, from some library, together to produce a process. You have to KNOW that no sub-routine is going to "STEP" on another sub-routine, or the mainbody. A "STEP" could cause disaster!

So... if an OEM wants to throw a bunch of sub-routines together... he has to be sure there is no "stepping". Also, he needs to know that the particular processor can handle the I/O and Control Relays used by the sub-routine.

If a particular sub-routine controls Output-XYZ, or Control Relay-ABC and that particular output number, or Control Relay number, doesn't exist in the current process... modifications have to be made.

What if one sub-routine controls Output-ABC on a smaller processor, and another sub-routine, controlling a different device, happens to control Output-ABC on a larger processor? Again, conflict. Modifications have to be made.

To eliminate the Output-conflict within a sub-routine, the throw-together sub-routines would have to control Control-Relays which would be used to control the actual outputs in the mainbody. But then... might there not be conflicts between those control-relays?

It could be that an OEM always uses ONE particular processor with such-n-such a number of Inputs, and such-n-such a number of Outputs, and such-n-such a number of Control Relays... in that case, he can pull it off... at least, for a while... until he decides to add more functionality... where the total of the possible functionalities exceeds the I/O and Control Relay count.

With all of that, and with over twenty-years of programming experience, I've learned that there is little value in using sub-routines to build a throw-together process.

In a field as dynamic as this, there is simply too much effort to make it work!

Sub-routines work best when they are used in the manner for which they were originally designed... that is, performing a particular function only on an as needed basis.

Otherwise... What the hell is the point?


BTW Burnerman...

If a sub-routine is not active, the counters and timers, in that sub-routine, do not increment or decrement. Outputs remain as they were.

The counter and timer must be actually be scanned to be updated.

Regarding Outputs... if the code controlling the Output is not scanned then the Output does not change state from the last time it was scanned.


Darren....

MCR is a whole different game! You simply have to KNOW the difference!
 
Last edited:
burnerman : I thank you for this post- in the manner in which you did!!!! You have posted a question about a topic that I also have a question about………and have had for sometime. Unfortunately, (recently) I have felt “ashamed” (for lack of a better way of putting it) about posting my questions, because of the potentially aggressive manner in which some of this forum’s participants reply to them. I’ve begun to think that it is sometime easier to not ask, and wait until someone else asks……. to get some feel as to what others (my peer’s in this industry) feel about our same question. It is almost as if some of this forums participants wish to, not only display/demonstrate, but enforce their prowess over those of us who (as you most gracefully put it- “I'm a self taught programmer”) have not had the benefit of years of experience or the cost prohibitive higher academic level of education in this area. I too am a self taught programmer (and operator) of PLC controlled equipment. I now am building these machines to do tasks that people used to do by hand.

I have benefited a great deal from the conversation here on this forum. Those who’s opinions and guidance I mostly I respect, know now who they are because they are usually engage in (forum) conversation with ease or without concern of verbal reprisal. THOSE WHO I DON’T RESPECT…………………………well! Let us leave it at that.

Your inquire's are always welcome here (in most cases by all) and look forward to your input of experience.
 
Terry Woods said:
Otherwise... What the hell is the point?
.

The poiunt is to organise the code for roubleshooting..I wish some of the programs i look at were organised into subroutines.. I have a conveyor program that takes up the amount of paper that a phone book uses.. If it was organised into groups it would make my life easier..Yes it is organised into groups at the moment..but if it was in subroutines then i could drill down thru the subroutines..find the machine i am looking at and double click..Bam..On the screen..Rather than going page down and trying to find rung comments..(Or in this case..network comments)

I did learn something from your post about skipping sections of code..I hadnt thought of that before...What happens to the outputs in this section while it is being skipped?? Is it the same a as a subroutine? do they stay in the last state?

Thanks

D
 
BDKuhns...

Don't you realize that this is the Internet?

You can say what you want to say (within Phil's sensibilities).

Regardless of what anyone says, there is such a thing as a stupid question... at least, as perceived by those that are more experienced.

And the reason, and it is a valid reason, is that they (we) perceive that some questioners have not even attempted to read-up on the most fundamental aspects of the basics.

For many of us, it's like going back to the First Grade and saying... can you spell "CAT"?

We are adults, and we assume that you are an adult. As such, we expect a certain amount of effort on your part to get in the game. Our expectation really isn't that high.

DO NOT BE AFRAID TO ASK A QUESTION!

DO NOT BE AFRAID OF THE ANSWER!

If the answer is not to your liking... read the comments, very carefully, and see if they aren't simply telling you to put your nose in the book and read-up, at least a bit, before asking a question. Because, the assumption is, if you do the basic reading, most of your basic questions will be answered for you.

Ask your questions... take the hits... be they as they may. Pay attention to the freebie info and the slams... especially the slams... they will tell you what you need to do to get better in this game. Basically, the slams involve you doing something... for yourself.
 

Similar Topics

Hi guys, I am creating a sub routine and was wondering how i can trigger Bit when the sub routine first runs is it just a Open Line ? or is the...
Replies
5
Views
789
Good Morning , I'm working on a project along with a manufacturer. We are both working on a project , and I'm integrating an existing portion...
Replies
8
Views
2,236
Hello: I am new to PLC's as far as writing the programs and have never written a sub routine. I know in a regular ladder you are limited to...
Replies
4
Views
2,500
Anyone help me please to add subroutines to a program that runs a baler.I want to delay the return stroke after a ram has extended.I've been doing...
Replies
1
Views
1,559
  • Poll
On another thread, the subject of subroutines came up. I do not use them myself. I spoke with everal others that do not either. Perhaps it...
Replies
26
Views
5,157
Back
Top Bottom