Compact Logix and Arrays - Question

Join Date
Jan 2013
Location
Michigan
Posts
41
I'm about to undertake a project on a L18ERM controller, which will be attached to a PV1000 HMI, and I think I might need to make extensive use of Arrays to get it to work. Since I am not yet clear on how to use an Array at all, I thought I would do some reading first... I found several posts regarding Arrays and Recipes, but I didn't find quite enough to dig right in and start. So, is there a good place to start my quest for knowledge? (yes... Google is my friend... but, most of my searches landed me here anyway)

Here's a basic description:

This is a 'single axis' motion (servo motor) that is attached to a set of rollers that moves material into a stamping press. (Feed to length application)

I was able to get a simple version of this to work, and by simple I mean that I have only a single repeating length based on a physical input. (Indexing)

Now I've been asked to take this to the 'next level', which will require multiple lengths and potential reverse movements, all based upon a 'job recipe'. I will need to be able to store as many as 100 'recipes' to be stored and called up as needed.

Each 'job' may have just a few repeating moves, while others may have complex forward and backwards moves, and also trigger outputs along the way... All this needs to be done via the HMI.

Thanks... ~Mike
 
Now I've been asked to take this to the 'next level', which will require multiple lengths and potential reverse movements, all based upon a 'job recipe'. I will need to be able to store as many as 100 'recipes' to be stored and called up as needed.

Each 'job' may have just a few repeating moves, while others may have complex forward and backwards moves, and also trigger outputs along the way... All this needs to be done via the HMI.

Thanks... ~Mike

The first thing you have to do is get the specification sorted out. Someone has to decide on the maximum length of the "recipe", and the number of outputs that can be triggered.

Based on that, you could then create separate arrays for the length parameter (REAL or DINT?) and the outputs, (SINT for up to 8 outputs, INT for up to 16, DINT for up to 32).

Now to think about storage of 100 of those "recipes", and you inevitably think about needing Arrays of those Arrays !!!

Getting a bit messy, but it can be simplified if we define the structure of a "Recipe" as a "User-Defined" data-type (UDT), which would include as members the Arrays for the Length and Outputs at each step.

Having got the "1-part" recipe structure (UDT) defined, it's now easy to create storage for 100 parts, as an array of that UDT.

Let's for arguments sake say your "most complex" part could have up to 30 operations, and you only have 4 outputs to drive, your UDT structure would look something like Pic#1. The UDT is set up to describe 1 part, with up to 30 indexable length/outputs parameters.

Your Recipe storage is then simply an Array of 100 of those Recipe UDTs. See Pic#2. You will notice that I have made the array 101 in size, I can then use Recipe[0] as my "selected" or "working" recipe, and my storage is indexed 1 to 100. At the appropriate time the HMI can ask for recipe xx, and the controller can simply copy Recipe{xx} to Recipe{0] for the part to be made.

Using a UDT for the part specification really does make the project a lot simpler. The only thing you need to be aware of is that your Recipe storage tag (the array of 100 of your Recipe Data-Types), cannot exceed 2MB of data. In the example I have shown, the UDT is 152 bytes, so an array of 101 of those is 152 x 101 = 15,352 bytes, well within capabilities.

Your control code will then index through...
Recipe[0].Length[Index] and Recipe[0].Outputs[Index]

You could make this easier to undertand if you create an Alias Tag e.g. WorkingRecipe as an alias to Recipe[0].

Your control code will then index through...
WorkingRecipe.Length[Index] and WorkingRecipe.Outputs[Index]

There's some ideas to be thinking about. If you have got your head around the concepts I've described, your control code will be easier to design, easier to debug, and clearer to understand without a huge amount of commenting.

FWIW, I have done exactly this scenario on a recipe structure (UDT) that was close to 1300 bytes, with 160 recipes.

Pic#1.jpg Pic#2.jpg
 
The first thing you have to do is get the specification sorted out. Someone has to decide on the maximum length of the "recipe", and the number of outputs that can be triggered.

I believe 8 outputs (and possibly 8 'status' inputs) will be sufficient for the project. And, since I don't know what the maximum amount of lengths *could* be, I'm thinking that I would limit the recipe entries to 10 'moves', and then provide a way to 'link' the recipes together... or even make groups of sub-recipes into a larger 'batch'.

Thanks Daba... This is certainly the direction I was heading. I can now study the possibilites and get started!

~Mike
 
I believe 8 outputs (and possibly 8 'status' inputs) will be sufficient for the project. And, since I don't know what the maximum amount of lengths *could* be, I'm thinking that I would limit the recipe entries to 10 'moves', and then provide a way to 'link' the recipes together... or even make groups of sub-recipes into a larger 'batch'.

Thanks Daba... This is certainly the direction I was heading. I can now study the possibilites and get started!

~Mike

You could do that, but I think it might get a bit clumsy... especially if you eventually decide to allow "Recipe Editing"

What are you concerned about.. memory usage ? I wouldn't worry too much about it, set a limit on the number of operations that gives manufacturing flexibility, and fits within your controller size, and "fit and forget". I think you'll have a much easier ride developing the code...

Whichever way you decide to head, you may need another member of the UDT that specifies the "length" (number of operations) of the part, or devise a special code for the next length,(which probably should be called "Position" if it can be +/-), that can be detected as "End of Process".
 
What are you concerned about.. memory usage ? I wouldn't worry too much about it, set a limit on the number of operations that gives manufacturing flexibility, and fits within your controller size, and "fit and forget". I think you'll have a much easier ride developing the code...

Memory usage hadn't even crossed my mind until you mentioned it! Mainly at this point in the design is to try to deal with the age-old differences between what the sales guys have told the customer, and what the engineering team can actually do! :rolleyes:

If I have to restict how many 'jobs' or 'recipes' or whatever... that's how it will have to be. Still way to early to tell. :p
 
100 recipes, each with 100 positions, 8 outputs and 8 inputs at each position, including a "recipe-length" and "repeatcount" occupies about 60K of memory (there was already 63K allocated for a blank project).

Note, I miss-spelt "RepeatCount" as "ReatCount" in the UDT declaration, and have now decided since creating the screenshot that it doesn't need to be in the UDT at all, which will bring the memory usage down a bit.

You could also think about using Non-Volatile memory (Flash Card in the controller) for storing the recipes (there's a whole bunch of sample code in the RSLogix5000 samples library), or you could store the recipes on your HMI or on a USB stick plugged into the HMI, and only transfer the "working" recipe.

Lots of options..

Pic#3.jpg
 
Last edited:
Hi daba,
What does the selection of the recipes look like in the HMI?
Are they scrolling through an un-alphabetized list, in the order that recipes were entered in? Or is there no list and they are required to enter in a correct recipe name that matches?
Thank you,
Bill
 
Hi daba,
What does the selection of the recipes look like in the HMI?
Are they scrolling through an un-alphabetized list, in the order that recipes were entered in? Or is there no list and they are required to enter in a correct recipe name that matches?
Thank you,
Bill


I've done similar recipe programs in which the operator had a faceplate that displayed the recipe name and had scroll buttons that could be single clicked, or would automatically scan through the list at a faster rate after holding the forward or reverse scroll button down for more than 3 seconds, or they could open a window with a list of defined recipes and click the recipe name of their choice, which would set the appropriate recipe number value into the recipe number register when they clicked it.

Of course, the "selected recipe" needs to be separate and different from the "currently running recipe", unless you only allow recipe changes with the entire system down.

The more I remember this system, the more edits I make. ;)

I also had a separate operator interface faceplate for creating new recipes that was very similar to the "select recipe to run" faceplate.
 
Last edited:

Similar Topics

Hi, I have a project where it has been asked of me to provide a means of loading a recipe by scanning a barcode. Basically the operator will scan...
Replies
35
Views
25,242
Hello Everyone, I have a issue with communication between two different PLCs. So here is the facts, The Master PLC is Guard Logix 5069 with IP...
Replies
4
Views
87
gents, I am trying to configure communication with EMERSON PK300 controller through port A1 using generic ethernet communication module . I could...
Replies
0
Views
98
I've blown the Output Transistor on the Output Card of a Compact Logix 1769-L24ER-QBFC1B It says J378. Does anyone know the replacement part...
Replies
3
Views
199
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
245
Back
Top Bottom