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

dweisser

Member
Join Date
Jul 2015
Location
pittsburgh
Posts
5
Hello,

I am in need of a solution to a problem I've failed to come up with a solution to that doesn't take entirely too long for my needs.

I have a light curtain with 360 points, what I want to do is count the number of objects which take up at least (x) number of said points, and not count anything smaller then that, and get a total number of objects passing through simultaneously.

If I were writing it as a while loop it'd be relatively simple, but I don't have the ability to do that without an additional software package.

Relying on each scan to implement a pseudo-while loop would result in 360 scans before completion, which could be up to a few seconds.

What I need to do is check each of the 360 bits, and see how many consecutive bits are TRUE, and then count each one above a certain threshold. A photoeye is triggered to take the snapshot of the state when I want to count.

For example, if the bit pattern looked like this, 0100 1001 0111 1 0001 1111 0001 1111 0010(completely made up), and my threshold were 4, I would want my result to be 3. Because 3 times in that made up word, were 4 bits in a row "true". With a small word like this, it's easy to do brute forced, but scaling it up to 360 bits ( about 22 and a half words), brute forcing this could get extremely ugly, especially considering you'd need to account for words overlapping (ie, word 1 ends in 0001, word two begins with 1110, that should count as 1)

I'm racking my brain here and feel like I'm missing something obvious
 
You need to count the number of "011"s. Add one if it starts with "11"
Either in structured text..

for i = 0 to 357
Etc

Or in ladder..

copy array to bool array bits[360].
Count = bits[0] & bits[1]
FAL FAL01
..LENGTH = 358
..POS = 0
..Method = All
..Dest = Count
..Source = Count + ( NOT bits[FAL01.POS] & bits[FAL01.POS + 1] & bits[FAL01.POS+2])
 
Read this thread: http://www.plctalk.net/qanda/showthread.php?t=70858

Pay attention to the Bits Hacks.

That's the thread I tried to search for, I remember reading it, but couldn't remember who suggested the Bit Hack method.

But unfortunately, this method will only count the total number of bits on, not tell you how many times in the 360 bits that you have 4 or more on consecutively.

You have a photocell to trigger the counting, and I'm thinking an AOI that can be executed by the photocell would be the best solution.

Obviously the computation in the AOI would induce a "hit" on the program scan it is triggered in, but I don't believe that would be a problem.

How are your 360 bits stored ? in a BOOL array, or a DINT array ?
 
Here's a solution that executes on a BOOL Array of 360 (384) bits, and it executes completely in less than 2.5 mS

I think it does what you described, counting how many occurences there are of 4 or more bits in the array.

Your biggest "problem" is getting the data into the BOOL array in the first place. If the bits are from input modules, then you need to copy the 32-bit words into the array, and that is not easy.... BOOL Arrays are completely unfriendly.

However, if you put your BOOL Array into a UDT, then you can COP (or CPS) a DINT array into it.... You'll need to modify tagnames and data structures to suit if you go this way.

The file i've attached is ControlLogix Version 20, and tested - if you need conversion, just ask
 
Last edited:
I have no idea whether or not this will help but maybe it can jog something loose. It occurred to me that this could be viewed as a pattern matching problem so: Boyer-Moore pattern match.

Good luck.

I don't think so
... I don't think there's any "pattern" involved, the OP just wants to know how many occurrences of a "light-curtain" are greater than 3. Can't envisage the situation where that would be useful, but that's what he asked for.

The solution I posted delivers what the OP wanted, but now I'm hoping there's no safety issues, then it's a whole new ball-game !!
 
Is brute force an option? 360-4 rungs?

I can think of other ways where the array of 360 bits is shifted once then ANDed with the original then shift again then ANDed with the original then yet again. After 3 shifts and ANDs only 1 bit will be left for a sequence of 4 bits being but there could be 2 bit left if there is a sequence of 5 bits on so shift one more time, invert then AND again. This will leave one 1 bit left no matter how many bits were set in a row.

I think the 360-4 rung brute force approach may be faster than sifting an array of 360 bits 4 times.
 
Is brute force an option? 360-4 rungs?

I can think of other ways where the array of 360 bits is shifted once then ANDed with the original then shift again then ANDed with the original then yet again. After 3 shifts and ANDs only 1 bit will be left for a sequence of 4 bits being but there could be 2 bit left if there is a sequence of 5 bits on so shift one more time, invert then AND again. This will leave one 1 bit left no matter how many bits were set in a row.

I think the 360-4 rung brute force approach may be faster than sifting an array of 360 bits 4 times.

Did you mean sifting Peter, or shifting ?


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

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 !!
 
dweisser, what model of CompactLogix have you got ?

It may be faster than my ControlLogix L62...
 
You need to count the number of "011"s. Add one if it starts with "11"

I think this is a good idea, but you need to look for 01111 to find 4 in a row.
I don't have time to write and test the code, but you might try something along the lines of

count=0
For I = 0 to 355 (where C[0] is always 0 and your array starts in C[1]
XIC C XIC C[I+1] XIC C[I+2] XIC C[I+3] XIC C[I+4] ADD count 1 count
next I
 
I think this is a good idea, but you need to look for 01111 to find 4 in a row.
I don't have time to write and test the code, but you might try something along the lines of

count=0
For I = 0 to 355 (where C[0] is always 0 and your array starts in C[1]
XIC C XIC C[I+1] XIC C[I+2] XIC C[I+3] XIC C[I+4] ADD count 1 count
next I


That won't work... if you had 6 bits on consecutively, you would get a count of 3. That's not what the OP wants...
 

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,035
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,698
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,496
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,408
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,537
Back
Top Bottom