Alphabetical Sort in RSLogix 5000

Ooops

A quicksort is recursive. Can the Control Logix handle making upto 20+ recursive calls? This isn't a problem on a PC. We can adjust the size of the stack. Ken must live with whatever stack size the designers deemed suitable.

An alternative:
http://linux.wku.edu/~lamonml/algor/sort/heap.html

Good sorting info below. Anyone who suggested bubble sort should look at this. Notice that there are two classes of sorting. The O(n log(n)) sorts are far superior to the O(n^2) sorts. Even if the heap sort in not the best for speed it is still far superior to a bubble sort.
http://linux.wku.edu/~lamonml/algor/sort/sort.html

Wow, source code to! One doesn't need to buy Numerical Recipes in C.
 
A great tutorial and java applet demo on the heap sort here. It looks like the winner as not needing recursion. It would have to be implemented so that each internal comparison/swap in 'sift' be on sequential scans. Then it wouldn't affect the rest of the application much.
 
While I never claimed that the Bubble-Sort is the fastest, or even fast, it is by far the simplest to implement. It is by far the simplest to understand and troubleshoot.

And since this thread is in relation to a screen update, how quickly can the screen be updated anyway? How critical is it to develop the result as fast as possible anyway? The information is being provided for a human to react to (not the quickest player in the game) not for some part of the process to respond to... at least, not directly and not immediately.

Sure, you can throw a lot of time and effort into a highly efficient, highly complicated, algorithm that produces a result that is effectively no faster than screen update time and human-reaction time. But, considering the potential number of items, really, what's the point?
 
You aren't thinking!!!

CroCop said:
At 5000 recipes, executing 1 iteration per 10 mSec, it takes 5 seconds to shift through all 5000 once
You are off by a factor of 10, at least! Do you want to wait 50 seconds after the results are required?
Worse yet. You are assuming that the PLC can do 4999 scans in 10 milliseconds the first pass. I wonder when the rest of the ladder is executed.

Terry Woods said:
While I never claimed that the Bubble-Sort is the fastest, or even fast, it is by far the simplest to implement. It is by far the simplest to understand and troubleshoot.
They are all simple to implement and understand.

Terry Woods said:
And since this thread is in relation to a screen update, how quickly can the screen be updated anyway?

I hope faster than 50 seconds.

Terry Woods said:
How critical is it to develop the result as fast as possible anyway?
As fast as possible is not the point. As fast as necessary is.

Terry Woods said:
The information is being provided for a human to react to (not the quickest player in the game) not for some part of the process to respond to... at least, not directly and not immediately.
I can react much faster than 50 seconds or 5 seconds.

Terry Woods said:
Sure, you can throw a lot of time and effort into a highly efficient, highly complicated, algorithm that produces a result that is effectively no faster than screen update time and human-reaction time. But, considering the potential number of items, really, what's the point?
What is a lot of time? An hour opposed to a half hour or 15 minutes? Compare this to 50 second to perhaps a half a second.
Actually, I think it will be closer to 5 minutes vers 5 seconds when done. 5 seconds is still a long time but at least I could look the customer in the face and tell him it is the best that can be done with the hardware available and he would know that getting a processor twice as fast would only make the sorting take half as long.
 
OK - let's back up from this a moment.

How will/did these 5000 items get into the PLC?. If already in the PLC can they be read by an external program? Maybe Excel via RSLinx for example, be sorted then put back?

Could they possibly be entered in a sorted manner in the first place? Can each individually entered item be sorted into the list as it is entered?

If the 5000 items are already in the PLC in their unsorted state can they be sorted JUST ONCE then future entries, if any, be properly inserted into the list? A binary search could find the proper point quickly (approx 12 - 13 tests).
 
For me any system that involved 5000 recipes would not be trivial. I am also not familiar with the equipment involved so not sure whether the HMI is capable of storing the recipes or the PLC has to.

With that said would it be possible on the MAIN display screen to offer a "link" to a "recipe" screen then have the alphabet listed on that screen so you choose a starting letter, example would be Podunk given by Ken so you choose P which will list all the recipes that start with P and from there your scroll thru the screen to the appropriate recipe. If the HMI has the capability of storing the recipe then you select it and the HMI transfers the necessary values into the data file(s). If the PLC has to handle the recipes you could associate the recipe, once selected, to a bit that MOVES the necessary values into the appropriate data file(s). I do not know anything about UDT's and RSView so those details would be left to the programmer.

Just seems to me it is just as easy to select a few screens as it is to type in a long name.
 
bernie_carlton said:
OK - let's back up from this a moment.

How will/did these 5000 items get into the PLC?.

This is exactly what I tought... until I saw number 5000.
If recipes are createed or entered manually one by one, it is easy to manipulate list of recipes and insert one new record at a time.
It is another story if recipes are downloaded and then have to be processed, because number of number of comparisons and swaps to be done.
If the recipes are downloaded from outside world, I would also try to look into possibility of sorting before downloading.
Bubble sort is simple but definitelly too slow - unless they don't need to scroll through sorted recipes seconds after download completes. If sorting must be done in PLC and given number of recors, I would try quicksort first.
 
Okay, I'm all in favor of pre-sorting if downloaded, but what about looping through the sort code up to ... say 100 times per scan. Then instead of 50 seconds, it's more like 0.5 seconds.

You could even calculate how many times to loop each scan to hit the 0.5 second target based on the number of recipes in existence.

Most screen update rates default to 0.5 seconds, so it would be un noticed by the operator.

100 times through the few rungs required, would be a minimal impact on a fast C-Logix processor, and with task scheduling, it's impact could be insulated from the rest of the program.

And remember, the update time will only be at the worst case when all 5000 recipes are used and a new entry is made that belongs at the end of the list.

The average sort time will be much less than half that.
 
I repeat - once the list is sorted in the CPU it doesn't need to be sorted again. This is a one shot deal. Future insertions can be properly inserted with a minimal time hit. Find the right spot by means of a binary lookup, move the higher entries up one slot and stick the new information in.
 
Why are we still talking about sorting the list?

Apply database indexing technology to the problem and forget the sort. The more I think about this, the more I'm sure it can be done in the CLX. No modern database bothers with sorting the data records. A binary tree will make short work of the problem with little CPU overhead. Even though the code is somewhat involved, the CPU will execute the binary tree routines only when a new reicpe is inserted or one is deleted, and when scanning for a matching name. Because of the tree's binary branching nature a very small number of comparrisons are needed (only 12 comparrisons to find a match among 5,000 records).

The only thing I am not sure about is whether RSView ME will support indirect addressing. If it will then this can be done, and the CPU will not need to do much of anything for the display of the list.
 
Last edited:
It appears as though I'm real late to reply to this thread, but I also had to setup an alphabetical sort for a central monitoring system in our facility. I was tasked with setting up a system that would monitor all the test cells within the facility and send out emails and text messages via email to engineers who were responsible for that cell with a logix5000 controller and a panelview 1500 for an HMI for them to edit their person information from.

Some folks earlier were talking about what sorting method to use, I ended up using a shaker sort and started at the high end of the array. (If you want to take a look at what a shaker sort is just hit up wikipedia. They may have called it a ****tail shaker sort) I picked this style sort because it's pretty easy to setup, and at any given point in time there will only be one person added or taken away from the array, so it pretty well negates all the arguments about how inefficient it is to sort things like that. Even if the array is massive, it only has to scan through the thing once and it's done. You just have to setup a little bit of logic to kick the thing out of the sort once it's made a full scan through the array without making any swaps.

Also, as some folks mentioned, I had a second array of Index values that I was actually manipulating rather than messing with the array of strings. So say you have the array of strings (Eng_Name[250]) you setup a second array of DINTS (Eng_Name_Inx[250]) then have a buffer location for the screen of strings. In my case I had a list of names they'd run through to find themselves that was 15 people long. (Eng_Name_Disp_Alph[15]). I didn't get as fancy as Ken was talking about with a deal to type a name in to find it, but I think the premise would be easy to follow once you get this first bit done. Something else to note, strings really do a number on the processor memory. Because what I was using was going to be short names I made a string of only 43 characters. Seems silly, but between cell names, engineer names, shutdown messages and display strings, memory gets used up pretty quickly. The 43 was pretty much arbitrary. I found a length of string display that made sense for the screen, found the max characters that'd fit in it and went with that.

So the root of the thing, without looking back in the program, was this. I setup a subroutine (Shaker_Sort) because I planned on using it for multiple lists. I'd tell it the array length, the lowest point to check and a highest point to check. I also setup a first scan bit to reset the program before executing and a move enable bit coming out showing it's completed and you can start to fill the displays with the alphabetized names. (The lowest value to check was called out because I'd setup the the monitoring system itself as a test cell in the 0 slot of the array, and I didn't want to be alphabetizing that out of order into the field where people could see it. The high point was added because other lists, such as engineers to contact list, might not have the full available amount of engineers in it, so scanning the whole list wasn't necessary) I would only run the subroutine when things needed alphabetized. So if the engineer sent them to a screen that would have a list that'd need alphabetized I'd command the sort to start and would hold it in until the move enable bit was set.

Inside the subroutine was relatively easy. I had a UDT for the JSR in and out parameters to make life a little easier on me, but that may not be necessary for everyone. Essentially I had a scanner that'd start at the High_Check point at the beginning of the routine and a second scanner based off the original one just minus 1. I would take those to indexes and look at there respective points in the Eng_Name_Inx[250] array and write the high point to a new index. Sort_Check_A and Sort_Check_B. From here, ASCII characters have different values if they're capital or not capital. So do the UPPER or LOWER instruction and dump the name into a buffer tag to do compares on -
Eng_Name[Sort_Check_A] -> Sort_Name_A
Eng_Name[Sort_Check_B] -> Sort_Name_B
Then I would compare letter by letter of the engineer names based on those. So...
Sort_Name_A.Data[Sort_Letter] > Sort_Name_B.Data[Sort_Letter] Swap A and B in Eng_Name_Inx.

The sort letter deal I setup in a way that some folks may not really like. I would say...
Sort_Name_A.Data[Sort_Letter] = Sort_Name_B.Data[Sort_Letter] add 1 to sort_letter and re-scan the rung
I just put a JMP right under the add to the sort_letter and put the LBL at the beginning of the same rung. This worked for me, but you'll want to test this before you can feel confident in putting it in service. Take 2 identical strings and compare them to see if the watchdog trips. No one want a faulted processor because you're trying to alphabetize something.

You'll also want to move un-used array slots to the end. So if Sort_Name_A.LEN = 0 and Sort_Name_B.LEN <> 0 then swap em.

You'll have to add in something so if the 2 names are identical, or at least start with the same letters until one of the strings runs out of characters, you'll stop once Sort_Letter is equal to the lowest length value for the a and b strings.

So once you've proven whether the words need to be swapped you can increment the scanner values from before and scan through the subroutine again. If you're scanning downwards and Sort_Check_A = the lowest point then you'l switch directions and start again, then add 1 to your low check (because you now know that the lowest check point is now setup with the lowest value). The same goes for the upward direction. Once Sort_Check_B = highest point to check, switch directions and subtract 1 from the highest point to check.

The last basic part of it was I setup a verification counter. So if you're highest element to check is 250 and the lowest is 1 the verification preset is set to 250. if you scan all the way up or down and don't see a swap in that you know you're sorted entirely and can kick on the move enable bit to update your screen, or even just an alphabetized array of strings for troubleshooting the setup.

I can't off hand remember if there's anything else I've forgotten. I would suggest setting up the program in a timed task at first so you can setup a trend and watch the stuff move through. Not only is it fun to watch the lines go up and down, but if you setup that stuff in the continuous task it moves a little too quick to see. Once it's function drop that puppy in the continuous and let'r eat.
 
This is a controller-managed recipe system. The user wants to be able to input a recipe name instead of a recipe number, and then look up the recipe by name instead of number. I anticipate attaching numbers, too, so I can use them as pointers to find the actual recipe data sets.

I've done this in the past simply by attaching the recipes to numerical values within the PLC while displaying a numerically associated string tag, rather than the recipe number, on the HMI display. The creator of the recipes attaches a string name of their choice to the numbered recipe when it is created via the HMI. That doesn't resolve the issue of alphabetical sorting of the recipe names, but that's how I've done some recipe systems that stored their recipes in the PLC memory, rather than in a file or database on a PC. This prevents the issue of having multiple PCs on the network with different recipe tables, since the actual recipe data resides in the PLC RAM.
 
Correction!

Just wanted to make a quick correction from last nights post. The sort letter thing isn't necessary for what I was doing. I was confusing a couple parts of the program. When you're comparing strings in their entirety you can do the whole string value in one compare. The sort letter deal I was using when I wanted to compare the first portions of the strings.

Sorry about that.
 

Similar Topics

I have an unusual task with a PanelView Plus 7 (running v11 firmware) and a CompactLogix. The customer wants to place a version number string in...
Replies
3
Views
630
Hello all, I was looking into different sorting techniques and actually found a bubble/insertion sort sample code file on Rockwell's site. Only...
Replies
20
Views
5,348
Hello all, I am attempting to sort a selection list via 'part-selection' buttons. Ex. a certain type of model is selected, I only want to have...
Replies
5
Views
1,393
I am storing values into an array. I am wanting to find an average of the highs and an average of the lows. Something like this... After 50...
Replies
36
Views
8,959
Hello, I been trying to sort some values in the the Do-more PLC but still have some issues. I have 20 elements from the data view with random...
Replies
9
Views
3,690
Back
Top Bottom