Control Logix indirect addressing

NevisGroup

Member
Join Date
Jan 2014
Location
Wisconsin
Posts
78
Hello All:
I have a situation where I have 110 PID loops. For the most part they are all tuned the same but there are always a couple that need special attention. I created an array of 110 PID structures and all is well. I also created one stand alone PID structure that the HMI points to. So to muck with the parameters of the loop I just copy the PID[X] structure into HMI_PID struct. This way the HMI only needs to know about the one struct. With me so far?

The problem with this approach is that I have to continuously copy PID[X] into HMI_PID to keep it live on the HMI. That's all fine and dandy till I want to change a parameter (ie a gain) on the HMI. I cant just copy HMI_PID back over PID[X].

In C I would create a pointer to the PID[X] struct and work with it directly. Is there such a thing in Logix? It would be an alias that I can change the base address of on the fly.

Any Ideas. I have run into this more times than I can count. Not just PID's, Motion Control structs are another place were this happens to me.

(BTW before you tell me to interlock the reads and write in ladder, remember that the tag updates happen async to ladder scans.)

Thanks in advance
 
Yes there is indirect addressing In controllogix. setup a move and for the address use this PIDX[pointertag] then move to hmi tag
 
There are a few different ways to do this, but an easy one is to copy PID[X] to your HMI_PID when you enter a screen that needs to display it, and then use a handshake on the entry fields to copy HMI_PID back to PID[X] when you change a value. Alternatively, do this with a "Save" button, so you can avoid people putting rubbish in there on the fly.
 
Well here is the catch...
When I copy PID[x] to HMI_PID I am moving live data. All the math that makes the PID loop work is in that struct. So when I copy HMI_PID back over PID[x] how do I know that I am coping the latest live data back along with the static that I am trying to change.

Example:
when PID[x] is copied ( in a ladder rung ) to HMI_PID the current live value of the integrator is also copied. If I change a gain and copy HMI_PID back over PID[x] how do I know that the value of the integrator in HMI_PID is current and not old from the last copy of PID[x] to HMI_PID.

OR...
If I am constantly updating HMI_PID with PID[x] when I change a gain in HMI_PID then next copy of PID[x] to HMI_PID over writes my change.

The problem is having to copy both live data and static at the same time.

This is not a problem if you address the PID structure directly because you can change PID.kp without effecting anything else. But when I change HMI_PID.kp then copy ALL of HMI_PID it steps on other stuff.

If I could make an alias HMI_PID that has a base of PID[x] then HMI_PID.kp would touch only PID[x].kp. So I am thinking I am back to an alias that I could change the base on the fly.

It does take a bit to get your head wrapped around this. I have been fighting with this for years. It seams I have a knack for getting these kind of jobs :)
 
In RSLogix 5000 the indirect addressing you are looking for is referred to as indexed addressing. There are many threads here, in addition to examples in the manuals available from AB, and the AB knowledgebase so I won't explore that further.

To handle your catch I would use indexed addressing to copy the gains to holding registers which is what the HMI or display would be pointed to (ie: PID_Gain_P[x] >>> HMI_Gain_P). I would copy the data every time you changed x.

Then you could use your display fields as data entry as well. Meaning when you changed something you would actually only be changing the displayed register, not the one the program uses. Then add a "load" action button that would flip a bit in the PLC. This would load the data from the display register to the values (ie: HMI_Gain_P >>> PID_Gain_P[x]) after that is complete you would reread the parameter from the PID gain registers back to your display register.

This has the advantage that you aren't accidentally changing program variables to unintended values multiple times. You get to set all the values then load the values into the program. If you decide you don't want to make the change you still have your original values and can reload those into the display register. You also have the opportunity to add a confirmation challenge (ie: 'Are you sure?') to your HMI.
 
Why not make the PID popup do the work? When you call the PID popup pass the PID reference so the popup points to the proper PID tag in the PLC. Then you are directly referencing the PLC tag.

What HMI software are you using?
 
OK, Let me restate.
I know what Indexed addressing is. That is NOT what I am looking for.
What I am looking for would ( in rslogix terms ) be an alias whose base address can be changed on the fly.

Perhaps the array of PID structs PID[x] was not a good example.
if I had TUNNEL_PID and DRIP_PID(not arrays!) and an alias called HMI_PID.
At one point I would like HMI_PID to be an alias for TUNNEL_PID.

So at that point anything I do to HMI_PID is really being done to TUNNEL_PID
HIM_PID is just a different name for TUNNEL_PID

Now I want to modify HMI_PID such that it is now a alias for DRIP_PID

This same thing would work for any structure. Timers, motion, whatever.

Paully's5.0:
The HMI is the problem. Cheap HMI's wont let me do indirection / or pass in an index to the popup. I would still have the same problem if the structures I was looking for were not arrays.

califflash:
If I follow you, That is what I am doing now. Basically handling each element of the structure one at a time. This is a real P.I.T.A. especially when a change in Version changes the structure.

If it can't be done, then it can't be done.
 
Even in C, if you create a pointer to a structure, accessing item WITHIN THE PROGRAM using the pointer gets compiled using appropriate math to generate access to the original storage place of the structure items.

If you were to use an HMI to probe the memory of the C program at the site of the pointer it would only see the pointer. The HMI would not see at that point the complete structure. You would have to have an HMI which was intelligent enough to understand that the pointer is just that, understand the structure that the pointer was pointing to, use it to find the location of the actual structure, then access the individual items.

So I think the continual moving of 'live' data from the selected structure to a central point observable by the HMI and also returning allowed changes to the original structure is your only viable method.
 
You can't dynamically change an alias. If you can't have the HMI point to where you want it to I don't see any better method than copy/past data to/from the "HMI_PID" reference.

Suppose you could always create 110 individual PID pop-ups, but if your HMI is that "cheap" you may not be able to do that either.
 
Are you bound to that cheap HMI? I have done what I think you want to do with Advanced HMI code like this.
EthernetIPforCLXCom1.Write("RTD_STATE[" & POINTER & "].RESET_HI_LO", 1)
Same for a read. And this will be live data.
Just an option.
 
Unfortunately...Yes I am stuck with what I have. As stated in the OP I run into this now and again. This particular job got me on this because there were 110 loops. I was just looking for a better / more generic solution to put in the tool bag.

BTW I am a programmer...C, Assembly, Python, Fortran, Basic, Ladder, Structured text, etc.. it is all just programming to me. Sometimes I get annoyed when something is trivial to do in one language, just can't be done in another.

Ultimately it is my clients check book that dictates what I have to work with. It does not really matter how much I try to explain the difference between price and cost.

Anyway... Thanks all for the input... sounds like it just can't be done.
:-(
 
How many parameters are you really needing to change?

I would create two structures...Create a UDT in CLX that has the parameters you need to change. When you change the index in the HMI of what you are viewing, copy the PID to HMI_PID all the time, but copy on change (Index <> Previous_Index) the PID changeable parameters to HMI_PID_CHG (of type UDT) and update the Index (use Previous Index = Index). That refreshes the screen. Now your code can copy HMI_PID_CHG to PID when index is live (Index = Previous_Index). Your live data on HMI will point directly to HMI_PID, your changeable data to HMI_PID_CHG.
 
Fal instruction

Take A Look At The FAL Instruction. It handles Arrays And Has A .POS Pointer. Use the Instruction in INC Mode And Force It to Write To A Position By MOVing The Value of [x] into The FAL's Controlname.POS

This Way you could Write Directly to the PID not The HMI PID and change individual parameters or use multiple FAL's to do more. I guess you would have to add selection buttons to the HMI to make the decision of which parameter would be updated.
 
Last edited:

Similar Topics

I am trying to do some indirect addressing in control logix 5000 and having no luck. In PLC 5 I used to write it like this B3/[N10:0], if N10:0...
Replies
1
Views
2,034
I am currently converting a Softlogix program to run in a Control Logix platform. The problem I am having involves "double Indirect" addressing...
Replies
8
Views
11,082
I am having trouble with getting no control of my analog output signal. I am using the SCL function block to control my analog output. The logic...
Replies
11
Views
249
hi all, i have a plc i need to get info from for a site im working on: I have a 1764 Micro Logix 1500 LSP Series C (See Attached Image) im...
Replies
2
Views
378
I currently have a weird issue involving Ethernet IP communication between a ABB CI873 (EthernetIP Module) and a 1756-L83ES. The Layout is as...
Replies
8
Views
758
Back
Top Bottom