Sorting an array of DINTS high to low

Join Date
Apr 2016
Location
Appleton WI
Posts
30
Edit to add - Logix Designer v30 / Controllogix L75

Guys, I'm sort of melting my brain here and I'm certain there has to be a better way to do this than what I'm coming up with, so bear with me.

I have a group of reclosers, 34 of them. I need to bring them up or down in order of a dynamic priority that I am assigning from my HMI. However, there is a higher priority that needs to be looked at first, I'm calling it a heirarchy. As in, if I bring the field online, Heirarchy 1 needs to check that the downstream (H2) are open so as to not have a massive inrush. Then I need to close the H1 group based on its assigned priority.

Once those are all closed, I can move on to the H2 group, check the H3s are open, and begin closing in the individual H2s in order of highest to lowest priority. So on and so forth. In a load shed scenario, I just have to work my way backwards, Dump lowest priority H4, loop through them until all are open, go to H3, and dump lowest priority until I get back into a balance load situation, even if that means working all the way up to dumping the H2 and H1 and just having a dead field.


So, the process is not that tough talking through, but I'm having a bit of a hard time determining how to sort through the priorities.

As in, I have UDTs that the priority maps 1-34 (1 highest, 34 lowest) from the HMI and then saves. I use a check sum to make sure I have no repeats (not the best way to check, but it works ok for my purposes / knowledge) The UDT also has the heirarchy in it, hard coded in the PLC 1-4 depending on what recloser it is.

What I'm trying to figure out is how to effectively sort through the 1-34 list that gets separated four times. As in, If I'm in H2 I have to ignore the other priorities in H3 that might actually be higher, as H2 needs to occur first in order for me to not possibly spike amperages.

I was thinking about, based on the heirarchy H1 - H4, moving the specific priority into a P1 - P4 array of DINTs. Then I would have four DINTS P1[0] - P1[33], P2[0-33] and so on. These would be filled with the various assignments, but mostly full of zeros. 0,0,0,0,0, 6,0,0,2,0,0,0,19,0,0,4, just as a sort of example of what I would expect to see.

I think what I need to do is figure out a way to loop those individual arrays and ignore the zeros, figure out the non zero values, and determine how to sort them from low to high or high to low depending on the scenario, and then based on their newly assigned 1,2,3,4 values, actuate the reclosers. Then I need to associate the new value with the appropriate recloser and open / close.

Does this make any sense. Do I sound delusional? I feel delusional.

I really don't know where to start on the sorting of the DINT array, though. File Sort sort of makes sense to me, but I'm not certain how to maintain the association to the appropriate recloser, unless I'm failing to understand the operation of it. So, comment and criticize, please. Most of this project has been fine, but this is a spot I'm feeling a bit over my head. Thanks
 
Last edited:
Time to indirect addressing.


Ron have example for 12fans, which takes non available motors off from rotation.


Thinking that you can use some of code for this and append 12 to 32 indirect outputs.


You need available list (not sorted),sorted list and indirect bits at least.



http://www.plctalk.net/qanda/showthread.php?t=49120






Bubble sort is another.
 
Last edited:
Maybe overthinked this.


You need 2 different values for every recloser. (Groups 1-4)
Then you need also number 1-34 for every recloser for quequ.

Counter from 1-34 also for switching off and on with pausing between different numbers.

if you counter is 1, and group numb=1 and recloser numb = 1 then set output, otherwise reset output.
(You need 34 compares on paraller or looping evey recloser 1..34 if they have quequ number .)

Then 33 times more comparing with quequ number 2-32.


And also same for groups 2-4.

As number 0 is not finded this way, they are discarded from control.



Lot of ladder, but no indirect addressing.

if number 1..34 is allways entered, then int sum is 595 which you can compare if all numbers are entered correctly? o_O


Would this make any sense?
 
Last edited:
Maybe overthinked this.


You need 2 different values for every recloser. (Groups 1-4)
Then you need also number 1-34 for every recloser for quequ.

Counter from 1-34 also for switching off and on with pausing between different numbers.

if you counter is 1, and group numb=1 and recloser numb = 1 then set output, otherwise reset output.
(You need 34 compares on paraller or looping evey recloser 1..34 if they have quequ number .)

Then 33 times more comparing with quequ number 2-32.


And also same for groups 2-4.

As number 0 is not finded this way, they are discarded from control.



Lot of ladder, but no indirect addressing.

if number 1..34 is allways entered, then int sum is 595 which you can compare if all numbers are entered correctly? o_O


Would this make any sense?

This was the method I was initially pursuing. I think it would work, but as you said, a hideous rats nest of ladder, especially once I begin accounting for the other program states. I also wasnt thrilled with the prospect of needing pauses necessarily, especially on an overgeneration state where I need to dump loads asap. The indirect addressing is not a big concern for me.

Looking through your first reply, I may be able to use some of those concepts. Thats a very helpful post. I'll go back to the counters as sort of a last resort.
 
Are the Heirarchies set from the HMI as well?


Is structered text available for this?

Heirarchies I am hardcoding in PLC as I do not want them to be modified.

Yes, structured text is available. Its how I'm doing the data handling to bring all my arrays into the program tags. Also controlling the reclosers with it.
 
I guess now that I think about it, I could do a dirty set of loops. Copy the array to a holding array, run the SRT on it, shift it to the first x number of dints in the array, then run a loop through my original array looking for the pointer number of where holding array x = array x, holding array y = array y, etc, and output the pointer value to tell me where in the array I am at. You could run the loop through the holding array until you get to DINT[....] = 0 and then use that as the trigger to increment to the next heirarchy?
 
You should look into creating a sorting algorithm. I've previously created an Insertion sort based of an example I found using pascal. Close enough to ST to serve as a guide.

In my exercise, I had any number of thermocouples placed on a a part. 1-48. Each had a temperature value when in process. The process couldn't move forward until the lowest value hit the minimum for the process, and given the number of TCs that could be used or not used I had to account for any combination of the TCs.

The insertion sort was very useful, it ended up sorting the values lowest to highest, and at the same time tracked the TC id number with the sort. This let me key off the first non-zero number of the sort, as it would be the lowest TC reading of all active TCs. Having the ID included with the sort allowed me to tell the operator which TCs the values were coming from and which we were waiting on.

You probably need to perform two sorts. 1 - The outer hierarchy, 2 - the inner values. Highly recommend working through a sorting algorithm as an exercise.

Note, there is the SRT instruction that might be useful as well. I found that due to the need to track my TC ID I needed to create my own AOI for sorting.
 
I've recently done my first pump rotation system and went through a similar process, I ended up not doing a sort, but determined which was the next pump to stop from the running pumps, and which was the next pump to start from the stopped pumps - you could adopt a similar approach as you don't actually need them stored in the 'correct' order.
 
Would simple double loop do that with array variables.


Inner loop is checking recloser 1-34. Outer loop is checkin which order each has.

Result is sorted numbers, but if order numbers are with caps.

device / order

11 = 1
12 = 2
15 = 5
17 = 7
21 = 8

result is 11,12,0,0,15,0,17,21


if there is no caps then

device / order

11 = 1
12 = 2
15 = 3
17 = 4
21 = 5


result is 11,12,15,17,21


Still you need check each groups intenpently and remove zeros from result if there is caps.




(* move 0 to finded order array *)

MOVE_INT_ARINT (IN := 0,
OUT => G1_FINDED_ORDER);


(* Move 0 to outputs, loop is setting outputs on every plc scan *)
MOVE_BOOL_AREBOOL (IN := 0,
OUT =>out );

(* Counters for looping, whe need 34 comparing and 34 times so all different combinations are checked*)

for i:=1 to 34 do;
for j:=1 to 34 do;



(* Looping trought different numbers *)


if G1_quequ_numbers[j]=i then
out_temp:=1;
G1_FINDED_ORDER:=j;
else
out_temp:=0;


End_if;

(*Number finded -> Set correct output bit on *)

if out_temp=1 then
out[j]:=1;
end_if;

end_for;
end_for;




 
Last edited:
Improved, caps are discarded


(* move 0 to finded order array *)

MOVE_INT_ARINT (IN := 0,
OUT => G1_FINDED_ORDER);


(* Move 0 to outputs, loop is setting outputs on every plc scan *)
MOVE_BOOL_AREBOOL (IN := 0,
OUT =>out );

(* Counters for looping, need 34 comparing and 34 times so all different combinations are checked*)

Numb_finded_save_index:=1;

for i:=1 to 34 do;
for j:=1 to 34 do;



(* Looping trought different numbers *)

(* Number finded, save finded number to array *)
(* caps are discarded with save index counter, which is only added +1 when new number is finded *)

if G1_quequ_numbers[j]=i then
out_temp:=1;
G1_FINDED_ORDER[Numb_finded_save_index]:=j;


Numb_finded_save_index:=Numb_finded_save_index+1;


else
out_temp:=0;


End_if;

(*Number finded -> Set correct output bit on *)

if out_temp=1 then
out[j]:=1;
end_if;

end_for;
end_for;


 
Ditto what L D[???] said.
If I want to do a priority scheme I first look at using bits.
Each item gets a priority bit with the least significant bit the highest priority. When an item is ready it is ORed into the ready WORD, DWORD or LWORD. It is easy to find the LSB set or the highest priority ready item. When an item is running then clear its ready bit and set the corresponding bit in the running WORD. No Sorting is necessary.
 

Similar Topics

Hello All, Needing some help with finding Min max values in an array that can have a dynamic element count. The Sort function in Logix 5K only...
Replies
9
Views
5,701
I am new to micrologix 850 cpu. Please help on sorting numbers in array. i want to sort in ascending order.
Replies
2
Views
2,095
Hello all, I've used these forums quite a bit in the past year while trying to learn PLCs and HMIs, and I've run across my first problem that...
Replies
1
Views
2,700
Hello, I need some ideas on how to sort an array. I have 3 1d arrays in a udt with a length of 101. Lets call them XAxis[0-100],YAxis[0-100],and...
Replies
3
Views
5,224
I have worked on small projects using AB Micrologix but now we want to take a photo, process it online, and sort based on returned variables...
Replies
5
Views
315
Back
Top Bottom