Sorting in Plc from smallest to largest

Avatar_41

Member
Join Date
Aug 2019
Location
Istanbul
Posts
96
Hello friends. There is an int type, number that I got from the DataBlock. For example, the DataBlock address is Db1.dbw0. Here's what I want to do, there are crates from 1 to 10. I want to use these crates in order from smallest to largest. In other words, when the robot uses the number of safes I specified, for example, it left 10 pieces in the 1st safe, and I want to use it in this way, which will move to the 2nd safe and then to the 3rd. But, if there is no active signal from safe 2, I want it to go to safe number 3, which is the smallest number, since 2 is passive after 1. I will set the passive signal as active passive from the HMI Panel. or I will set it passively with the compare command. Can you help me how can I do this? Thanks in advance. The program I use is Simatic Manager, Plc S7-315-2 Pn/DP. Hmi panel Mp277, 8'Touch.
 
Your description is a little confusing, do you mean the robot only puts data into DB1.DBW0 ?
Then you want to sort them into an array of 10 cells in order ?
 
Hello again, imagine that there are 10 sensors belonging to 10 cases. There are 10 int type data in DB1. If the sensor of the safe does not output, it will not write data to the Datablock, if it does, the address of the smallest safe will be written to DB1.DBW0. The next major vault number will be written to DB1.DBW1. This way the smallest value will always be written to DB1.DBW0 and Robot will read this value. If the lowest value safe is deactivated, the next smallest safe will be written to DB1.DBW0. I tried to simplify, I hope I succeeded. Because the problem is already a bit complicated ��. Thank you.
 
It is still not very clear.

It sounds like there are 10 safes (also known as "" vaults" or cases").

Each safe has two properties:
(1) an index (or address) e.g. 0 to 9, of the safe; this index is unique to each safe and never changes.
(2) a sensor-defined value for that safe, or no value if the sensor does not write an output for that safe. This value can change when the sensor makes a measurement on the safe. This value of a safe can also become "no value" when the robot reads the index of that safe from DB1.DBW0.

You want DB1.DBW0 to always contain the index (1), of the safe with the smallest value (2).

And if a safe has no value, then it should be the same as if that safe has a very large value (2), so DB1.DBW0 will never contain the index (1) of a safe with no value (2).

Finally, when the robot reads the index (1) of a safe from DB1.DBW0, then that safe's value (2) becomes "no value," and the index (1) of the safe, with the next lowest value (2), is moved into DB1.DBW0.

Is that what you want?
 
Last edited:
What is the range of indexes (also known as addresses) of the safes?

What is the range of sensor values for each safe?
 
Damn, it is little bit difficult even without old S7-300 CPU.
You have SCL programming option? šŸ™ƒ


For 10 different values sorting values 10 times is maybe easier on 300. Longer coding but easier to understand.


Buble sort would need I and J indexing and indirect addressing on STL. šŸ”Ø.
 
I will try to explain it with the plainest and simplest carpet I can, because I cannot use English well enough, which causes me to explain the problem well enough during translation. However, something occurred to me. Can I print the smallest number to a DB address provided it is greater than Zero as the int value of the deactivated safe will be Zero? It doesn't have to be DB1, but if we sort the smallest number greater than zero in DB 1 in DB 2, my problem will be solved again. I'm pretty new to SCL, but if there is an example I'll consider it as well. Thank you for your support.
 
I Can I print the smallest number to a DB address provided it is greater than Zero as the int value of the deactivated safe will be Zero?

[Whoops, I had to correct the logic in the second code block a few times!]
Yes. The key here is the compare operation used to sort the indices: instead of
Code:
IF value[INDEX1] > value[INDEX2] THEN ...
you can do
Code:
IF (value[INDEX1] > 0 AND value[INDEX1] > value[INDEX2])
OR (value[index1] < 1 AND value[index2] > 0)
OR (value[index1] < 1 AND value[index2] < 1 AND INDEX1 > INDEX2)
THEN ...
To determine if INDEX1 should sort after INDEX2. Similar code could be used to determine if INDEX2 should sort before INDEX2.

Also, you don't need to sort the indices into a list. It would be less work to simply find the index with the smallest non-zero value each time, and once the robot chooses that index, then put a zero in that index's value, so it would not be chosen the next time.
 
Last edited:
your English is better than some people who's main language is English šŸ»šŸ»
Anyway, I think I understand what you are trying to do.
Rather than describe the variables as actual addresses I will use what we call post boxes or containers.
So you have a container where the robot picks up the number in it
You also have a set of containers (an array of 10), the 10 containers have the values in them in any order for example 10,2,0,5,6,3,7,8,1,4
At some point you want to find the smallest value in those containers & move it into the container the robot uses, however, if the container is not active then it finds the next lowest container.
Lets assume then tht DB1.DBW0 is the container for the robot and DB1.DBW2 to 20 are the stored values (note: Semens data blocks are actually 8 bit (byte)not 16 so if used as words then it takes two i.e. DB1.DBB0 & DBB1 is the 16 bit word so word 0 is DB1.DBW0, Word 1 is DB1.DBW2).
So, now we have a range of words (we will use DB1.DBW0 as the value for the robot and DB1.DBW4 (leave a spare) to DB1.DBW24 as the 10 containers for the numbers to be selected).
DB1.DBW0 This is the word for the robot
DB1.DBW4 Store 1
DB1.DBW6 Store 2
DB1.DBW8 Store 3
DB1.DBW10 Store 4
DB1.DBW12 Store 5
And so on
You create a pointer to the first container and also move this into a temporary variable, compare this with the lcontainer pointed to (initially it is the same as in the temporary variable) so if it is greater than 0 and less than the one in the temporary variable move it into the temporary variable, increment the pointer, check if all 10 containers have been checked, if not loop back, else exit loop. There are other things you might need to check i.e. you mention a disable mode so the containers could be disabled, this would require a second array with values i.e. if enabled or disabled.
This could be done by having a two dimentional array so array[x,0] would contain the value array[x,1] contains the enable.
I do not have S7 here at the moment but will produce some code that althogh not the same but give you some ideas on how to proceed, assuming the above is something close to what you are trying to do.
 
[Whoops, I had to correct the logic in the second code block a few times!]
Yes. The key here is the compare operation used to sort the indices: instead of
Code:
IF value[INDEX1] > value[INDEX2] THEN ...
you can do
Code:
IF (value[INDEX1] > 0 AND value[INDEX1] > value[INDEX2])
OR (value[index1] < 1 AND value[index2] > 0)
OR (value[index1] < 1 AND value[index2] < 1 AND INDEX1 > INDEX2)
THEN ...
To determine if INDEX1 should sort after INDEX2. Similar code could be used to determine if INDEX2 should sort before INDEX2.

Also, you don't need to sort the indices into a list. It would be less work to simply find the index with the smallest non-zero value each time, and once the robot chooses that index, then put a zero in that index's value, so it would not be chosen the next time.

Thank you.
 
[Whoops, I had to correct the logic in the second code block a few times!]
Yes. The key here is the compare operation used to sort the indices: instead of
Code:
IF value[INDEX1] > value[INDEX2] THEN ...
you can do
Code:
IF (value[INDEX1] > 0 AND value[INDEX1] > value[INDEX2])
OR (value[index1] < 1 AND value[index2] > 0)
OR (value[index1] < 1 AND value[index2] < 1 AND INDEX1 > INDEX2)
THEN ...
To determine if INDEX1 should sort after INDEX2. Similar code could be used to determine if INDEX2 should sort before INDEX2.

Also, you don't need to sort the indices into a list. It would be less work to simply find the index with the smallest non-zero value each time, and once the robot chooses that index, then put a zero in that index's value, so it would not be chosen the next time.

Thank you. šŸ‘
 
your English is better than some people who's main language is English šŸ»šŸ»
Anyway, I think I understand what you are trying to do.
Rather than describe the variables as actual addresses I will use what we call post boxes or containers.
So you have a container where the robot picks up the number in it
You also have a set of containers (an array of 10), the 10 containers have the values in them in any order for example 10,2,0,5,6,3,7,8,1,4
At some point you want to find the smallest value in those containers & move it into the container the robot uses, however, if the container is not active then it finds the next lowest container.
Lets assume then tht DB1.DBW0 is the container for the robot and DB1.DBW2 to 20 are the stored values (note: Semens data blocks are actually 8 bit (byte)not 16 so if used as words then it takes two i.e. DB1.DBB0 & DBB1 is the 16 bit word so word 0 is DB1.DBW0, Word 1 is DB1.DBW2).
So, now we have a range of words (we will use DB1.DBW0 as the value for the robot and DB1.DBW4 (leave a spare) to DB1.DBW24 as the 10 containers for the numbers to be selected).
DB1.DBW0 This is the word for the robot
DB1.DBW4 Store 1
DB1.DBW6 Store 2
DB1.DBW8 Store 3
DB1.DBW10 Store 4
DB1.DBW12 Store 5
And so on
You create a pointer to the first container and also move this into a temporary variable, compare this with the lcontainer pointed to (initially it is the same as in the temporary variable) so if it is greater than 0 and less than the one in the temporary variable move it into the temporary variable, increment the pointer, check if all 10 containers have been checked, if not loop back, else exit loop. There are other things you might need to check i.e. you mention a disable mode so the containers could be disabled, this would require a second array with values i.e. if enabled or disabled.
This could be done by having a two dimentional array so array[x,0] would contain the value array[x,1] contains the enable.
I do not have S7 here at the moment but will produce some code that althogh not the same but give you some ideas on how to proceed, assuming the above is something close to what you are trying to do.

Thank you. šŸ‘
 
Yes that is correct, attached is a different PLc code, this could be a function block I have tried to do it in a fashion that replicates Siemens but that is difficult, I have not added the two dimentional array but that would be easy, I assume that in Siemens a two dimentional array would be
DBW4 Array[0,0] Number
DBW6 Array[0,1] Status i.e. Enabled, disabled or what ever you need
DBW8 Array 1,0] Number
DBW10 Array[1,1] Status
and so on.
It would be just adding another compare on ladder 2 for the status so it only moved the number if enabled.
There other obvious things that need to be done like perhaps only call the function on a oneshot when you need to find & store the lowest value to the Robot container.
Also, there will be I assume the population of the containers from the HMI.
If you are using Step 7 Classic & it is a S7-300 then I would do it in STL I'm very proficient in S5, but S7 is something I have not used in many years so pointers are a bit different.

Lowest HMI.png Find Lowest.png
 
haha @parky beat me to it, as usual. Here is the same thing.

I assume the JMP instruction or similar is available to OP and that JMP does not jump back to the LOOP label if the rung feeding it is FALSE; @parky's version uses a CJ, which I assume is a Conditional Jump.
2022-08-30-034935.png
 
Last edited:
ST/SCL is a little cleaner, or at least more compact:

min_idx = 0;
index := 1;


FOR INDEX := 1 tTO 9 DO
IF val[min_idx] < 1 OR (val[index] > 0) AND val[index] < val[min_idx]) THEN
min_idx := index;
END_IF
END_FOR;


P.S. @parky: I am not up early, I'm in Trondheim!
 

Similar Topics

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
First off, I am new to the whole PLC world and was tasked with a project at work. I was given a Click C0-11dre-D, Honeywell 310G barcode scanner...
Replies
4
Views
2,302
I am trying to make an object sorting system using PLCs for university. The system uses the shape of incoming objects to figure out if they need...
Replies
9
Views
3,739
Hello all, I am currently reseaching the best way to create a simple sorting system. My challange is that all sorting decisions are made by...
Replies
2
Views
6,055
I am a user of Siemens PLCS. I am not a regular visitor of this site, but whenever I am here, I click mostly * Postings that are related to...
Replies
14
Views
3,242
Back
Top Bottom