First a disclaimer, this is purely an exercise which I found to be interesting and decided to share my results.
A while back there was a post on changing the array size within and AOI dynamically. I was curious about this and set out to explore some possibilities for its use. At the time I had watched a documentary about sorting algorithms and realized that a sorting AOI which could automatically adjust to the size of the dataset input into it could prove useful on the production floor (think motor runtime, valve/actuator activation counts as it relates to life cycle and PMs). I thought it would be a fun exercise to see if I could create a self-aware solution which minimized impact on logic execution.
The solution results: 5,000 random values ranging from -2,147,483,648 to +2,147,483,647 are sorted in descending order in ~ 400ms using a 1756-L73 controller. This also includes 5000 indexes, 1 index per value so I can track the identity of each value during the sort.
Actual results of PLC sorting:
Further tests produced:
1,000 random values ~ 50ms
100 random values ~ 3ms
50,000 random values ~ 5,845ms
375,000 random values ~ 66,027ms
As a baseline, using the SRT instruction it sorts 5,000 random values in ascending order w/no index reference took ~ 1100ms. If I remove the index consideration of the sorting AOI, the AOI can sort 5000 random values in ~ 270ms!
Testing Information:
I used Excel and vba to generate the random values, some more VBA allowed me to download the random values to the PLC, trigger the sort, then upload the values back into Excel for a nice chart to confirm the sort was successful. To confirm impact on scan times I simply looked directly at the monitor tab of the task the logic was in and referenced the “max” scan time. I reset this prior to each test and the AOI was triggered on a one-shot. The logic in a “steady’ state was running at 0.10 ms, so negligible.
Algorithm:
When first playing with the sort concept I used a “bubble” sort. This worked but as I progressed I found that a “shell” sort had little bit better performance-wise and less logic. I did not track the data to show this. I did not attempt any other type of sorting algorithm as I was happy with the results. I have decided not to post my source code as to encourage others to try to create their own. Hint - find a pascal example of the algorithm you wish to try and start there, pascal is extremely close to structured text and requires minimal changes to port. It would be interesting to compare the results of other sorting algorithms if people wish to try.
Here is a screen shot of the AOI and parameters into it. Notice they have an array size of [1].
Process:
Since I want to maintain an index with its associated value, the data is really best described as a 2 dimensional array: Data[index,value]. While I was able to use a 2 dimensional array and create the shell sort solution, there was large impact on scan time, and I could not make the AOI array sizes dynamic as this only works on one dimensional arrays. Hence my final AOI parameters are one-dimensional for a total of 4. 2 for the unsorted data index and value and 2 for the sorted data index and value. These 4 tags are required to be the same type and length. The AOI adjusts accordingly.
Conclusions:
The dynamic ability in the AOI is very convenient for this example. I simply had to resize the 4 array tags input into my AOI (or reference other tags of varying array sizes), the AOI definition did not have to change. I spent more time adjusting my VBA so I could write/read the test values (went from simple "fixed" code to "I should make this dynamic to match..."). It was very easy to change from 10 – 100 – 1000 – 5000 – 50,000 - 375,000 and test the logic. Examination of the implementation and results it produces are positive IMHO. It works with minimal impact on scan time unless you are trying to sort a large dataset which is highly unlikely in a PLC. Considering that a sort function probably does not to be ran per scan calling it from an event, or dropping into a 1 sec periodic tasks seems very reasonable if you wish to process up to 50,000 values or so. Single AOI that doesn't require changes to adapt to varying data sizes, I'll take it!
A while back there was a post on changing the array size within and AOI dynamically. I was curious about this and set out to explore some possibilities for its use. At the time I had watched a documentary about sorting algorithms and realized that a sorting AOI which could automatically adjust to the size of the dataset input into it could prove useful on the production floor (think motor runtime, valve/actuator activation counts as it relates to life cycle and PMs). I thought it would be a fun exercise to see if I could create a self-aware solution which minimized impact on logic execution.
The solution results: 5,000 random values ranging from -2,147,483,648 to +2,147,483,647 are sorted in descending order in ~ 400ms using a 1756-L73 controller. This also includes 5000 indexes, 1 index per value so I can track the identity of each value during the sort.
Actual results of PLC sorting:
Further tests produced:
1,000 random values ~ 50ms
100 random values ~ 3ms
50,000 random values ~ 5,845ms
375,000 random values ~ 66,027ms
As a baseline, using the SRT instruction it sorts 5,000 random values in ascending order w/no index reference took ~ 1100ms. If I remove the index consideration of the sorting AOI, the AOI can sort 5000 random values in ~ 270ms!
Testing Information:
I used Excel and vba to generate the random values, some more VBA allowed me to download the random values to the PLC, trigger the sort, then upload the values back into Excel for a nice chart to confirm the sort was successful. To confirm impact on scan times I simply looked directly at the monitor tab of the task the logic was in and referenced the “max” scan time. I reset this prior to each test and the AOI was triggered on a one-shot. The logic in a “steady’ state was running at 0.10 ms, so negligible.
Algorithm:
When first playing with the sort concept I used a “bubble” sort. This worked but as I progressed I found that a “shell” sort had little bit better performance-wise and less logic. I did not track the data to show this. I did not attempt any other type of sorting algorithm as I was happy with the results. I have decided not to post my source code as to encourage others to try to create their own. Hint - find a pascal example of the algorithm you wish to try and start there, pascal is extremely close to structured text and requires minimal changes to port. It would be interesting to compare the results of other sorting algorithms if people wish to try.
Here is a screen shot of the AOI and parameters into it. Notice they have an array size of [1].
Process:
Since I want to maintain an index with its associated value, the data is really best described as a 2 dimensional array: Data[index,value]. While I was able to use a 2 dimensional array and create the shell sort solution, there was large impact on scan time, and I could not make the AOI array sizes dynamic as this only works on one dimensional arrays. Hence my final AOI parameters are one-dimensional for a total of 4. 2 for the unsorted data index and value and 2 for the sorted data index and value. These 4 tags are required to be the same type and length. The AOI adjusts accordingly.
Conclusions:
The dynamic ability in the AOI is very convenient for this example. I simply had to resize the 4 array tags input into my AOI (or reference other tags of varying array sizes), the AOI definition did not have to change. I spent more time adjusting my VBA so I could write/read the test values (went from simple "fixed" code to "I should make this dynamic to match..."). It was very easy to change from 10 – 100 – 1000 – 5000 – 50,000 - 375,000 and test the logic. Examination of the implementation and results it produces are positive IMHO. It works with minimal impact on scan time unless you are trying to sort a large dataset which is highly unlikely in a PLC. Considering that a sort function probably does not to be ran per scan calling it from an event, or dropping into a 1 sec periodic tasks seems very reasonable if you wish to process up to 50,000 values or so. Single AOI that doesn't require changes to adapt to varying data sizes, I'll take it!
Last edited: