RSL5000 PID - can it be used for multiple loops via JSR & subroutine?

wildswing

Member
Join Date
May 2005
Location
Sault Ste Marie, Ontario
Posts
281
Hi fellas,

I've just learned of an upcoming project that I'm going to be asked to do the programming on. Details are very sketchy at this point. Here's what I've been told. Project is a new resin (glue) injection system in our MDF mill. Resin is injected into the fiber blowline immediately after refining and before drying.

The physical system includes 80 identical injection nozzles, each with it's own analog valve and some other stuff. What I'm told is that this will require 80 PID loops. I'm hoping that's a typo, but it's all I've got to go on for now. My heads racing trying to think of a way to not write 80 identical pieces of cookie cutter ladder logic [note: I have no SFC and very little text based programming experience. I'm an old PLC5 ladder guy]

One idea I've had is to put the PID in a subroutine and then go to it 80 times, but wouldn't that bugger up the PID? Could I change the PID address each time through using an indirect (or clx equivalent).

Like I said, initial details are very sketchy, but now that I know I'm in for a boat load of work, I'm beating the door down for more specifics. Thought I'd get the juices flowing by posting now.

Any guidance or advice you may have would be greatly apprecaited.
 
I beg of you, do not attempt to multiplex PID logic. It's not recommended, not supported, and nearly impossible to troubleshoot. The only thing it's not, is impossible.

Run eighty nearly-identical PID routines, each as a Subroutine. As long as you don't put them all into one big long routine, they won't be nearly as difficult to maintain and troubleshoot as you fear.

Are you at GP Flakeboard ?
 
Udt

There is definitely a way to do this without writing 80 rungs of code.

First you would create a user defined tag (UDT) with the structure of all of the information needed for the PID process. Once that is created you make an array of 80 using that tag type. Once that is done you can either use JSR with parameters or you can simply create an add on instruction (AOI)to process the PID.

From a efficiency standpoint using an aoi will actually process the data faster.

Using a counter you can use one AOI that will sequence through the array of 80 tags by using a single aoi with a reference to the array index which will be incremented.
 
Ken does have a very valid point with troubleshooting the logic. Using the method I referenced you are only allowed to monitor the signals with the tag database which can be a nightmare.

80 rungs using the same AOI will allow much more flexibility for troubleshooting and monitoring.
 
I agree with Ken.

If you need 80 PID loops, then do 80 PID loops as separate rungs. Regardless of how you implement this, you need to maintain the data for 80 loops. There is no real advantage to executing the same PID instruction 80 times as opposed to executing 80 separate PID instructions.

If this was a routine with a fair amount of custom code that you wanted to be absolutely certain was the same for all 80 instances, then I'd say an Add On Instruction would be appropriate. But since the routines will probably be a single rung with a single PID instruction, it just doesn't make sense.
 
The UDT is a great idea if you have many of the same thing. Makes it way easier to set up and repeat. If you can I would use that UDT with a PIDE in function block (if you are licensed for FB in your activation). The PIDE is a great block in that it has lots of parameters you can configure. You can make it very simple or complex depending on your needs and FB programming is very clean imo.
 
I guess I am missing something...

The PID instruction requires a tag of type PID which is a predefined structure with about 50 elements. The PIDE has even more.

What are you going to put in the udt?
 
I have only one thing to add:

If you don't have the FB and ST language extensions then get them.


Other than that, whats so hard about 80 rungs of logic? You'll spend more time futzing around with alternatives than you will with 80 rungs.

(ok, that was two things)
 
Mellis

You make a udt with the members you need to map the IO to like your PV, CV, etc. These are tags you will use in the logic to connect to the PIDE. When you drop a PIDE instruction into your logic it will create a new PID block of tags (default name will be PIDE_01 most likely). If you go to the program tags you will see PIDE_01 there. Expand it and you will see all the tags associated with the instruction (internal to it). Likewise, if you want to rename it you can name it anything but you will have to make a "new one" (right click on it and select new PIDE I think it says). Then you can select program or controller scope etc.

This is seperate from the UDT you create with the PV, CV etc tags. In my opinion this would be the cleanest way to do it as you have everything in once place (the UDT). I also like the suggestion of creating an array of these but if you need individual names associated the array won't work unless you make the differentiation in the description.

I hope this helps and if you need more info feel free to PM me.
 
wildswing, im thinking typo. i could be wrong but if you have 80 valves injecting resin and you are controling their flow via analog output and lets say each valve has an analog position feedback signal,what would be the advantage of this? you could have great control of the valves but would you know how much resin flows from each? could these other things be flow meter?. do you have other systems that use this same method. just seems to me there are better ways to handle the mech. aspect of this process but without more details who knows?
 
do the each pid on its own for the sake of future people troubleshooting it and maintenance.

I worked on an mcc where the original programmer basically setup a for loop and JSRs to run through one piece of logic to control all devicenet drives and overloads. it was nightmare to follow or troubleshoot.
 
Just my two cents on creating 80 PIDs, if I had to do it in ladder I would copy the ASCII code to Excel, concantinate, drag the cursor down to copy the first line formula, copy all the rungs from Excel, add rung, and paste.

For example Where 'A183' = XV_13214, 'B183' = 3, 'C183' = 4, 'D183' = D132(not Excel cell location):
XIO XV_13214.HasLimits BST MUL XV_13214.OpenTimeDelay.PRE 1000 XV_13214_Fail_to_Open.MinDurationPRE MUL XV_13214.CloseTimeDelay.PRE 1000 XV_13214_Fail_to_Close.MinDurationPRE NXB XIC XV_13214.Status.Opening ALMD XV_13214_Fail_to_Open D132_Alarm_Interface_Bits[3].Alarm_Ack D132_Alarm_Interface_Bits[3].Alarm_Reset D132_Alarm_Interface_Bits[3].Alarm_Disable D132_Alarm_Interface_Bits[3].Alarm_Enable NXB XIC XV_13214.Status.Closing ALMD XV_13214_Fail_to_Close D132_Alarm_Interface_Bits[3].Alarm_Ack D132_Alarm_Interface_Bits[3].Alarm_Reset D132_Alarm_Interface_Bits[4].Alarm_Disable D132_Alarm_Interface_Bits[4].Alarm_Enable NXB BST XIC XV_13214_Fail_to_Open.InAlarm NXB XIC XV_13214_Fail_to_Close.InAlarm BND OTE XV_13214.Alarm NXB XIC Alarm_Ack_All OTE D132_Alarm_Interface_Bits[3].Alarm_Ack NXB XIC Alarm_Reset_All OTE D132_Alarm_Interface_Bits[3].Alarm_Reset BND
=
"XIO "&A183&".HasLimits BST MUL "&A183&".OpenTimeDelay.PRE 1000 "&A183&"_Fail_to_Open.MinDurationPRE MUL "&A183&".CloseTimeDelay.PRE 1000 "&A183&"_Fail_to_Close.MinDurationPRE NXB XIC "&A183&".Status.Opening ALMD "&A183&"_Fail_to_Open "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Ack "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Reset "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Disable "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Enable NXB XIC "&A183&".Status.Closing ALMD "&A183&"_Fail_to_Close "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Ack "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Reset "&D183&"_Alarm_Interface_Bits["&C183&"].Alarm_Disable "&D183&"_Alarm_Interface_Bits["&C183&"].Alarm_Enable NXB BST XIC "&A183&"_Fail_to_Open.InAlarm NXB XIC "&A183&"_Fail_to_Close.InAlarm BND OTE "&A183&".Alarm NXB XIC Alarm_Ack_All OTE "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Ack NXB XIC Alarm_Reset_All OTE "&D183&"_Alarm_Interface_Bits["&B183&"].Alarm_Reset BND "
 
Last edited:
Hey fellas,

Sorry for taking so long to reply. I was off Friday and swamped yesterday.

Ken, yes I am. Deja vu. We've had this conversation before. A long time ago you replied to a question I posted asking about wireless for a storage cart system. BTW, Christine is doing fine, we did a complete rebuild and overhaul on her many years ago!

Thanks for all the ideas guys. I got some more info yesterday. Turns out there may only be 40 loops, so it won't be that bad. We may also start out with the valves either on or off. They went with analog valves just in case we find we need to vary flow rates. I like the idea of creating the ladder logic for one, the text elsewhere to make the rest. I tried it out and seemed to work. I'm not an Excel VB type, but have other means.

Also, we do not have the license for FB or ST. Got a quote from our vender yesterday. It may be an option. Unfortunately I do not hold the purse strings.

For those concerned about later troubleshooting, I hear ya. I came from the maintenance side of things, so am very aware of what things should look like at 3 am. Ladder is my first choice.

The UDT is also an interesting suggestion. I just tried something in a test program. Let me know if I'm understanding your suggestions right. I created a UDT named NOZZLE that contained the PID tag, some reals (for PV, CV, SP, etc) to go to/from our hmi, some BOOLs (again for hmi; auto/manual, alarms, etc). I then created a new controller tag array called NOZZLE with type NOZZLE with 80 elements. Now I have tags arranged together by nozzle number, like Nozzle[1].SetPoint, Nozzle[1].PID (which has all its own sub elements), Nozzle[1].Auto, etc. Am I understanding this right?

Question about hmi I/O efficiency. We're running WW Intouch. This system will have an ENBT module so everything will be over ethernet. Usually I try to group all my hmi tags together. In this case however, each UDT contains maybe 1/2 dozen tags that will go to/from the hmi, so they're not all bunched together. It'll only be a couple hundred, so maybe it's not such a big deal.

Thanks again for all the input fellas. I'll be back with some more specifics about the RSL5000 PID instructions once I dig further.
 
Mark, regarding your post #13 above, that is essentially how I handle my machine sections... One UDT that contains a bunch of sub-UDT's, including a few PID data types. It works fine, and makes writing a program much easier.

The HMI's also read from these myriad of UDT tags (not grouped), and seem to have no issues with traffic. I was using 1756-ENBT's, and they worked fine. I did change them out to EN2T's just for the heck of it a year or so ago.

One thing I will advise, is use the structure as you build it, and any time you find yourself declaring another tag, consider strongly incorporating it into the structure.

I still add to mine, even though they have been 'Mostly' unchanged for years. One nice side effect is that my machine section UDT's have generic interfaces to drives, and I found that I can use the generic interface no matter what actual drive I'm using. It doesn't even matter if I'm using communications to control the drive, or discrete I/O. All of my routines stay the same, and all of my HMI displays do as well.

I don't bother declaring an array of the UDT's, though. I actually declare one, named appropriately for each machine/drive section.
 
I don't bother declaring an array of the UDT's, though. I actually declare one, named appropriately for each machine/drive section.

I second this, I have seen machines that use an array, but when it comes to fault finding etc its is a lot easier to have a name that means something than just having a number.

Valve[1].Open or AV101.Open - Which is easier?

Just my 2p worth

Mark
 

Similar Topics

I don't see anything in the reference manual, does anyone know if the Control Variable tag can be changed in the PID instruction so that I could...
Replies
6
Views
2,174
Do the gains in the RSL5000 PID instruction work on values in percent or in engineering units? Trying to help a colleague in the field tune a...
Replies
1
Views
1,533
Just curious, trying to make set up of 20 PID tags identical. What if on first scan I COPY MyPIDtag01 to MyPIDtag02 Length 1 COPY MyPIDtag01 to...
Replies
4
Views
2,918
I am using version V17.01.00 (CPR 9 SR 1) I have a fairly large machine with multiple PIO nodes on an ethernet network. I am getting a flashing...
Replies
0
Views
1,381
Hello, My coworker and I are commissioning a new panel. We have a 1732-AENTR series C remote IO thats Rev 6.1. The project file from a previous...
Replies
3
Views
1,611
Back
Top Bottom