Addressing controller tags RSLogix5000

TimeFluxCap

Member
Join Date
Nov 2002
Location
Australia
Posts
321
Hi all

I am writing a program for a Control Logix and have a fundamental question regarding the variable type to use for Control Logix.

  • Now I am led to believe that CLX works best with 32bit double integers as that is the way it has been designed. If you use 16bit integers it actually uses more memory and hence slows down processer. True or false?
  • If the the above is true, is it the same for booleans? Is it best to make a dint word say called "WORD1"and then alias each individual bit of that word to then be used a bool variables in the program? True or false?
TFC
 
This is the way I understand it.

The CLX platform is designed as a 32-bit platform. Staying 32 bits has an advantage. The reason that 16-bit integer math takes more time is that extra operations are required to extract and format the data. It doesn't use more memory, just more processor time.

A standard BOOL data type in CLX is a 32-bit integer limited (artificially) to a value of 1 or 0. Using individual bits in a DINT for logic operations will save memory but will chew up processor time. Again, you need to extract and format the single bit in order to use it in a logic operation. That takes processor time. The exception to this is when you create a structure (user defined data type). In this case successive BOOLs are combined into a DINT. If you put 32 BOOLs together you will use up one DINT. If you put 33 BOOLs together you use up two DINTs. If you group 15 BOOLs together followed by a DINT followed by 15 BOOLs you will end up with three DINTs in the structure, one to the first 15 BOOLs, one for the DINT and one for the second group of BOOLs.

By the way, in a somewhat unscientific, imperical test I found that FLOAT calculations execute faster than INT calculations. Go figure.

Hope this helps.
Keith
 
TFC,

I wouldn't say that ControlLogix "works best" with 32-bit structures but certainly its memory is allocated in 32-bits chunks so creating INT's and SINT's "wastes" memory in the sense that the remaining bits can't be used for anything else. Depending on what you do with the data it may be more efficient to be using native, 32-bit structures. Look at it from the opposite viewpoint; why would you not want to make 32-bit structures? (other than for PLC/SLC compatibility)

The same is true for BOOL's; each discrete BOOL is actually a 32-bit structure but you only get to use 1 bit of it.

Is this a problem? Probably not; one of the reasons the CLX has such a huge amount of memory relative to PLC/SLC is to cater for this "waste" on memory allocation.

I haven't seen any examples of people assigning individual BOOL's from within DINT's but I've certainly seen examples of people creating BOOL arrays and using individual members instead of discrete BOOL's. (I think it's partly a desire to return to the good old days of B3......).

Speaking for myself I think that such code looks p*ss-poor compared to the "self documenting" code that results from using individual tags which have meaningful names.

I'd say use DINT's where you need integer values, REAL's where you need floating-points and you make as many discrete BOOL's as you feel like making. If you find that you're running out of memory then start using BOOL's within DINT's. (Or ask A-B to sell you some more memory, I'm sure they'll say yes :ROFLMAO: )

Did your course instructor show you how memory gets allocated when making UDT's? That's another area where you can trade-off readability for memory. (Looks like Keith's did, wish I'd pressed the submit key before I went to get a drink :oops: )
 
Last edited:
TimeFluxCap,

True or False?

It depends...

If we are talking about an individual tag, it really doesn't matter that much if you declare it as a DINT, INT, REAL, or BOOL. All of them are going to take one 32-bit word. They are all going to take even more memory for the TAGNAME. So quibbling over efficiency of memory usage in this scenario is really kind of pointless since in most cases the length of the name is the major factor rather than the data type. It's a good thing that you have a lot of memory to use in a ControlLogix.

That is not to say you should not be concerned about memory usage. Any time you have a large quantity of related tags, arrays and udts start getting attractive. You only have the overhead of one tagname for many items.

In your example WORD1 may only use one 32-bit word to store the values for 32 bools, but you have 32 aliases and 1 tagname too. However, here is an example where I do something similar. I generally make a local (not controller) tag in each program called OneShot and make it a DINT. Then as I need oneshots in my program I just address the individual bits (i.e. OneShot.0). This *DOES* save memory since I only have one tagname and one word for up to 32 uses. However, the main reason I do this is not to save memory, it's to avoid making up unique names for oneshots.

Execution time is a whole different ballgame. Casting tags as INTS and then manipulating them requires extra steps that take extra time. Almost every time you MOV, ADD, SUB, or whatever to an INT, it first gets converted to a DINT, the operation is done, and then it gets converted back to an INT. So much neater to just stay all DINTS. Sometimes you need to deal with INTS, like messaging to/from a PLC-5. But, restrict it to those situations where you have a good reason to use integers that are not DINTs.

Hope this helps,

Mike Ellis
 
A BOOL defined as an individual tag will occupy a whole 32bits of memory.

If however the same BOOL is member of the structure of a UDT tag it will only occupy 1bit of memory within that tag. The same applies to an array of BOOLs.

ie in general it is best to avoid individual BOOL tags and to create them as members of arrays or UDT tags. I normally write all my CLX programs using nothing but UDT's and Arrays. Any "stray" tags get ruthlessly tidied up.
 
TimeFluxCap said:
Keith and Phillip

I did not cover UDT's in my course, anyone care to educate me?

User-Defined Data Types.

This is one of the more useful features of Logix5000. It makes PLC programming more like PC programming because you can define data structures to pass into subroutines. When the ability to create your own pre-defined function blocks comes along (scheduled for version 15?), UDTs will be even more useful.

AK
 
When the ability to create your own pre-defined function blocks comes along (scheduled for version 15?), UDTs will be even more useful.

I've heard V16 but you never know.....

There's already quite a good work-around for making your own Function Blocks (well, I think it's quite good). Define what inputs and outputs you want your FB to have and create a UDT to encompass them, write your function as a ST routine (don't I make this bit sound easy?) starting with an SBR. Instead of a "real" function block you now use a JSR block to your routine which uses elements of a UDT as input and output parameters. It still says "JSR" on the front instead of your custom block but you can wire it other blocks just as you would if was a "real" block.

TFC,
A UDT is a way for you to create a data type that enables you to monitor and control some part of your plant in a single tag. In the same way that a counter consists of accumulative value, preset, count-up etc. etc. you can create a "motor" tag that consists of speed, running, stopped, error etc. etc. You'll find them in the project explorer under Data Types. R-click on User Defined and add one. You get a dialog box which allows you to name the members of the data type together with what type of data to use. (You can have a UDT which consists of other UDT's but let's start simple). What trips most people up the first time is that when you've finished this stage you've made a tag type, not a tag; when you go to the Edit tab of the Tag Database you can now make a tag of your custom type.

The general guidance on BOOLS within a UDT is, as the others have said, that you don't alternate them with other Atomic Types (eg, use REAL, BOOL, BOOL, DINT rather than REAL, BOOL, DINT, BOOL) as it makes the finished UDT larger than it would otherwise be. It's up to you to trade-off the extra size per Tag against possible benefits in legibility.
 
When the ability to create your own pre-defined function blocks comes along (scheduled for version 15?), UDTs will be even more useful.

At the moment the major limitation on UDT structures is that they cannot be online edited. A moments thought on why, will reveal that this is a totally non-trivial feature for Rockwell to implement, but I am aware that it is planned for in Rev 15 or 16. And I agree with NOP the ability to pass UDT tags in/out of JSR subroutines is pretty much the same as a "function block".

But going back to TFC's question: UDT's are the single most powerful feature of the CLX from a programmers perspective and you owe it to yourself to get the hang of them.

Start with creating a UDT for something simple like a small motor, create some tags with it, and use them directly in your logic. If you want I could knock up and post a small RSLogix project in Ver13 to illustrate the "buffered subroutine" method NOP and I have been referring to.
 
PhilipW said:
Start with creating a UDT for something simple like a small motor, create some tags with it, and use them directly in your logic. If you want I could knock up and post a small RSLogix project in Ver13 to illustrate the "buffered subroutine" method NOP and I have been referring to.

I think we're already doing what you guys are talking about. I'm not sure where the recommendation came from: tech note, or support.

The major problem with this method is interfacing with an HMI. You pass data into the subroutine, which uses an "internal" tag of the same type that you're connecting to the HMI. If the subroutine is executing while you make a setpoint change from the HMI, data can get "stuck" or "lost" because the tag you just wrote to got overwritten or ignored. It happens a LOT more than you might expect, too. We found a way around this problem, by only passing data out of the JSR that we want to be HMI read-only. All the UDTs for "function blocks" are built from Read-only and Read-write UDTs.

So, while we're excited about future versions, I've got to say that the Logix5000 software is the MOST reliable, and functional part of this project. The other software: RSViewSE, RSLinx, Historian, etc... We've got some hurdles.

AK
 
akreel...I think we've got slightly (and harmlessly) at cross-purposes because I expressed my last post rather loosely. What I meant was that TFC should create some UDT tags and get used to them by using them directly in his programs.

This is a perfectly sensible approach. I've just worked on a major new sawmill plant were the control engineers have created enormous UDT tags, built from many arrays of sub-UDT's up to 10,000 bytes long!! A complete log infeed line, log turners, slewing infeed, chippers and quad bandsaw are implemented with just 1 tag! Of course that one tag has thousands of members. For these guys scantime is critical so they don't have the luxury of passing lots of data in and out of lots of subroutines, so most of their logic is executed explicitly in just several main routines.

But what at first seems a large and daunting program, is remarkably easy to get around in because ALL the tags in the system are HIGHLY organised into UDT's that name exactly what the tag is and what functional part of the logic it belongs in.

The question of using UDT tags within function blocks is the next step along in the discussion. This "buffered subroutine" method works well if your process can stand longer scantimes, because passing lots of UDT's in/out of subroutines does take time. The problem you mention (akreel) of having HMI data getting stuck or lost made me stop and think...I've never come across it...so what am I doing differently??

One is that I usually use Periodic Tasks to schedule my logic. Typically my IO devices run every 50-100msec, and my supervisory logic which the HMI interfaces to every 200msec. Reporting and totalisers might happen at a 1 second rate. And then I have no Continuous Task and set the system Overhead to 90%. By contrast if you are calling your "function block" subroutines in the Continuous Task say every 20-50msec, then yes I would expect that your HMI data is getting overwritten quite frequently. By scanning my logic at a much more leisurely rate, my chances of the HMI data being overwritten are greatly reduced...BUT not eliminated. Also your process may not stand such slow update times. To eliminate the problem requires organising the HMI data writes differently and some logic to manage it.

For Numeric Data Entry writes I send the new value to a buffer location, then use the "Enter Notify" flag to trigger some limit checking logic, and pass the value to the working location, and when this is confirmed as a valid value, set the "Handshake" flag to let RSView know the write was successfull.

For pushbuttons I've been writing to common array of common "HMI P/B's" that are always the same location regardless of the screen I am on. RSView also passes the number of the active screen, and then I use this call the specific mapping of these common HMI P/B's to the actual tags I want to write to. The mapping passes the data as XIC, OTL, ie it always latches the working flag ON, and then later on somewhere in the subroutine AFTER the flag in question has been processed, I just unconditionally OTU it.

Once this method is set up it's pretty efficient and is more effort to write about here than to do in the ladder.
 
Unregistered said:
The problem you mention (akreel) of having HMI data getting stuck or lost made me stop and think...I've never come across it...so what am I doing differently??

Philip,

I imagine that the "buffering" that you mentioned does something similar to what we've accomplished by splitting the UDTs. Buffering, as I understand it and have seen it implemented, would be a fine way to handle the asynchronous program scan in CLX and the issues we've seen with using a JSR as a function block. I just wanted to point out why user defined function blocks are still desirable.

So, TFC, if you're still reading: there is more than one way to skin this cat.

AK
 

Similar Topics

Hello friends, I’ve recently started learning about PLCs and HMIs after I acquired a Wago 750-871 with one digital input card and two digital...
Replies
20
Views
5,506
Having finished a project with DirectLogic, I now find myself thrown into the world of RSLogix 500. The tutorials are clear about addressing...
Replies
4
Views
3,079
Hello all. I have a Simatic SM374 (374-sxh01-0aa0) sim module. I am using TIA portal v.18. I can't find this module in my list of hardware devices...
Replies
12
Views
659
Hello, I have a device with 68 words input. But one block on the Devicenet Scanner is only 61 words. I am trying to map this device to 2...
Replies
3
Views
464
We had an AC 800M stand alone controller fail. We have a spare, and we are trying to set it up on the bench. We can connect with the serial cable...
Replies
0
Views
257
Back
Top Bottom