Sub-routines - general question

O.K. Terry..time to educate the stupid!..I understand what you mean by modularity..but how can you achieve this with out the subroutines?..Lets use for example rs logix 5000 and control logix platform..(I only use this because aside from a dos based program my software knowledge is slightly lacking..)...

O.K. so lets say i have 7 different lines..each line has 5 conveyors..each line has a coding machine, casing machine and a stacking machine.. All 7 lines must eventually merge into 1 line for palletization..Of course it must be grouped so you dont have different products on the pallet..How would i break this program into "Modules" that would be easy to find?? Say i want to change a setting on line 4 stacker? If each machine was in a subroutine the i could literally go to routine "Line 4 stacker"..
 
Terry,

What processors are you working with? From my perspective CLX (and most other similar class of processors I am aware of) allow multiple tasks, programs and routines structured in pretty much an unlimited manner to suit the application.

In my world I simply could not imagine building a significant system without using multiple programs and routines. It may be academic, but I only call a piece of code, eg _sbrValve, a subroutine when it is called multiple times and I pass parameters to and from it. eg I will have a common subroutine for all my valves, and pass the UDT tag structure in and out as Input and Output Parameters each time I call it. This to my mind is a true "subroutine".

If I want modularity then I just break up the program into functional chucks and call them on whatever basis I need to and call it a "routine". A single "program" in the CLX world is then simply scheduled within a task, along with any other programs in the Task configuration properties.

I guess what I am saying is that from my experience with CLX, and the type of application I do, there is every reason and facility to make an application as modular as I wish.
 
Thanks for all your input guys, good feedback. This is my pick on the subject:

Using unconditionally called subroutines is a good way of organising your program into easily found, easily managed chunks - I have found this to be the case, particularly with AB and GE - I usually try to limit a sub to about a dozen rungs. Unfortunately (unless I've missed a trick) Mitsi A or Q don't have subroutines.

I'm lucky to have never been in the situation where I've been worried about scan time or running out of memory locations. (Presumably things like serious number crunching and shifting huge chunks of data about can be real killers in this respect) so unless it's a problem I don't see the value of using conditional jumps due to the potential pitfalls of uncertainty about the state of uncalled outputs, timers and counters. One exception to this which I have done before is to run a sub only on the first scan to pre-load numeric values into registers for initial start conditions.

Incidentally, I did notice in the Mitsubishi Q programming manual that if you use the Jump function (a way of skipping sections of code that are not always required - similar to using a conditional subroutine), the coils in the jumped section of code remain in their current state but timers continue to run - don't know if that's the case with other brands of PLC.

I don't know if you would put these in the same catagory as subroutines, but I like the sound of function blocks where you load all the required inputs into the block, the block does it's stuff and chucks out the required outputs (I think Siemens have them but I've never used Siemens). Once you've tried and tested a block you can use it over and over. Are there any other PLCs with this sort of feature?

 
Personally, I use nothing but conditional subroutines. My programming style depends on them. They are easy to troubleshoot, conserve memory and scan time, and generally do all the things Terry described and more.

I program in state logic. Every station has a sequence. Every sequence is made up of steps. Every step is a subroutine scanned only when it comes due.

Here are a couple of other tidbits I've found programming this way -

1. Use the same piece of code for both auto cycle and manual. In Auto, on step completion, advance to next state. In Manual, return to Idle State. Same timeouts and fault logic. If it works in manual, you can count on it in auto.

2. Reuse non-critical bits. Some guys have 200 memory bits set aside for HMI pushbuttons. In my most elaborate programs, I have 10, 20 tops. Everyone points out that non-scanned bits will not update, but scanned bits will update ONLY based on the conditions in your active state. Efficient.

3. Conserve timers. I use the same timer for every fault in a particular station sequence. Remember to reset it before moving from the current state to the next, you'll never have an issue.

4. Troubleshooting is a breeze. If it hangs, you can see instantly where, and exactly what the problem is, in seconds.

5. Trigger actions at the beginning or end of a state, as needed.

The biggest thing to remember here is, by using state logic and conditional subroutines, you are taking responsibilty for the program scan on your own shoulders. There are requirements involved with this.

1. Use Set and Reset (Latch and Unlatch). You really can't do it any other way. You must turn it on, turn it off, and make sure it's off at power-up by whatever means your controller provides.

2. Apply structure. My programs always scan 3 routines - Main, Active State, and Status. Main coordinates the sequence and handles remote IO and communication. Status scans for faults and certain conditions, like guards secure, fault active, etc.

Like Terry says, "Be the machine." In this approach to programming, it's mandatory.

So take a moment and turn the consensus on it's head - and look at why you SHOULD be using conditional subroutines ALL the time.

TM

PS - BD Kuhns - dude, I read the thread you got so cranky about. You asked a good question, and got legitimate answers. If they went over your head, you got more to learn. So why be so thin-skinned? Get over it and participate - without the snide remarks.

TM
 
This not going to persuade anyone to quit using, or undo, existing unconditional sub-routines that they might already have... however, it might persuade novices from following that path.

My primary objection is to the idea of using unconditional sub-routines.

So... let's say you have a main section of code that is perhaps 100 rungs long. Then, let's say that you have... oh, 50 sub-routines. And let's say they all just happen to be 100 rungs each. And all of the sub-routines are called, unconditionally, every scan.

50 sub-routines x 100 rungs = 5000 total sub-routine rungs
The main has 100 rungs.

5000 + 100 = a grand-total of 5100 rungs... every single scan...

In terms of the processor, what is the difference between a single-body program, consisting of 5100 rungs, and a multiple-body program, again, consisting of a total of 5100 rungs?

Generally nothing, except that, from the processor's point of view, the sub-routine version has a bit of extra over-head, what with all that jumping and returning.

Gee... do ya think that might affect the scan time... just a little? Maybe?

Do you have any sorta-high-speed Input ON/OFF situations? Situations where, if the scan-time was just a little bit better you wouldn't need to install a high-speed counter?

Except in the case where certain inputs are monitored on an interrupt-basis, the "read-inputs" portion of the scan is essentially... non-existent. While you are "sleeping", the world keeps turning on it's axis... things happen, sometimes slowly... sometimes quickly... sometimes too quickly to notice.

We "Computers" (as in "Be the Computer") need to notice everything! As quickly as possible! Un-neccessarily long scan-times cause un-necessary problems. Don't forget... PLCs are NOT REAL TIME! Not even with interrupts.

Changing tack a bit...

I have absolutely no objection to the idea of using a sub-routine to support a "Class", as in "C", or "C++". In this case, if fully utilized, the particular sub-routine can be notified as to which inputs/conditions are pertinent as well as which outputs are affected. That would be a case of a truely "general-purpose" sub-routine... very much in line with the original intent of sub-routines.

A valve-class was suggested. All of the valves, in that particular class (there might be any number of classes... Valve-Type-A, Valve-Type-B, etc), are handled in exactly the same way. In this case, the sub-routine is absolutely unprejudiced... it treats all valves, in the particular class, exactly the same. (OK, yeah... it's absolutely unprejudiced, however, only within the particular class - I guess that, over-all, that makes it inherently prejudiced)

Be that as it may... all the sub-routine needs to know is... which conditions to pay attention to, and which output(s) to affect.

That is a TRUE general-purpose sub-routine! There's no way in the world that I can argue against the value of such a tool!

Then there is the argument that using sub-routines makes it easier to get right to the area of interest while troubleshooting. This is the general solution for not having at least a minimum set of reasonable documentation.

When I started in my current situation, the first thing I did was produce a document identifying all of the Inputs and Outputs by number and name... on a functional-module basis. I had to change a lot of those names into something reasonable. I distributed that document to all of the electricians. They have been updated ever since.

I did NOT include Timer and Counter numbers.

In general, any process that has been working well for any length of time represents pretty stable code. If a problem occurs in stable code... you can bet your house that it is an input issue, or a mechanical issue... not a code issue.

And so, that document gives those electricians (and perhaps the brighter mechanics and production people) the primary tool that they need to figure out what's wrong. Of course, they need to know how to read the idiot-lights on the PLC modules... a "map" is always beneficial!

If an HMI is available, access to Timers and Counters should ALWAYS be restricted as much as possible, except through the HMI.

If a situation occurs, in an HMI-less system, where the Timers and/or Counters need to be modified, in the program, by maintenance folks... that "wanna-be-a-programmer" guy should be fired. That "so-called programmer" simply ain't doin' what needs to be done!


Darren asked...
"What happens to the outputs in this section while it is being skipped??"

You have to realize how a computer really works with memory. You also need to realize that there is a FRIGGIN' HUGE difference between a Sub-Routine and an MCR (Master Control Relay).

In a computer, once a bit is told to turn on, it STAYS ON... until TOLD to turn OFF! Otherwise, how could you possible expect to call-up a document and have all of the 0s and 1s as they should be?

The thing about a PLC is that... upon "SCANNING" a rung, if it doesn't have "cause" to turn on, or keep on, the particular output-bit, then the PLC will drive that bit OFF!

The key here is that the rung has to be SCANNED! If the rung is not scanned, then the associated output-bit is not changed... at least, not by that rung.

If a sub-routine is not running, then that sub-routine is not scanned, and so, the rung associated with a particular bit can not cause the last written state to be changed. The bit remains as it was after the last scan across the rung controlling that bit.

In an MCR the PLC is designed to turn OFF all bits within the MCR range if the MCR is not active.

HOWEVER... what you need to know is that ALL rungs in an MCR area are ALWAYS scanned! If the MCR is OFF, then ALL Output-bits are turned OFF. If the MCR is ON, then all Output-bits respond to the conditions within each rung.

A PLC is nothing more, or less, than a COMPUTER! It is a PC! (or mac). It follows the same rules that a PC follows!

I'm goin' for a serious MGD-break now... later.
 
I use sub-routines almost exclusively in my programs, with many of them being called unconditionally. The additionally overhead is negliglible (maybe 100 microseconds per scan?) compared to the decreased time in development and commissioning, plus the ease of troubleshooting later if necessary.

Of course, I have always used Siemens, and they really lend themselves to an organized structure, and no one would ever put their code in one block.
 
Terry Woods said:
If an HMI is available, access to Timers and Counters should ALWAYS be restricted as much as possible, except through the HMI.

If a situation occurs, in an HMI-less system, where the Timers and/or Counters need to be modified, in the program, by maintenance folks... that "wanna-be-a-programmer" guy should be fired. That "so-called programmer" simply ain't doin' what needs to be done!

I agree with the first part of this. I've had to fight this way to long. Once control is granted, it is hard to take it back.

The second part is hooey. A babbit bearing starting to ware throws the encoder off, causing missfired valves. Something needs to be done, and done quickley, at thousands per minute of downtime. Real world bubba. No Programmer can predict, or prevent this situation, nor should he/she have to. Change the window a few degrees, and the machine is running again. Bearing changed when downtime is scheduled, parts and tools in hand.

Yeah right its easy to say that maintenance was not doing their part, but downtime is downtime. The blame game can be played later.

Documentation is wonderful. Just remember that the code is seldom input on=output on. Being able to read the idiot lights is only the beginning of the process. The most effective troubleshooting is done by those who have access to the brains of the machine. Particularly in high speed complex applications, the blackbox is just too expensive. If you ever had to send forty people home while you waited for the programming god to grace you with his golden key to the gate, you would understand.

Then there is product changes, process changes, new components, and progress in general. A simple belt change can require changes in your sacred land.

The very reason most people start to learn programming is because of these situations. The first program change I made was to use the plc to flash lights, and eliminate the turnsignal flashers that were blowing power supplies. That was not considdered worthy of a programmers time. I saved thousands of dollars the first year alone.
 
burnerman said:
Unfortunately (unless I've missed a trick) Mitsi A or Q don't have subroutines.


Incidentally, I did notice in the Mitsubishi Q programming manual that if you use the Jump function (a way of skipping sections of code that are not always required - similar to using a conditional subroutine), the coils in the jumped section of code remain in their current state but timers continue to run - don't know if that's the case with other brands of PLC.

I don't know if you would put these in the same catagory as subroutines, but I like the sound of function blocks where you load all the required inputs into the block, the block does it's stuff and chucks out the required outputs (I think Siemens have them but I've never used Siemens). Once you've tried and tested a block you can use it over and over. Are there any other PLCs with this sort of feature?



Hi Burnerman

The mitsu does have the possebility to do SUB.
If using the The A and Q series you can uste the "UC" unconditional jump the SCJ or the JMP and using som code you make them conditional.
But there is also the posebility of using "real" sub, where your code is in a diffrent "body" not main.. These is accesable fram Q02(H)..

And as you say the Siemens have FB (Function blocks) this is also somthing you can do with other brands for example Mitsu when using the IEC programing laungage... Then you almost have the same funtionality as the Siemens.
You can structure your program by using FC's (Functions) or FB's

Dariusch
 
TimothyMoulder said:
. . Use Set and Reset (Latch and Unlatch). You really can't do it any other way. You must turn it on, turn it off, and make sure it's off at power-up by whatever means your controller provides.

2. Apply structure. My programs always scan 3 routines - Main, Active State, and Status. Main coordinates the sequence and handles remote IO and communication. Status scans for faults and certain conditions, like guards secure, fault active, etc.

Like Terry says, "Be the machine." In this approach to programming, it's mandatory.

So take a moment and turn the consensus on it's head - and look at why you SHOULD be using conditional subroutines ALL the time.
TM


I am almost inclined to agree with you Timothy, strictly speaking you are right - we should be turning things off as well as on, i.e. don't assume that off is the default state. Just as you wouldn't assume that a numeric value would default to zero if you left it to it's own devices - you always ensure that you are writing the correct value to a register.

I would also guess that it would be much easier to program this way from a flowchart and make it easier to troubleshoot in a logical manner.

The only problem I have with this method is that it goes against the traditional way of thinking for people who have grown up with relay logic and who, at the moment, most of my colleagues and customers are. This may change as a new generation of (hopefully)better educated and trained engineers comes along - us 'oldies' will have to adapt.
 
If a sub-routine is not running, then that sub-routine is not scanned, and so, the rung associated with a particular bit can not cause the last written state to be changed. The bit remains as it was after the last scan across the rung controlling that bit.


This discussion jogged one of my memory buttons....

I thought I remembered Ron Beaufort mentioning EXCEPTIONS to this rule a while back, and after a little digging I found the thread in question. Basically, it talks about what happens to an A-B processor when you initially power it up, or you cycle it from program mode to run mode.... An unscanned subroutine CAN still have an affect on the program bits, so you need to take that into account in your programming.

Part 1
Part 2
 
Terry Woods said:
Darren asked...
"What happens to the outputs in this section while it is being skipped??"

You have to realize how a computer really works with memory. You also need to realize that there is a FRIGGIN' HUGE difference between a Sub-Routine and an MCR (Master Control Relay).

Terry i understand the frigging huge difference between MCR and a subroutine..Didnt i say i used them both?

If a situation occurs, in an HMI-less system, where the Timers and/or Counters need to be modified, in the program, by maintenance folks... that "wanna-be-a-programmer" guy should be fired. That "so-called programmer" simply ain't doin' what needs to be done!


Now this part confuses me..who is the wanna be programmer..the guy who wrote the program or the guy who is changing it?

 

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
800
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,259
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,512
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,564
  • 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,176
Back
Top Bottom