Sign in to follow this  
Followers 0
Bill Linne

Copying And/or Averaging Counter Accumulator Values

14 posts in this topic

Okay, I'm probably overlooking something obvious, but for the life of me I'm unable to successfully manipulate a contiguous group of C-5 accumulator addresses. Seems simple enough. I want to add the values in the accumulators of C5:0 through C5:29, then divide the result by 30. Everything I try returns an error message that, in typical Rockwell fashion, tells me little more than "You can't do that, stupid!". Any and all help will be greatly appreciated! Bill

Share this post


Link to post
Share on other sites
here are a couple of ideas ... the FOR/NEXT method in Ladder File #4 is more "elegant" ... but the BRUTE FORCE method in Ladder File #3 is a lot easier for most people to understand ... plus it will execute faster too ... and incidentally ... your problem with this statement is that the accumulators are NOT actually contiguous ... each counter takes up three memory words ... therefore the thirty "accumulator" words are separated from each other by the other two words of each counter ... that's why you need to store the accumulators in a contiguous buffer (such as N15:0 through N15:29) before you do the next step ... CTUAVE.pdf CTUAVE.zip Edited by Ron Beaufort

Share this post


Link to post
Share on other sites
I looked into tackling this in one rung and came up with the following logic. After trying it, it will only copy C5:0.acc to N7:0. This is puzzling to me why the rest will not copy to N7. Anyone have any ideas?? See Atached

Share this post


Link to post
Share on other sites
when the rung executes, the POS of the AVErage function runs all the way from 0 through 29 !-BEFORE-! the MOVe gets a crack at the data ... that's the "short story" ... do you need more detail? ... Edited by Ron Beaufort

Share this post


Link to post
Share on other sites
Thanks, Ron. I just wanted to be sure I wasn't missing something with a FAL or other file mainipulation instruction. A useful modification to the Counters would be the ability to specify the address of the accumulator, so one could MAKE them contiguous. Thanks again! Bill

Share this post


Link to post
Share on other sites
That is what I was thinking, but what I found interesting is that when you execute the code you can see the number change in the mov instruction, but I assume the MOV instruction is just not processing all the data?? It all just seems a little strange, is it a scan issue?? using the enable bit you would think it would step only one pos at a time??

Share this post


Link to post
Share on other sites
You may want to consider just writing out 29 seperate rungs since it would be a bit easier to follow and save the time penalties of using subroutines or the for next loop. If the sum would cause overflow error consider using long or doing the division first and storing the running total in a float (if availiable).

Share this post


Link to post
Share on other sites
from hakko808: I’m afraid I’ll have to respectfully disagree on that one ... without using something like the “conditional subroutine jump” approach, the processor would be forced to either: (a) execute the “store-and-average” rungs as “true” on each scan ... or ... (b) execute those rungs as “false” on each scan ... either way would waste substantially more time than the simple “just-go-to-this-subroutine-whenever-we-need-to-do-the-operation” approach ... and thanks for bringing up these particular topics for conversation ...

Share this post


Link to post
Share on other sites
Here is another alternative. The PLC5/20E is an enhanced processor that supports structured text. The advantage of structured text for this particular operation is that you can skip all of the intermeidate result memory storage operations. This still uses a brute force computation rather than a loop, but only one memory storage operation is required at the completion of the computation. (This is a pretty long line for ST - but it did verify so I'm assuming it will work). See the attached. For those who don't have Logix 5: Ladder 2 contains a single rung: JSR 3. Subroutine 3 is an ST routine that contains a single line: F8:0 := (C5:0.ACC + C5:1.ACC + ....... C5:29.ACC) / 30.0; AVERAGE_COUNTERS.zip

Share this post


Link to post
Share on other sites
I would try using the Compute (CPT) instruction if you want to stay away from indirect adressing, looping, etc. You may be able to fit all 30 accumulators in 3-4 CPT instructions, which has an 80 characters limit in the expression field. Note you do need an enhanced PLC5.

Share this post


Link to post
Share on other sites
the ACC can be addressed contiguously. as a case in point C5:[N7:0].ACC will allow you to use a single variable in a loop and address each of the counter data. N7:0 is incremented by ONE for the next counter, not Three. Yes, there are three words associated with each counter, but AB does not need you to address them in groups of three as per Modicon or GE. A simple FOR/NEXT loop, or a simple counter that increments on each scan up to thirty would allow you to add all the ACC's together. Don't forget to use an F register or you might overflow the integer register. I have attached a PLC5/20E program for the FOR/NEXT and Counter methods. Bob TEST.zip Edited by rswolff

Share this post


Link to post
Share on other sites
In a PLC a summing loop is very heavy on overhead. The PLC-5 has a For-Next instruction - no need to build your own. See Ron's excellent example. The PLC-5 also has an AVE instruciton - however it requires contiguous file memory, that is memory arranged with all of the values to be summed in consecutive words without any words in between. This is what is meant by contiguous memory. Maybe its just the C programmer in me speaking but I believe that is how most programmers would interpret "contiguous" Indirect addressing in a loop would require: -150 memory read operations. -63 memory write operations. -30 memory offset calculations. Every intermediate result is stored out to memory, then retrieved again from memory. Imagine adding 30 marbles to a bowl one at a time, but between each marble you have to put the bowl back in the cupboard, close the cupboard, then open the cupboard, take the bowl back out. Use of direct addressing without a loop in ladder requires: -60 memory reads -31 memory writes. Use of direct addressing in ST will require: -30 memory read operations. -1 memory write operation. Summing continues in the CPU's internal registers - there is no need to store an intermediate result. That said, I have programmed many many loops. They can save the programmer a lot of work. I think a programmer should just be clear on what he is adding in terms of overhead. If using a loop I have one suggestion - its a minor change, but it shortens the loop slightly and saves a few memory read/writes as well as one less indirection. See rung 1 of the attahced PDF where the sum in intitialized with the first counter value instead of 0, and the loop starts a 1 instead of 0. (I converted it to PDF so those without Logix5 can see the file) TEST.pdf Edited by Alaric

Share this post


Link to post
Share on other sites
change is very good....I agree using indirect has overhead requirements....however this is a relatively small loop (30 iterations) but the application should be the deciding factor. And yes, the PLC5 has a FOR/NEXT which would be a better choice. I normally show as my own loop in case this needs to be applied to something else besides an AB (even though this is an AB forum). Lots of programmers get used to using specific instructions that are specific for a single processor type. When they are faced with moving to something else, they flounder, as they do not have the basic understanding of the underlying coding...only the specific instruction....lots of other processors do not have a FOR/NEXT but support program jumps.

Share this post


Link to post
Share on other sites
You bring up a good point on the subroutines. I was assuming that the object was to keep the average of the accumulators availiable at all times rather than just occasionally. I guess it would depend on the specifics of the application which were not included in the original description. I tend to avoid subroutines when possible since the overhead consumes scan time. The marble example seems close to what I am referring to. Subroutines have their place, but I have seen programs where they seem overused.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0