Host Engineering Forum
General Category => Do-more CPUs and Do-more Designer Software => Topic started by: Mike Nash on March 16, 2016, 09:16:04 PM
-
I have a new project that is hurting my brain (conceptually.) In playing around with different ideas, or seeing what sticks to the wall, or tickles my brain, or whatever, I have come to a few conclusions.
First, it is so incredibly easy to do things with the Do-more. The biggest issue I have is looking for the instruction that surely must be there because everything else has been. (Unless I overlooked it, there is no instruction to SWAP two memory locations without switching bytes or words around.)
Second, bubble sorting 30,000 Signed Double Integers in a Do-more may take a few days if the values start as random numbers (nice function that RANDREAL()*10,000 or whatever for getting test values quickly. I had to "build" one once in a 260 and it wasn't fun.)
Third, I was surprised to find that MAPIO, INIT and MATH all ran faster than MOVE and much faster than MEMCOPY when doing the shuffle in a random 1000 cell bubble sort. No optimizations, all 1000*999 loops "swapping" Q-memory (just another D table) with a third temp holding cell. The first three take 2 min 32 secs, MOVE is 2 min 59 secs and MEMCOPY takes 3 Min 34 secs. Two runs for each with fresh random numbers. Sorting was done in a task with 100 uS time slice (more didn't seem to matter, nothing else is happening anyway.) Some optimizing has it to 1 Min 30 secs using MAPIO for full random values, quicker if partially sorted.
The MAPIO is the cleanest since I don't need to see the values as this is happening. That's the only thing I don't like about MAPIO for its intended purpose, the not having monitor values. But since I have 3 arrays to sort based on the contents of one array, I can do all of it with a single MAPIO, including an extra check value to stop sorting values that are already done. That's 10 discrete moves in one instruction, in order.
And no, I don't think I will pursue the 30K array option. It was just a test, it was only a test.
Nice job Host!
Now to stop tickling my brain by throwing it against the wall...
-
Do you have to physically sort the arrays? Would it be faster to generate an index array?
-
I wouldn't mind seeing a SORT function.
-
I wouldn't mind seeing a SORT function.
On the list. We will add this when we implement Tables.
-
Do you have to physically sort the arrays? Would it be faster to generate an index array?
I haven't quite got the concept nailed down I'm but much closer. I don't think I'll have more than 200-500 values to calculate and sort and that happens pretty fast since I am sorting as the table is built. I also get to do all this before the machine starts up so no need for massive speed.
-
Export Memory Data is a fantastic feature. Being able to select very specific ranges of memory to export and even choosing how many rows, and names and then one click into the spreadsheet has helped tremendously. (I have been looking for patterns in the data Do-more is producing from my code.)
I've looked in help and the forum but I can't find a means of saving the export ranges I've selected so I can easily pop out another batch to look over. Cut and paste didn't work and I right clicked all over with no helpful hints. It's not hard at all, but I have 14 ranges to type in each time.
Is there a way to do this?
I'll admit I have still got to dig into the memory manager as that still hasn't really clicked for me yet. That would make a nice tutorial video if it isn't already out there and I just missed it.
-
Memory manager just lets you pick which retentive ranges that you want to back up to the project file and restore to the PLC. You can view and edit the stored memory content. Nothing too complicated.
-
I have another "How should I" type question on this current project.
Many years ago, in BASIC (never learned C), I would have an If Else type structure that could have multiple results for the If and multiple results for the Else, and their variants.
IF this=893
do this, that and the other
ELSE
do a few other things instead
ENDIF
I had some places today where this would have been handy but I only have the one result per MATH box so I wound up just setting a flag to handle the results in other instructions.
Is there a cleaner way to deal with this?
Second question - I suppose nesting If's in that MATH box is the only way to test for x=y AND z=7? The question being the multiple conditionals. They're great, just harder to follow. I could not easily do them as "contact" conditionals due to a lot of indirect addressing - some multilayered with offsets such as D[V[V10]]==TRD[200+V10] - which don't all work outside of the MATH box. (HA! I'm learning! I caught the single "=" before posting. That has tripped me up quite a few times.)
-
Until we implement some variant of a textual scripting language, constructs like that will always remain a little awkward. Traditional PLC languages are great at certain things, not so good at others. So short answer: no magic bullet.
-
I have another "How should I" type question on this current project.
IF this=893
do this, that and the other
ELSE
do a few other things instead
ENDIF
I construct IF/THEN/ELSE constructs via ladder logic using the NOT contact. Basically, have all the input contacts driving a group of boxes for the IF portion, then put a NOT contact below the IF leg to drive a different set of boxes for the ELSE leg.
See the attached example. Note that C0 input logic can be as complex as it needs to be to drive the MOVE box, the NOT contact is just the "not" of all that input logic. Note also that the number of boxes being driven by each leg can be longer than 1 instruction for the IF part and the ELSE part.
-
I construct IF/THEN/ELSE constructs via ladder logic using the NOT contact.
That's pretty slick, I like that! :)
Also, if both the IF and the ELSE are computation of the same register using different rules, sometimes you can use the inline IF() in a MATH box.
-
That's pretty slick, I like that!
Yes! And it is a very recognizable pattern when you see it...
{blob o'logic}--+----------+-[BOX1]
| |
| +-[BOX2]
| |
| +-[BOX3]
|
+-|>O------+-[BOX4]
|
+-[BOX5]
|
+-[BOX6]
|
+-[BOX7]
-
I like that too and saw where plcnut on the ADC forum demonstrated that. My query was generated due to a MATH box construct required by the indirect referencing I needed for comparisons. And it also had nested IFs in place of the AND I needed.
-
I like that too and saw where plcnut on the ADC forum demonstrated that. My query was generated due to a MATH box construct required by the indirect referencing I needed for comparisons. And it also had nested IFs in place of the AND I needed.
You can do Boolean and, or, not:
&& || !
"(X0 && !X1) || X2"
-
I like that too and saw where plcnut on the ADC forum demonstrated that. My query was generated due to a MATH box construct required by the indirect referencing I needed for comparisons. And it also had nested IFs in place of the AND I needed.
You can do Boolean and, or, not:
&& || !
"(X0 && !X1) || X2"
Yes, but I can do all that on the left side of the rung where I can see what state they are in! ;)
Since I have involved conditionals that can't as yet be used directly in contacts, I was simply wondering whether I was missing some clean looking method of doing it in the MATH box. The MATH box is great, it is just not going to show the current state of conditionals, etc. as well. One of the boons of ladder over ST or whatever is that visual feedback.
-
One of the boons of ladder over ST or whatever is that visual feedback.
Graphical language > textual language
A picture is worth 1000 words!
-
Yes, but I can do all that on the left side of the rung where I can see what state they are in! ;)
One of our wishlist items is to add a status bar at the top of the view that would expand status on expressions. Another wishlist item is to expand expressions to virtually any input parameter...which is why we added the status bar idea. It's bad enough that we can't get status of math box contents, but imagine how much worse that becomes when you have small expressions scattered all over the logic!
-
Now that would be handy!
Rockwell's CPT (MATH) allows you to hover over a tagname and it will show the value in a small box, but only for the one you are hovering over. Good, but not great.
-
One of the boons of ladder over ST or whatever is that visual feedback.
Siemens' TIA Portal does a reasonable job of showing ST status. In status mode, there's a display off to the right of the ST code that shows IF() results, values of variables, etc.; it can even add additional lines to the display and space the ST lines when it needs to to have enough lines to show status. It's not quite as obvious as in ladder, but serviceable.
Can't remember what AB does for ST status, if anything. It's been about 4 years since I did any ST in AB. It's like a CPT box, IIRC. You can hover and get one value at a time. Pretty weak compared to the Siemens implementation if my recollection is correct.
-
I thought I would update this thread. I got to playing around with this project in the simulator and our test Do-more over the weekend. The machine is running well, only had a few bugs and feature requests. But one thing has bothered me for awhile.
The relatively quick table building, sorting, shifting, re-sorting, etc. works, but the task takes about 67 seconds or so to complete which far exceeds what I was seeing early on. So I have been looking at other sorting methods.
Well, when I stripped off all of the other code to look into optimizing it, the simulator was handling the task so quickly I thought I had broken the code. I then loaded it into the test PLC and that was completing in 13 seconds. So what I found is ... (yes, I should have found this sooner)
1) Default Yield every 100 micro-seconds in Program/Task Code-Block Configuration dialog is way, way too short when scan time is averaging 2.45 milli-seconds without the task running.
2) Changing the yield time in the above location DOES NOT DO ANYTHING UNTIL PROGRAM TO RUN TRANSITION. I discovered this when I stumbled across Timeslice and could monitor/change it. And gee, it does indeed mention both of these in the dialog. :-[
3) Stripped down code doesn't take 2.45 mS scan time, it's only 0.356 mS.
4) I added a program I can set the Timeslice on that simply Goto's a label in the previous rung. This allowed me to set an average scan time for testing. After this I changed values and recorded results and determined that my convoluted task actually requires about 2.8 seconds to run all by itself, exclusive of overhead. So I was able to confirm that a 2.4mS scan time and a MySortTask.Timeslice of 100 uS does indeed take about 68 seconds to complete. But! With a MySortTask.Timeslice of 2000 uS, it completes in about 6.2 seconds. And since a 4.5 mS scan time while this is running once in every so many shifts (for 6 seconds!) is no issue. Whoo Hoo! Now I just need to go put it in the actual machine sometime.
At 30,000 uS timeslice for the task, it completes in 3.0 seconds.
At 50,000 uS timeslice for the task, it completes in 2.9 seconds.
I will probably stick with 2000.
-
Now you know the power of Do-more .TimeSlice-ing!
You have complete control over scan time vs. calendar time for your looping algorithms like sorting. Just tweak the .TimeSlice member, just as you did.
The last thing I do is put a MOVE at the top of the task/program to set .TimeSlice in code. Then the rung comment documents what I tried and how I came up with THAT value in the Source of the MOVE. The configuration value is just to initialize it on PGM to RUN.