0:01
Thank you for joining us on this webinar. We’ll go further into data sorting function blocks.
0:08
The presentation itself is just under 12 minutes, but if you do have any questions, put them at any point and we’ll get them at the end.
0:15
Hello and welcome to today’s webinar. Today we will look at more data sorting function blocks for your Horner controller.
0:23
Today, we are going to start with a quick review of the data sorting user-defined function blocks, or UDFBs, that we have already covered in previous webinars.
0:33
Then we will discuss what is new with today’s functions.
0:36
Then we will go through some examples of applications for today’s functions, and we will have demonstrations throughout.
0:42
There will also be a Q &A session at the end.
0:46
Why data sort in a modular or all-in-one controller?
0:49
In today’s world, machine data is an important aspect of machine control.
0:55
Capturing and logging machine process data and performance data is also important.
1:01
Sorting that data on the controller itself offers several benefits, for example, finding the best and worst results, graphing data in value order, and so on.
1:11
This is the last bit of review we are going to go through on data sorting function blocks, as we have already done so in a previous webinar.
1:19
You can find this webinar on either our website or YouTube channel under the name Data Sorting Operations in the Horner OCS.
1:28
In that video, we explained the concept of a bubble sort, how bubble sort logic was applied in the data sort UDFBs, and we did some demonstrations on importing and using the data sort UDFBs.
1:42
We are going to quickly look at the Horner data sort user-defined function block, both a sort up and sort down user-defined function block are available.
1:54
In this example we are looking at a sort up integer user-defined function block.
2:00
On the input side we have three inputs and on the output side we have four outputs.
2:06
We have en for enabling the sort, INAY or input array for inputting the array data to sort and length for the length of the array to sort.
2:19
We have done which will flag when the process finishes, out array which outputs your sorted array, pass count which tells us the number of passes required to sort the data and finally error which will flag any errors that might occur.
2:36
Now let’s discuss what’s new with today’s sorting user-defined function blocks.
2:42
Sometimes we have sets of machine data that need to be managed.
2:47
On the right we have four variables, each captured as a set with a common index number.
2:54
In this example each index number captures the same row of data at the same time or on the same trigger.
3:02
So each row is related in terms of when they were taken.
3:05
For this demonstration we want to sort variable A in ascending order or sort up and then we want the other variables to be sorted so they correlate with variable A.
3:19
We are not trying to sort the data within variables B, C or D.
3:25
We only want to sort the data in variable A but we want B, C and D to be reordered to match the changes made to variable A.
3:37
If we use one of our existing sort function blocks we can easily sort variable A as shown by the tables on the right.
3:46
However the original indexes have been lost.
3:50
With today’s sorting user-defined function blocks we can now return the sorted data as well as the corresponding original indexes.
4:00
And this is important because now we can use those original indexes to sort the columns.
4:07
This way we only sort variable a and then our other columns are reordered to match the changes made to a.
4:16
Now let’s take a look at the new data sort user-defined function blocks with index outputs.
4:22
This will look very similar to the sort up integer user-defined function block we looked at earlier but now with two output arrays.
4:33
One for the array of sorted data one for the array of original indexes.
4:39
Beyond our previous example we can also use original index arrays for other sort UDFBs.
4:46
Here we have another sort block called an index sort user-defined function block.
4:52
It has a lot of the same inputs and outputs as the previous block we looked at but now with a new input index array. Instead of sorting data by value, we can sort it by an inputted index array.
5:06
Now let’s look at how these new function blocks work on the bench.
5:12
Here we have our Horner controller configured with the user-defined function blocks you’ve just seen.
5:18
In this column on the left, we have a list of initial unsorted data that we want to sort in ascending order.
5:25
Beside the list, we have the corresponding indexes for each value.
5:30
We are going to sort these with a SortUpUDFB that will output our initial indexes.
5:36
Once we press this button, we can see that our data is sorted in ascending order in this column on the right.
5:43
And we have also received a copy of the original indexes.
5:48
And it is these indexes that we will use to sort our other data.
5:52
Now, let’s continue and do some additional sorting, but this time by using the array of original indexes.
5:59
Here is our list of indexes from the previous sort, and beside it, we have two additional columns of data, and we are going to sort both of these lists not by their values, but by their indexes.
6:11
So, once we press this button, we can see that the first list gets sorted, and we can verify that it has worked correctly by checking the sorted values against their original indexes.
6:22
So the first value should have originally been in index 3.
6:26
And as we can see, indeed it is.
6:29
The next value should have originally been in index 1.
6:33
And once again, we can see that it is.
6:36
Now we can go ahead and sort the next list.
6:39
Once again, we can see that all our data gets sorted by the indexes correctly.
6:45
Now let’s jump to Cscape and see how this works.
6:51
Here we are in Cscape.
6:52
In the logic area we can see our user-defined function blocks.
6:57
These were added to our Cscape by first navigating up to the menu on the left and right-clicking on Logic Modules.
7:05
Then we click Import Logic Modules and you will then be asked to select the Logic Modules which, once selected, will appear here under User-Defined Function Block Modules.
7:18
They will also be added to the toolbox under UDFBs.
7:22
The first function block in our logic is a sortUp double integer UDFB.
7:28
For our demonstration, we have named it testD index, but yours can be whatever you prefer.
7:35
Then we have to assign all our inputs, including our input array and all our outputs.
7:41
Once this sort has been completed, we will take the output index array down to our next bit of logic.
7:48
These next two function blocks use the other UDFB that we imported, the index source.
7:56
As we can see, our input index array for both these function blocks is the same output index array from our initial source.
8:05
Now that we’ve shown you the workflow, we are going to go through an example application for this sort of program.
8:13
We are going to look at a pumping application.
8:15
For this demonstration, imagine we want to select which of four pumps to use based on machine hours.
8:24
At selection time, the pump with the least number of hours should be selected, unless it is out of service.
8:32
To set this up, the following arrays have been created for pumps 0 through pump 3.
8:37
Pump hours, which is a double integer that contains, in hours, how long the pump has been pumping.
8:44
PumpInService, which is an integer where the low bit indicates whether the pump is in service or not.
8:50
And finally we have PumpSelected, which is another integer where the low bit indicates which pump is selected.
8:57
So how is our logic going to execute?
8:59
First we are going to sort the PumpHours array from least to most using the SortUpUDFB.
9:07
This user-defined function block also outputs a list of the indexes corresponding to the sorted list of pump hours.
9:15
Based on the first index value, we will select the pump, unless it is out of service.
9:21
Finally, if the pump with the least number of hours is out of service, we check the next pump and so on down the line until we land on an available pump.
9:30
Now let’s look at a demonstration on the bench.
9:36
Here we are on the bench.
9:37
Here we have all four pumps and this button at the bottom will begin our sorting logic.
9:43
We will start by setting all the pumps to be in service.
9:48
For this demonstration, we have made a button that simulates a pump being in or out of service.
9:55
Based on our logic, once we hit the button at the bottom of our program, our program should automatically select the pump with the hours that is also in service which in this demonstration happens to be pump three. Once we hit the button we can see that pump three is indeed selected.
10:14
Now we are going to simulate that pump being out of service.
10:19
If we start our sorting program again we would expect pump two to be selected as that is the next pump with the least amount of hours and once again we can see that our program selects the correct pump.
10:32
Our logic is working as intended, and it will always select the pump with the least amount of hours that is also in service.
10:41
Now, let’s switch back to Cscape and take a closer look at the logic inside.
10:46
The core of this logic is here, in our sortWithIndexOutput function block.
10:52
The pump hours array is our input. The output is the sorted hours array as well as the original index array.
11:02
This original index array is the key to sorting our pumps.
11:07
Then we are going to deselect all current pumps and based on the index array we are going to select the pump with the least hours.
11:15
But before we select that pump we are going to use our index array once again to check if that pump is in service or out of service.
11:25
If the block receives a 1, that means it is in service, but if it receives a 0, that means it is out of service.
11:33
Then on the next rung, here if the program has received a 1, then this block executes, which selects the desired pump.
11:41
But in the situation where the pump is out of service, we increment our count by 1 and loop back to the top of this logic to retrieve the next index in our array.
11:51
and this process will repeat until a suitable pump is found.
11:57
That concludes our webinar for today. Thank you so much for listening and the Q &A session will begin shortly.
12:10
Okay, so next week we’ll be following up with using set points with our controllers.
12:15
As usual, the registration links are up on the website or in the newsletters that would have gone out.
12:20
So if that is of interest to you, the registration links are there.
12:24
We don’t see any questions in on today’s webinar so I think we can leave it there.
12:28
Thank you all for joining us, we’ll see you next time.