(AB) Bubble Sort Ladder Logic Example Code

ck8177

Member
Join Date
Oct 2021
Location
SW Ohio
Posts
31
Hello all,

I was looking into different sorting techniques and actually found a bubble/insertion sort sample code file on Rockwell's site. Only problem is, the sample code is written in ST which is apparently a paid option that my company does not have. Does anyone have examples of implementing a sorting algorithm like this in ladder logic, or even screenshots of ST/FBD code?

TIA
 
Last edited:
It's pretty simple for a bubble sort (there are other ways) you need to create two loops one inside the other, but bear in mind that if you have an array of 9 values then the code will loop through it'self 100 times so you have to be careful that you do not exeed the watchdog timer. The other solution is to only use one loop but keep going through it each scan until there are no changes but then you may need to set a bit until you need to run the function again.
Inserting a value into the array would need a bit more logic & modifications to the pointers and allow the last one to drop off as you cannot have a variable array of indeterminate length.
run through the itterations i.e. array length X array length or run one loop every scan until no more moves required, or just run one swap (if required) each scan but bear in mind the loops would have to complete before a new value is inserted, also remembering if you insert a new value you would have to overwrite one of them, I have done that with a two dimentional array using a timestamp & inserting it into the one with the oldest timestamp.
I do not have CLX but this is in FBD so should give you some ideas if I have understood your post correctly
 
It's pretty simple for a bubble sort (there are other ways) you need to create two loops one inside the other, but bear in mind that if you have an array of 9 values then the code will loop through it'self 100 times so you have to be careful that you do not exeed the watchdog timer.
The simple solution is to sort one item per scan if the results aren't needed immediately. Another option is to do only one outer loop per scan.
Also, the bubble sort will usually try to find the min first. After it is found it doesn't need to check it the next time through the loop. This will reduce the time in half. Another solution is
I am surprised there isn't an AOI already written for this. There doesn't seem to be a Rockwell Users Group unless there is something like that on github.
 
If you're using the Logix platform, there is a sort (SRT) instruction that operates on a linear array of simple values (DINT, REAL, etc).

You would need to do your own if an older platform (e.g., PLC-5), or you needed to sort a UDT based on an element value.
 
I posted this previously... If its an array of elementary data type use SRT.
Below is an example that sorts an array of a udt with two members: id and count.

In Ladder:

Code:
Main -> For i -> For J -> Sort Logic

Main:

Lad1.png

i routine:

Lad2.png

j routine:

Lad3.png



or in ST:

ST.png
 
As I posted, the one shown sorts from lowest value to highest, (easily changed to high to low I also mentioned doing it either one per scan or doing inner per scan while the outer did it on successive scans, the OP did mention inserting, that poses another problem that would require dropping one off each insertion. The OP also mentioned an AOI that exists but in ST that's why I posted a version in FBD I do not have AB loaded at the moment. The information posted is a little vague in respect of what is required in the sort. i.e. how often will data be added, is it a sort after data how often etc.
 
Thank you all for the input. A few points to clarify what is being attempted:

The data in question is an array of UDT's.

Current array size is 25.

The value by which the data will be sorted is UDT[x].Integer.

The data in question is a recipe structure, and the sorting itself would only have
to occur when the data in the array of UDT's is modified, which occurs with the system in manual mode. Therefore the sort could be distributed over multiple scans as necessary.
 
The problem is without knowing the structure of the UDT it is difficult to determine how it could be done.
If for example the recipe only contained integers (or only one type) then pretty simple, however, if the recipe contained othe datatypes and the integer variables were not in a contiguous block this would be very difficult without brute force of each integer at a time.
Perhaps give a screenshot of the structure of the recipe, using a UDT usually means that the structure contains different types & probably not ordered in variable types.
Although 25 seems reasonably small.
How is the sorting going to work ?
Are you sorting the variables in a recipe in order of say low to high ?
Or are you sorting the recipes as a block in order ?
Are all the variables you want to sort integers ? without any other types
 
Here's my submission for a bubble sort, low to high of 25 UDTs, one comparison per scan. Untested on actual hardware. Sorry for photo of screen.

I made the array 26 long to use the extra UDT[25] for temporary storage, but you could use a separate single UDT. The limit is extra precaution because you don't want to try to operate outside the bounds of an array.

361ECEC0-B369-480D-AD1D-2DCE112838D2.jpg
 
The data in question is an array of UDT's.

Do you want to sort the data in place e.g. without more than one extra UDT instance for swapping and/or temporary storage?

Actually, I think @5618's code is perfect: even if Index becomes a pathological value, it will eventually recover (I hope Index is not a DINT ;)); and it will always (normally) ensure the array is sorted within 576 scan cycles after any changes.
 
Last edited:
The simple solution is to sort one item per scan if the results aren't needed immediately. Another option is to do only one outer loop per scan.
Also, the bubble sort will usually try to find the min first. After it is found it doesn't need to check it the next time through the loop. This will reduce the time in half. Another solution is
I am surprised there isn't an AOI already written for this. There doesn't seem to be a Rockwell Users Group unless there is something like that on github.

Quite a strange solution

My stuff uses simple sorts like this (check Sys AOIs). The problem isn’t that it hasn’t been done, it’s that you have to effectively have a re-definition of the sort code for every complex data type you want to manage.

Rockwell could implement class/overload/interface support so that we could just define how comparison operators behave on a UDT basis. The best that can be done now is a comparable key (usually DINT), then using COP to do the actual data movement. But you still need a unique AOI per.
 
Last edited:
As an aside has anyone implemented a Quick Sort in ST?
I have a WIP version...

//Declarations
//InOuts
Array_In: UDT_Example[1]
Array_Sorted: UDT_Example[1]
//Inputs
Direction: DINT
//Local
ArraySize: DINT
i: DINT
j: DINT
low: DINT
high: DINT
pivot: DINT
temp: UDT_Example
stack: DINT[64]
top: DINT


ST Quick Sort:
Code:
SIZE(Array_In, 0, ArraySize);
COP(Array_In[0], Array_Sorted[0], ArraySize);

top := 0;

stack[top + 1] := 0;
stack[top + 2] := ArraySize - 1;

WHILE top >= 0 DO
    high := stack[top + 2];
    low := stack[top + 1];
    top := top - 2;

	IF high > low THEN
        pivot := Array_Sorted[high].Count;
        i := low - 1;
        FOR j := low TO high - 1 DO
            IF (Direction = 0 AND Array_Sorted[j].Count >= pivot) OR (Direction = 1 AND Array_Sorted[j].Count <= pivot) THEN
                i := i + 1;
                COP(Array_Sorted[i], temp, 1);
                COP(Array_Sorted[j], Array_Sorted[i], 1);
                COP(temp, Array_Sorted[j], 1);
            END_IF;
        END_FOR;

        COP(Array_Sorted[i + 1], temp, 1);
        COP(Array_Sorted[high], Array_Sorted[i + 1], 1);
        COP(temp, Array_Sorted[high], 1);

        top := top + 2;
        stack[top + 1] := low;
        stack[top + 2] := i;

        top := top + 2;
        stack[top + 1] := i + 2;
        stack[top + 2] := high;
    END_IF;
END_WHILE;
 
Last edited:
IIRC, the first step of quicksort is to shuffle the elements randomly, which attempts to prevent quicksort performance from being O(N2).
 

Similar Topics

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,586
Hi, im creating compressor station project with S7-1200. Project requires that 4 compressors should work in cascade - that's already done, and...
Replies
13
Views
11,528
Hey, I have written a function in SCL for doing the bubble sort thing. The code is taken from wikipedia. But, question I have is: When you...
Replies
20
Views
6,099
Hi all, I need some help here please. I'm trying to understand the SCL programming example included in the SIEMENS SCL official documentation...
Replies
1
Views
7,776
Good afternoon guys, I have a basic question on the bubble level in the picture attached. This is probably really easy, but I don't get it, haha...
Replies
11
Views
3,266
Back
Top Bottom