Counting consecutive bits in ladder logic (RSLogix 5000, CompactLogix)

Did you mean sifting Peter, or shifting ?
Shifting.

My FOR-NEXT solution executed in about 2.2mS, inspecting all 360 bits of a BOOL Array.
On a MicroLogix or a S7?

I tried a Brute-Force method, using similar counting principles, it executed in about 10mS, but it was only looking at the first 32 bits... multiply that by 11.25 to do 360 bits, and your scan goes through the roof at about 113mS !!
354 rungs each accessing at most 5 coils and one increment if all are true can't take that long. The trade off is that each coil is accessed 5 times but there is no loop over head.
 
On a MicroLogix or a S7?

This is on a ControlLogix L62


354 rungs each accessing at most 5 coils and one increment if all are true can't take that long. The trade off is that each coil is accessed 5 times but there is no loop over head.

The problem I faced with the brute-force suggested is that if you had a longer run of ON bits, you had to avoid counting more than one "group".

proof's method of detecting the start of a group overcomes that, means you have to index the bits, and four of the five involve a calculation (eg [Index+1], [Index+2] etc.

I will try brute-force again, this time using proff's detection method. I will post the results later.
 
Result : the "brute-force" method (peter_speed) wins hands-down !!

To be honest I didn't expect such a dramatic speed

2017-02-02_101413.jpg
 
Result : the "brute-force" method (peter_speed) wins hands-down !!

To be honest I didn't expect such a dramatic speed

Its like you said earlier. Additions take a lot of time. I wonder if accessing a bit in an array of bits take longer than accessing a bit in a DINT. Would peter_speed be any faster if you uses dints instead of an array of bits (or even an array of dints)? For example, using curtain_dint1.30 curtain_dint1.31, curtain_dint1.32, curtain_dint2.0, and curtain_dint2.0.
 
Optimizing the Peter_speed method slightly, replace the ADD instructions with CTUs and OTU Counter.CU.

Also, combine the logic as follows:

RES Counter

XIC myDINTs[0].3 BST XIC myDINTs[0].2 BST XIC myDINTs[0].1 BST XIC myDINTs[0].0 NXB XIC myDINTs[0].4 BND NXB XIC myDINTs[0].4 XIC myDINTs[0].5 BND NXB XIC myDINTs[0].4 XIC myDINTs[0].5 XIC myDINTs[0].6 BND CTU Counter 0 0 OTU Counter.CU

XIC myDINTs[0].7 BST XIC myDINTs[0].6 BST XIC myDINTs[0].5 BST XIO myDINTs[0].3 XIC myDINTs[0].4 NXB XIO myDINTs[0].4 XIC myDINTs[0].8 BND NXB XIO myDINTs[0].5 XIC myDINTs[0].8 XIC myDINTs[0].9 BND NXB XIO myDINTs[0].6 XIC myDINTs[0].8 XIC myDINTs[0].9 XIC myDINTs[0].10 BND CTU Counter ? ? OTU Counter.CU

XIC myDINTs[0].11 BST XIC myDINTs[0].10 BST XIC myDINTs[0].9 BST XIO myDINTs[0].7 XIC myDINTs[0].8 NXB XIO myDINTs[0].8 XIC myDINTs[0].12 BND NXB XIO myDINTs[0].9 XIC myDINTs[0].12 XIC myDINTs[0].13 BND NXB XIO myDINTs[0].10 XIC myDINTs[0].12 XIC myDINTs[0].13 XIC myDINTs[0].14 BND CTU Counter ? ? OTU Counter.CU



Continue on in that fashion until the last one.. note [11].7 is the 360th bit


XIC myDINTs[11].3 BST XIC myDINTs[11].2 BST XIC myDINTs[11].1 BST XIO myDINTs[10].31 XIC myDINTs[11].0 NXB XIO myDINTs[11].0 XIC myDINTs[11].4 BND NXB XIO myDINTs[11].1 XIC myDINTs[11].4 XIC myDINTs[11].5 BND NXB XIO myDINTs[11].2 XIC myDINTs[11].4 XIC myDINTs[11].5 XIC myDINTs[11].6 BND CTU Counter ? ? OTU Counter.CU

XIO myDINTs[11].3 XIC myDINTs[11].4 XIC myDINTs[11].5 XIC myDINTs[11].6 XIC myDINTs[11].7 CTU Counter ? ? OTU Counter.CU



Fast counter.jpg
 
Last edited:
This is on a ControlLogix L62

The problem I faced with the brute-force suggested is that if you had a longer run of ON bits, you had to avoid counting more than one "group".

proof's method of detecting the start of a group overcomes that, means you have to index the bits, and four of the five involve a calculation (eg [Index+1], [Index+2] etc.

I will try brute-force again, this time using proff's detection method. I will post the results later.


If you are trying to optimize, after the incrementing command, add a JMP instruction jump over the next 4 rungs. We know that if the test was true, the next 4 tests will fail, since the starting bit is on for these 4 tests. This will give varying time results, but the more sets that match, the faster the test will run.
 
If you are trying to optimize, after the incrementing command, add a JMP instruction jump over the next 4 rungs. We know that if the test was true, the next 4 tests will fail, since the starting bit is on for these 4 tests. This will give varying time results, but the more sets that match, the faster the test will run.

There are some clever ideas being suggested, I just wish the OP would step back in and tell us what scan time "hit" would be acceptable to him.

We don't know the application, it might be that once a "set" of four or more is detected, (curtain "not clear") then it doesn't matter about the rest of the array. Or it may be that he definitely needs to know how many obscurations there are (all parts in place). If it's the latter, I think he should be using an FBC instruction to compare against a "reference" array

I personally don't see any issues for a sub-10mS hit, so further optimisation may just be overkill, and added programming effort.

The "brute-force" method took a fair while to code, I simplified the process by creating an excel spreadsheet which "built" the ASCII text for the 356 rungs. Then I used Copy/Paste Special (Values) to overwrite the formulas, finally copy/pasting into notepad, from where I copy pasted the whole lot into the ASCII editor in RSLogix5000. For some reason it didn't go directly from excel, I didn't investigate why, I just knew that I could do it from notepad so went straight there.

To be honest, if sub-10mS is acceptable, I would use my method, just two rungs of code in the FOR routine, and a lot less programming effort !!

I'll convert peter's brute-force method to look at the original DINT array bits tomorrow and see if that has any effect on his winning time. I not expecting it to have much effect, but we'll see.

I'll also try AustralIan's code if I get time.
 
Last edited:
If you are trying to optimize, after the incrementing command, add a JMP instruction jump over the next 4 rungs. We know that if the test was true, the next 4 tests will fail, since the starting bit is on for these 4 tests. This will give varying time results, but the more sets that match, the faster the test will run.

A JMP instruction takes 10x the execution time to process than an XIO or XIC. So it may only be a marginal improvement.
 
A JMP instruction takes 10x the execution time to process than an XIO or XIC. So it may only be a marginal improvement.

I had a little more time available, so I looked up a few things. The execution time of an XIC or XIO is 4. The execution time of a JMP is 28 and a LBL is 16. So there are some cases where it would speed the single line check up, but many cases where it would slow things down. After looking at AustralIans example, it seems pretty obvious that is the better code.

I had always read that the DINTs was the native format, so I had assumed that doing things in Boolean arrays was the 'slow' way and using DINTs with ANDs and ORs, EQUs and the like would be the fast way. But these commands have an execution of 28 each. We can do a lot of XIC and XIOs for a couple of the DINT commands.

I couldn't find anything that talked about the whether using Booleans, Dints, or Arrays affected time. Made some sample code that had 100 lines that referenced 32 bits in each line. One used XIC BIT[0], one XIC DINT.1, and one with XIC DINTARRAY[1].1. They all executed at about the same time, so I don't supposed using Booleans or DINTS makes much difference. Then I tried using XIC bit. This code took 48 times as long to run as XIC bit[0]. This seems to indicate that unrolling a loop and doing it brute force with hard coded addresses is a much faster that using a loop and indexing.

One last thing. Using Excel is a often easier to modify and create code than the editor functions in RSLogix 5000, but for generating code like the in AustralIans example, using Bash Shell scripts is the way to go. A one line script will generate the code from rungs 3 on without having do copying, substituting and other hand editing. I recommend that all serious programmers learn bash, then grep, sed, and awk. These tools are very powerful and can speed up code development, and make sorting of data much easier. These are in the base install of the Cygwin.
 
My use of grep et al. is googling "I want to do x from a terminal". Definitely a skill I would like to perfect. I have started using git for version control and it is so much easier than keeping track of PLC_backup.acd, PLC_latest.acd, PLC_laterthanlate.acd, PLC_latest1.acd (timestamped 2007)
 
One last thing. Using Excel is a often easier to modify and create code than the editor functions in RSLogix 5000, but for generating code like the in AustralIans example, using Bash Shell scripts is the way to go.

+1 For excel, you can replicate a lot of code w/ "text-to-columns", "transpose" and "concatenate". VBA macros are helpful too as often times Excel documents accompany a project with programming information such as tags, descriptions, addressing so it's easy to use excel and VBA to knockout code generation.

I've use phyton as well for random things I might need. I'll have to take a look at your suggestions.
 

Similar Topics

Hi all I have a program that when a can is rejected from the machine this is put into a shift register, which is moved via a clock pulse on the...
Replies
12
Views
3,041
Hello I am looking for tips on how to count the duration of a given function and then how to display it on the hmi panel in the hh:mm:ss format...
Replies
4
Views
1,702
Guys, I know it will be silly but can't get my head around it. I have 3 conveyors, every one on a separate servo drive, and 2...
Replies
25
Views
3,501
The 1734-IB8 has no hardware counting function correct? I am trying to find something to substitute in for a 5069-IB16F (since lead times are...
Replies
3
Views
1,415
Been scratching my head at what I thought should be a relatively simple task. I need to count how many rows a .csv file has, so I can later read...
Replies
6
Views
2,542
Back
Top Bottom