Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations cowski on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

For next loop on Compactlogix 4

Status
Not open for further replies.

kebo2K

Electrical
Nov 28, 2007
7
Hi,

I am a programmer that has been given that task of writing code for a Compact Logix controller. I have worked with opto22 and CTC PAC systems before, but never with AB stuff, and am having difficulty with a few (hopefully basic) concepts. My project involves monitoring and controlling temperature, level, pH, etc. in a number of tanks. Since each tank will monitor that same things, I have created a user defined type that includes all the variable for a 'generic' tank. I have also created an array of generic tanks whose size is equal to the number of tanks.

Question 1.
How do I alias IO to members of my tank variables ? That is how do I alias Local:3:I.Ch0Data to Tank[2].Temperature for example ?

Question 2.
Being that I don't know any ladder logic, I would like to do as much coding as possible in Structured Text and if not there, then I would like to be in Sequential Function Charts. Is there a way in either of those to implement a For Next loop so that I can iterate through my array of user defined tanks? If so how?

Any and all feedback is welcome and thanks for reading
kevin
 
Replies continue below

Recommended for you

Question 1
Aliasing
Go to controller tags
Go to the Edit Tag tab
Name of tag = Tank[2].Temperature
Their is a column called Alias For = Local:3:I.Ch0Data
Pretty simply huh?

Question 2
Structured Text is just like basic or c to me so if your familar with those languages then it would not be too much of a stretch.

Sequential Function Chart is used if you have to follow a certain sequence. Under each sequence is a form to write your code similar to structured text.

I have used for loops with ladder and did not find it very hard to follow.

But the point I guess I am trying to make is I did a project where some of it was in the above programming methods and it was difficult to find others that could support it. Just a thought.
 
kebo2K
Be very carefull, many plant maintenance people expect their PLC's to be programmed in Ladder.
You can in fact program one Generic tank in ladder and then call that ladder for each instance of the tank. Mind you, some maintenance people would even object to that, on the grounds that it prevent effective online monitoring.
If you do use one generic routine for all the tanks then you need to to understand the relative addressing features of the PLC.
 
Thanks for the replies....

I thought it would be simple to create an alias, which I can do for any tag other than UDT's and arrays. For each of those, I can create an alias for the base tag definition, but not for the individual element of the array or UDT. For the individual elements, the 'Alias For' cell is gray and does not accept type.

From both responses, I get the feeling that I need to suck it up and learn ladder.

thanks
kevin
 
I would not take francesl comment about maint people not following for loops. My experience with most maintenance people is that they are more mechanical and never seem to be in the program. When I leave site the programs are only changed for bugs, which are infrequent. If your changing them alot then you should be onsite till the program is stable.

For loops are very useful for code thats executed the same across similar acting devices. debug falls away real quick since your not fighting its similar to the next line that is exactly the same code sequence that FrancesL described. I never had a customer say take the for loop out replace with same code across all same devices. If it works and stable who would care.

 
Question 1.
How do I alias IO to members of my tank variables ? That is how do I alias Local:3:I.Ch0Data to Tank[2].Temperature for example ?

You cannot alias an UDT. The Alias for is grayed out. AB will not allow you to do this for some reason. In order to shorten your code (which I assume is what you are trying to do), use a Jump to Subroutine (JSR) with Input parameters and a return parameter of your data structure (UDT) to reduce you code.

Question 2.
Being that I don't know any ladder logic, I would like to do as much coding as possible in Structured Text and if not there, then I would like to be in Sequential Function Charts. Is there a way in either of those to implement a For Next loop so that I can iterate through my array of user defined tanks? If so how?

You can do a For Next Loop. A lot of PLCs use a watch dog timer which times how long a scan has been executing. If that time exceeds the watchdog timer, then the PLC will fault out (in case of an infinite loop created by the For-Next). I don't know if the ControlLogix has such a timer, but be mindful of it. Personally, I never have used a for-next in a PLC because the PLC is continuously scanning and you can increment a number everytime if scans to create your own for-next loop. For-Next loops are typically used in event-driven applications such as VB or Visual C++ and not PLC applications where your code is executed continuously.

You really don't need to use ladder as long as the instructions are available in structure text. AB allows structured text to allow people like yourself to write programs. A word of advice: If you need to write an if statement with 10-15 conditions, it makes it much easier to read for everyone if you do it in ladder logic. Don't use structured text, because it would make it difficult to follow. Use the output (OTE) of the ladder code in your ST if statement.

Hope this helps.
 
Don't use the same code to control several loops, it doesn't make sense. It might satisfy your ego to write code that uses as few instructions as possible but it makes for difficult troubleshooting and the maintenance people won't thank you for it. I suggest using function chart to write the code for 1 tank, get it working correctly, then copy it for all the other tanks. That way if you make a change to only one tank the others are not effected.
I would be very surprised if you find all your tanks are exactly the same.
You have lots of memory, speed is not an issue so make it easy to understand with 1 chart per loop or perhaps 1 chart per tank with the various associated loops on different pages. Don't forget, lots of comments, code that others don't understand is not good code.
I would save the structured text for complex math, or perhaps alarm handling.
Don't put any logic or calculations in the HMI that would stop the process if it gets unplugged e.g. buttons that toggle. You should be able to re-boot the HMI with zero effect on the PLC.
You will find the AB function charts a lot different from Opto22's Sequential Function Chart, all the blocks get executed unless they are in a sub-routine.

I'll duck into my trench now and wait for incoming flack.

Regards
Roy
 
I totally disagree with the last poster, using the same code makes perfect sense in many applications.

However I agree with marshg 100%, and would like to add that you should learn ladder logic - it is incredibly simple
 
If the tanks are all functionally the same it makes absolute sense to use the same code.
But each should have it's own data.
Even if they have minor differences it is possible that the code could cater for that.
Replicating the code for each tank means that each time there is a change you will have to make it for each tank, which is not efficient.
There are some systems, such as Sattline, where you can create a 'Tank object' that contains the code, the data, and even the graphics and then create an instance for each tank.
With Siemens PLC's you could use a single function block with pointers to the data and call it for each tank.
With AB you can do something equivalent.
As I said originally you need to to understand the maintenance policy at the site, including or any programming standards. If under those constraints you are allowed to use a subroutine then you need to to understand the relative addressing features of the PLC.
 
I really don't think there is an ego to reuse the same code. The reason is not only to speed up testing and validation during startup, but to make it easier to add equipment to an existing process line. If you have several hundred pieces of equipment (i.e. valves or tanks in a process) that are similar, why re-write this existing code and have re-test each individual valve? If you need to add functionality to a valve or tank for some reason after the equipment has been validated and commissioned:
1) you will only have to make a change once and test once while using a JSR.
2) If you use the re-write code approach, you will need to write code for each piece of equipment and test each one of them as well.

The second option is easy for maintenance, but will cause a lot of headache and expense. There are ways to troubleshoot JSR w/ input/output parameters. Try putting a test bit (latch instruction) before a specific JSR and an unlatch test bit after the JSR. You can use that test bit in the JSR for the specific piece of equipment for debugging.

The one thing that I do agree with RoyD is that you should use a lot of comments, especially, when using JSR w/ input/output parameters to reduce code. It would be good to give a full explanation of how a JSR works so maintenance people can understand why its being used.
 
thanks for all of the feedback...

Modern OOP (object oriented programming) techniques allow you to write re-usable code and since debugging time for any given code set is directly proportional to the number of lines of code, it doesn't make sense to not write re-usable code. Having said that the original post came before I realized that writing code for an AB PLC is really no different than writing code in C++ or any other language. If OOP can be used, then use it.

As far as code maintenance is concerned, if your code takes a computer engineer to understand it and work on it, then it's probably too complicated to begin with. Also as mentioned previously, thorough commenting is a must. Besides all that, maintaining a code base is not very different than maintaining your car.... if you can't fix it, get someone who can :p

Finally the ego part.... knowing that I have written tight, understandable, flexible code gives me the warm fuzzies all over and is indeed a large motivation for that work I put out, but whatever code I publish there is only one bottom line and that is that it must work.
kevin
 
Finally the ego part.... knowing that I have written tight, understandable, flexible code gives me the warm fuzzies all over and is indeed a large motivation for that work I put out, but whatever code I publish there is only one bottom line and that is that it must work.

You might want to listen to Roy's earlier comment: good code is also easy to follow, well documented, and avoids cute tricks where possible. Remember that the multi-skilled technicians who form the backbone of a manufacturing maintenance support team probably haven't the time to develop all the skills needed to be a full-time PLC developer, because they have to know a bit about pretty much everything from the smallest sensors to the power distribution. A big part of your responsibility is to provide a well structured and well documented application which helps the maintenance techs fault-find and gets the line back up and earning money. The owner of the plant doesn't care whether the code is ultra-compact and makes you feel warm and fuzzy: to him both it and you are necessary evils for him to make his product.

One of our DCS software guys - a talented man with an ego the size of planet - infuriates the engineering staff by his insistance on using cute tricks like delays introduced by program scan order which aren't immediately apparent, or ladders where placement of individual contacts in a rung affect ladder execution (more scan order tricks). Well-meaning people have broken programs by upsetting these fragile logic sequences merely by moving contacts to the beginning of a rung when they were placed to the far right. Some of these issues are specific to that particular DCS, but you get the idea. I have no problem with using subroutines or macros called as needed, as long as the program is well structured and adequately commented or documented.


----------------------------------
image.php

If we learn from our mistakes I'm getting a great education!
 
Well, I thought I would open a hornets nest. I expect most of the guys pushing multiple use of the same code are computer programmers whereas I am coming from the electrical trade. I will try to answer your responses one by one. Perhaps I should first expand on my thoughts. I am not advocating having a whole bunch of identical ladder where the interlocks are the same but once it gets down to process control, each loop should be stand alone. I don't understand why we need to conserve memory, it's cheap. My old Mum used to say "Don't put all your eggs in one basket"

mikek10 (Electrical) I do agree if you had 100 identical simple tasks it might make sense to multiplex however take for example a PID loop it calculates the response to Setpoint, PV Gains etc typically about 20 registers and changes the output to a valve, then it has to store all the results in another set of registers so it can load a complete new set of variables, the overhead to do all that must be at least as memory hungry as having a complete separate dedicated PID. I agree ladder is easy, but I think it's gradually getting phased out for process control at any rate.

FrancisL (computer) Yes but as I said, it's very unlikely they will be exactly the same. If you use a copy of the code then it can be modified to cater to the difference. I agree the site may dictate "no subroutines" because they are harder for the electrician to understand.

Marshg (electrical) I didn't suggest re-writing, just copy, paste and modify. Each valve/piece of equipment will have its own unique set of conditions for operating. If they were all the same you could wire them all together. I'm not sure what you mean by "easy for maintenance but will cause a lot of headache and expense", that seems contradictory, are you advocating make it hard for maintenance? "It would be good to give a full explanation of JSR so maintenance can understand why it's being used", Why was that again?

Kebo2K (electrical) I agree re-usable but by cloning not multi-plexing.

ScottyUK - Yea, finally a kindred spirit.

I'm sure all you guys are doing great work, I think this is an interesting thread and I look forward to lots more.

Regards
Roy






 
Roy: Actually, I'm an electrical engineer by trade and learned that there are better ways of accomplishing the same task quicker (in my opinion). I agree that you shouldn't create a program for the sole purpose of reducing code to save memory. In these days, it makes no sense.

I wasn't suggesting that all the valves, tanks, etc. were exactly the same as far as operating conditions. I can create the same subroutine for a 50,000 gallon tank as I can for a 50 gallon tank. I just have to pass the size of the tank in a parameter so the subroutine knows how to make decisions (i.e. is this tank in a high level, low level, etc.). A JSR w/ parameters is no different than writing function in C or basic. You can create as many unique set of conditions for operating as you need to. It is not an easy concept to understand, but I feel is necessary to understand (please look up some examples of JSRs w/ parameters for more information). Manufacturers are increasingly putting pressure on Integrators & machine builders to reduce their design & startup costs. I've been seeing more equipment coming into our facility with code that is being written using JSRs w/ parameters (or functions as called in VC++ or VB). Our maintenance team will have to learn how to use these concepts or they will be left behind.

Just to clarify... when I stated "easy for maintenance but will cause a lot of headache and expense", I didn't finish my sentence. When you copy, paste, and modify (As I thought you were advocating at the time I wrote it) would be easy for maintenance. What it would do is make it time consuming for someone to add additional functionality to all of the tanks (i.e. a hi-hi and lo-lo alarm). Each tank would have to be tested individually. You could have different software bugs for different tanks. If you use a JSR properly, you would only have to test one tank and then enable it for the rest of the tanks.

As for the other question that you directed to me, I really think it would be good for you to look at some examples of JSR w/ parameters. It took me some time to understand it and I even had to write my own code using a JSR to fully understand what was going on.

There are 100 different ways of accomplishing the same task, all of which are correct if the code works. I'm just suggesting a different way of going about it.

Thanks for the interesting thread.

Regards.
 
Marshg (Electrical)
Thanks for the explanation. I know your way is more efficient but speed is not an issue with process control.
I have pretty much stopped using ladder in favour of function blocks which are similar to small sub-routines I guess but I prefer not to use them over.

Example:
For alarms I use AB's alarm block which I tag as per the P&ID for example - I have a water tank with level transmitter LT_345. I tag the I/O accordingly. On the chart my alarm block tag is LA_345. When I configure my RSView I see the tag LA_345 c/w all the sub tags H,act, HH.act etc without having to create them. With your method I suspect you store the alarm status between scans. To add additional functionality e.g. Low alarm I just need to enter the set-point then access the LA_345.L.act from the graphic (note, I may have the tag structure incorrect, I don't have it to hand).
I treat all the blocks in the loop in similar fashion so all the tags end up grouped together.

Would you also use a subroutine to solve motor interlocks, Start/Stop inputs, run status etc?

Do you see Ladder still around in another 20 years?

As you say there 100 different ways to skin a cat, I recently handed off an Opto22 system to a young mechanical engineer with no PLC experience. With a little guidance he soon had the system configured and working in ways I had never thought of.

Hopefully Kebo2K (Electrical) will try many different ways and create something wonderful to behold.

46 years on, and still learning.

Regards

Roy
 
For Loops - I just see it easier to troubleshoot the same code across the same equipment. I try to stay away from passing parameters in code, it just confuses people and me included. In my business MHE (material handling equipment) using less time to program cuts your hours programming, debugging, and hours onsite during startup.

If you explain to maintenance that the for loop executes the code the same way across mulitple lines, then they are less likely to suspect the code and truly look at sensor, device or motor failures which are really the problems after the system has been turned over. Why do I say this, because if the code is executed across multiple lanes or same equipment and the code is the same, then what else is there to look at?

As far as Alias, I know if you have an individual IO point then you can only alias this for a BOOL, not some variable buried in a UDT. That was misleading on my part. Same goes for analog, has to be real seperate from an UDT.
 
RoyD: Sorry for the delay...
Would you also use a subroutine to solve motor interlocks, Start/Stop inputs, run status etc?
If it would save time in validation & startup as well as be useful in saving time and cost for future projects, yes.

FYI: Maybe an easier way would be use an Add-On instruction (same as a JSR w/ parameters, but with more documentation). Also, do some research into RSLogix5000 Phase manager as far as run status, holding status, etc. Just another way of doing the same thing w/ less overhead software that you would have to validate because rockwell should have these items already validated (you would probably have to be familiar w/ ISA-88).

Do you see Ladder still around in another 20 years?
I hope so. I recently looked at vendor's code which was written entirely in structure text. I don't have a problem with structured text, however, I do have a problem when I came across a statement that looks like this: If bit1 and bit2 and bit3 or ((bit4 and bit5) or bit6) Then setpoint := 15.
Wouldn't this be much easier to write in ladder logic? All they would have to do is write that logic in ladder and take the OTE output (i.e. bit10) and write the structured text as follows: If bit10 Then setpoint := 15.
 
What are tags
There are many names for this capability; internally we call this concept a "reference tag". A "tag" in Logix5000 defines a name a memory definition for information that you want to store in the controller. At the lowest or atomic level the memory definition can be a single BIT, a number stored as a SINT (8Bit), INT (16Bit), DINT (32Bit) and REAL (32bit Float). Additionally, tag can be defined as a compound set of the atomic data types known as a structure or a table known as an array. In the case of structures Logix5000 supports the ability to create custom User-Defined Data-Types (UDT). The key to memory allocation for these tags is that the values being stored must reside in contiguous memory cells. This consolidation ensures the best overall performance when the information is accessed directly via program code or remotely via messaging. For example when a copy instruction operates or data is read via a message, the controller locates the first memory cell for the tag and then simply grabs the next set of cells until all of he data is read.

What is an Alias Tag
A second type of tag in Logix 5000 is an Alias Tag. An "alias tag" is a defined name for a piece that is already defined as part of another tag in the application. Unlike a base tag, an alias tag does not have a defined data-type because it simply assumes the data-type of the tag that it refers to. The benefit of the alias tag is that it allows you to create a new name for a piece of data. In most cases this is useful for accessing I/O data, to create a short name for piece of data that is nested several levels deep in a UDT, or to create a specific name for a piece of data that us within an array. During the download process, RSLogix 5000 converts program references for alias tags to the physical memory used by the data that the alias' point to. This provides a direct reference at run-time to ensure the best possible performance. I should also point out that the Alias tag concept is only available on the Logix5000 family of products (no competitive offering is available).

Alias Tag in a UDT
The leap that most people make is that because I can create UDT tags and alias tags, then I should be able to create an alias in a UDT. The big problem is that doing this would mean that part of the UDT would be in one place in memory then the alias tag would point to a separate location in memory. This means that if you attempted to copy or read the data from a message, the controller would have to scan the tag definition first so that it could locate any alias references within it and then at run-time gather all of the data up. This adds a great deal of time to both the lookup and the data transfer operations. This performance impact would affect every type of tag operation so that we could ensure that the correct data is being pulled. Because of the impact we decided not to implement the reference tag style capability. The good news is that we are not alone in this limitation. There is no competitive offering that can provide a reference tag.

To work around this limitation the best solution is to store all the data that is needed in the UDT directly. When I/O data is needed, you can copy the input values into the UDT at the beginning of the program and then at the end of the program copy the data values from the UDT back out to the outputs. This actually has a side benefit in that is synchronizes the data to the program scan so you do not need to worry about values changing state in the middle of the scan. If you had used a true reference tag, asynchronous I/O updates would still need to be managed.

Long term we are looking at developing the reference tag concept and in fact are doing some research in this area. However, at this time it the development has not yet been scheduled for a release


Attached is an example acd.
 
 http://files.engineering.com/getfile.aspx?folder=55a73de3-139b-43d7-93ee-db373e88f163&file=udt_alias.ACD
Status
Not open for further replies.

Part and Inventory Search

Sponsor