Jump to content


Photo
- - - - -

Subroutine


  • Please log in to reply
8 replies to this topic

#1 HiGhVoLtAgEgUrU

HiGhVoLtAgEgUrU

    Sparky

  • MrPLC Member
  • PipPipPip
  • 64 posts
  • Gender:Male
  • Location:Central California
  • Country:United States
    United States

Posted 31 March 2009 - 08:31 AM

How do I create subroutine. Can someone explain it to me then how do I call them in the program. Also how's subroutine useful?

have a wonderful day

#2 Ken Moore

Ken Moore

    Principal Specialist

  • MrPLC Admin
  • 1710 posts
  • Gender:Male
  • Location:Upstate South Carolina
  • Country:United States
    United States

Posted 31 March 2009 - 09:19 AM

What brand and model of PLC are we talking about?

Depending on platform, subroutines can be used for repetitive task by passing parameters to the sub, let it run.

In AB PLC's, non-conditional (always scanned) subroutines are often used organize ladders into logical groups.
You might have sub for PID's, a sub for motors, a sub for valves, etc....

If one PLC is controlling multiple units, you may have a dedicated sub for each unit.

As usual, it all depends on the application.





#3 BobLfoot

BobLfoot

    The Wizard

  • MrPLC Admin
  • 3159 posts
  • Gender:Male
  • Location:Southern Indiana
  • Country:United States
    United States

Posted 31 March 2009 - 11:02 AM

How do I create subroutine. Can someone explain it to me then how do I call them in the program. Also how's subroutine useful?

have a wonderful day


Ken is spot on when he says subroutines are platform specific.

To answer the other part of your question. Subroutines are used for common repetetive code and for program division into logical parts.
BobLfoot

"Poor Planning on your part does not a crisis on my part make"

#4 HiGhVoLtAgEgUrU

HiGhVoLtAgEgUrU

    Sparky

  • MrPLC Member
  • PipPipPip
  • 64 posts
  • Gender:Male
  • Location:Central California
  • Country:United States
    United States

Posted 31 March 2009 - 11:32 AM


How do I create subroutine. Can someone explain it to me then how do I call them in the program. Also how's subroutine useful?

have a wonderful day


Ken is spot on when he says subroutines are platform specific.

To answer the other part of your question. Subroutines are used for common repetetive code and for program division into logical parts.


ML1100 using rslogix 500 software. My question is let's say I write a logic for 3motor to come on at certin time. Also 2 hydurlic valve will close at same time. So I understand that I can make two different subroutine one for motors and one hyd. valves. My question is how do I create or Put my logic under one of the two subroutine.

#5 Mickey

Mickey

    Propeller Head

  • MrPLC Member
  • PipPipPipPipPipPip
  • 1512 posts
  • Country:United States
    United States

Posted 31 March 2009 - 11:42 AM



How do I create subroutine. Can someone explain it to me then how do I call them in the program. Also how's subroutine useful?

have a wonderful day


Ken is spot on when he says subroutines are platform specific.

To answer the other part of your question. Subroutines are used for common repetetive code and for program division into logical parts.


ML1100 using rslogix 500 software. My question is let's say I write a logic for 3motor to come on at certin time. Also 2 hydurlic valve will close at same time. So I understand that I can make two different subroutine one for motors and one hyd. valves. My question is how do I create or Put my logic under one of the two subroutine.


Right click on program file within RSLogix500, then click on new and add the new LAD files ( subroutines)

Then see picture below for running the subroutines. Note, the subroutines in the pictures below are run every scan.

Attached Thumbnails

  • SubroutinesControl.jpg


#6 Ken Moore

Ken Moore

    Principal Specialist

  • MrPLC Admin
  • 1710 posts
  • Gender:Male
  • Location:Upstate South Carolina
  • Country:United States
    United States

Posted 31 March 2009 - 12:44 PM

Conditional subroutines can be difficult for first timers, logic in a conditional subroutine, will retain it's last state, if an output is energized, it will remain energized until the sub is scanned again and turned off. Lots of gotchas.

I uploaded a simple washing machine program a few years ago;
http://forums.mrplc....ds&showfile=359

Take a look at it, it uses condiitonal and non-conditional subs.





#7 paulengr

paulengr

    Propeller Head

  • MrPLC Member
  • PipPipPipPipPipPip
  • 1416 posts
  • Gender:Male
  • Location:North Carolina
  • Country:United States
    United States

Posted 31 March 2009 - 08:50 PM

How do I create subroutine. Can someone explain it to me then how do I call them in the program. Also how's subroutine useful?

have a wonderful day


I will explain both in due course by explaining how I have set up 99% of my programs, and then why it is useful.

This is highly dependent on the processor. However, using your example of ML1100...

Easiest way is to click "File" on the main menu bar, then "Program Files". Use the buttons to create/modify your ladders from here. Each ladder is a subroutine. One of them, the "main" subroutine (usually #2) is called by the PLC. This creates your subroutines (aka ladders or "program files" in Logix 5000 parlance).

Now, you need to call your subroutines. You CAN do this with the point-and-click interface in Logix 500 but in reality, it is actually difficult to use in this particular instance. Instead, do this. Start edit mode on a new rung. Press the enter (return) key. Now type in "JSR x" and press enter again, where x is the program number that you want to call. When the program scan hits the JSR instruction and the rung is true, then scanning will jump to the ladder referenced by the JSR. When it "falls off" the end (hits the END rung at the bottom), it will then return back to the calling ladder and continue scanning where it left off.

Now as to why this is useful...I'll simply explain how I use it. There are other ways to use subroutines but this is one way to do it. The goal is to implement modularity, and separation of concerns. These are both extremely powerful concepts that professional programmers in the PC world use, and they are equally useful for the same reasons when it comes to PLC's. I want to organize the program so that each component of the system is cleanly and clearly separated from the others. This modularity concept has been around the programming world since the 1970's. I also want to organize it so that changes to one component do not affect the others, and so that when I'm doing troubleshooting or debugging, I can focus only on the part of the system where the problem seems to lie and ignore all the others. The separation of concerns concept is much younger than simple modularity but has been shown to be almost more important than modularity by itself.

See: http://en.wikipedia....ion_of_concerns

This requires a bit of extra code and some effort on your part when you write code. It does make the scan time slightly longer but the advantages are immense, and well worth the extra code, scan time, and effort. In fact your effort (programming time) will be amortized away completely later on when you start up and maintain the system.

I want to organize the program in two distinct ways. First off, I want to keep each part of the system separate. I want each conveyor, each "station" (if it's an assembly-line type system), each functional process step, etc., as separate parts of the system. Usually if you think of a machine in terms of functional parts, such as "brakes", "steering", and "engine" on a car, this makes the most sense to most people. Organizing it as "valves", "motors", "pressure sensors", etc., might make sense from a wiring diagram but once you've commissioned the machine, this isn't the most logical arrangement. For a car, that would be like organizing it by "structure", "rotating parts", "fluid systems", etc. It might make sense in some contexts but it's generally just not how people actually think.

The second dimension of this organization is from high level to "low level". An example of a high level function would be running a batch system to follow a recipe. "Medium level" if you have such a thing would be for instance switching between automatic and manual control over the mixer. Usually depending on what the system looks like, auto/manual controls fall into either high or low level code. The starting/stopping function and interlocks on the mixer itself are very low level.

Practically, this is how the program layout looks (almost all my programs are written the same way).

First, I have one ladder called "MAIN" or "MASTER". This ladder is always ladder #2 (unless I'm changing someone else's work and it turns out to be easier to create a new MAIN program). This ladder contains only very basic and/or global functions. The rest of the entire program is nothing but JSR's onto the subroutines.

The next group of subroutines have names like "ANALOG" or "MSGs" or "BLOCK_IO" (if it's a PLC-5). These are low level functions that handle simple IO operations like scaling analog I/O, or doing a lot of communication.

If there are lots of things that I have to do to interact with an HMI that have nothing to do with the actual process, I'll have an "HMI" subroutine. In practice the HMI routine is pretty "high level" but does a bunch of utility functions. For instance if I need some code to tell the HMI to switch screens, set the date/time, or other types of things that have to do specifically with PLC/HMI interaction, it goes in this program.

The rest of my ladders have names like "CONVEYOR_1", "MIXER_1", "CAR", etc. There may also be an "AUTO_MODE" or "MAS_CTRL" file containing an overall master control section of the code, if you don't put it in the "MAIN" subroutine.

I try to create as many ladders as I have functional parts of the system. I try not to go too far with the idea of functional groups (creating far too many subroutines), nor too coarse (only 2 or 3 subroutines). Usually with any given machine again, it is usually pretty obvious how to split up a machine into functional components, and there are often only 2 or 3 groups of code that don't belong to any particular functional part.

Within each subroutine, I create bits such as "running" or "stopped" or "auto" or "manual" or "done" which are used to coordinate activities BETWEEN different subroutines. I try to make an effort not to just use a limit switch or some other function DIRECTLY. For instance in a typical "assembly line" type machine, there are often several "stations". Each station should have a "ready" bit. The upstream station should not pass a part to the downstream station until the downstream station is "ready". Or if you are using a walking beam, do not advance the walking beam until each individual station triggers a "done" bit. The done bit is always an internal bit, NOT a hardware function (like a limit switch).

The top section of each of these ladders contains high level code implementing whatever it is that one distinct part of the ladder runs. I don't usually have direct output functions here unless there's really nothing special about the low-level code that makes it necessary. The middle section (if there is one) takes on roles such as handling auto/manual functions, although more often than not it makes more sense to either mix this in with the high level code or put it at the top. This might not be the best place, but I also tend to put the "state bits" (the bits which interlock different ladders) somewhere near the end of all the high level code since they should be reacting to the high level code as it changes state. The bottom half has a rung title (and rung comment) that I always label "utility". Then the low level functions that do things like start/stop motors or open/close valves fall in the utility code. This clearly separates the high and low level code. I also put additional rung titles into both the high and low level sections to split them up. If you have turned on the "Integrate Advanced Diagnostics in Project Tree" option (See main menu bar "Tools", "Options"), then each of the rung titles appears as an entry in the system tree to the left, neatly arranged in order underneath each program (ladder) file. This visually shows you the second dimension of organization that I referred to earlier.

Now here's why this structure is useful:

All of your analog I/O scaling (or unit conversions) is in one convenient spot, all laid out for convenience.

You don't have to page through all the low-level utility I/O stuff such as page after page of block transfers that are necessary in PLC-5 programs.

If production/maintenance/engineering wants to change how something works (adding/changing various functions), then I simply have to go the the appropriate section (CONVEYOR_1 for instance) and edit the high level code. There's no reason to search throughout the program for various places where things are tied together or to mess with anything else. Every function is self-contained within each subroutine. This is the advantage of separation of concerns. It drastically lessens the age old problem of being very careful when making changes that you don't have unintended consequences elsewhere in your program.

In addition if you need to move the I/O to another physical location (to support some sort of rewiring or renumbering effort), then simply edit the low-level code to move things around. Again, the debugging effort is very small. You can also be pretty sure that you've located ALL the pieces of a particular functional component by looking through a short low-level utility I/O section rather than having to laboriously go through the ENTIRE program looking for any rungs that might do something you don't expect.

The same advantages carry through when you are doing startup/commissioning. I/O checkout involves only the low-level code. High level problems (the conveyor is turning on at the wrong time) are addressed in the high level code within that single subroutine.

And the same kinds of advantages carry through during troubleshooting and other maintenance efforts. After 10-20 minutes of training on how to navigate around in Logix 500 from a high level (not just tracing I/O points), other technicians/electricians can locate the appropriate part of my program and do troubleshooting or even make changes in a matter of a couple minutes even with no prior experience with editting the program, even when the program is hundreds of lines and encompasses hundreds of I/O points.

So in summary, I use subroutines as one of a couple methods to achieve modularity and separation of concerns. The advantages of those techniques are to reduce downtime and mistakes, and increase productivity of maintenance and engineering personnel.

#8 Mickey

Mickey

    Propeller Head

  • MrPLC Member
  • PipPipPipPipPipPip
  • 1512 posts
  • Country:United States
    United States

Posted 31 March 2009 - 10:50 PM

WOW!! Paul
You have said what others have, in bit and pieces over the years. But you put it all together like no one else has.
This post should that its rightful place in the "Articles" section.
It can't be said any better.

#9 HiGhVoLtAgEgUrU

HiGhVoLtAgEgUrU

    Sparky

  • MrPLC Member
  • PipPipPip
  • 64 posts
  • Gender:Male
  • Location:Central California
  • Country:United States
    United States

Posted 01 April 2009 - 08:14 AM

Allen Bradley training who? I'm getting mine right here...... :-2 :wacko: :-) you guys are awesome.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users