Product Tracking Problem

PLC Pie Guy

Member
Join Date
Jun 2013
Location
Halifax
Posts
1,144
Hey Folks.

Using RSL5K on V21

I'm working on a little project here. Proving to be a bit of a challenge.
I have a production line that is an approx 3 hour trip for our product start to finish.
The line is broken into many sections. I want to track the product on our line and determine where and when the breaks in product occur. I want to be able to represent the time left until a break and the duration the break will be on the HMI screen.

What I have so far is a BSL instruction that is say 2016 bits long, or 63 DINT words.
This is to represent the entire length of one section of conveyor. I know the speed in feet per minute and there is a photoeye looking across the conveyor at the entry.

If the speed is 80 FPM, then my BSL will get fired every 1.3 Seconds and depending on the state of the photo eye, the BSL will carry the bits through to illustrate where on the belt the product is. This works very well for a visual on the HMI. However, I want to get the time between true bits (duration of break in product) and time until the next section of say 10 or more untrue bits. (Time until break in production)
I know that each bit represents 1 foot of conveyor and the FPM. So if I have 100 untrue bits coming through the BSL array in a row, I want to be able to say, that I have a 75 second gap coming in 10 minutes,, sort of thing.



Any thoughts on how I what the expression might look like that could pull that out of my BSL knowing what my conveyor speed is? The math makes sense to me, just how to examine a group of bits in a word and how many untrue bits between the groups is what Im struggling with.

Any advice would be appreciated.
 
One approach, which will take a relatively long time (i.e., 2016+ program scans), would be to (1) make a copy of the 63 DINTs, (2) bit shift that working copy once per scan, (3) count bit shifts within the 2016 range, (4) keep track of whether shifting true or untrue bits, (5) at a true/untrue transition, save the scan count in an array for true->untrue, (6) at an untrue/true transition, save the scan count in an array for untrue->true.

Once you have these two arrays of scan counts, which represent distance (based on how the bit array is described) from the beginning of the conveyor system, you can then calculate the location and size of gaps along the whole conveyor.

This is a somewhat "brute force" approach, relatively slow, and memory intensive. But not too hard to understand and may meet the requirements of HMI visualization.
 
I think Mispeld is close.
1 before shifting the working copy of 63 DINTS, copy them to a queue or ring buffer.

2. shift the bits in the working copy.

3. Now 'OR' the working copy and the copies in the queue together.
4. now search for a 0. If you found a 0 then you know there where 1 plus the number of copies in the queue 0s in a row.


There is no reason to search for edges. Yes, my method is very brutish.

Is it easy to scan for 0s? Is it easier to scan for 1?
Can an array of 63 DINTS be put in a queue?
 
Hey All.

So Iv been looking at the solutions given to me. I must say, its a little more than I understand.

(1) Making a copy of the 63 DINTS is not a problem, but do I make this copy every time the BSL gets enabled? I'm not clear on this.
Also, Peter suggested copy them to a queue or ring buffer. Care to elaborate? I'm not sure what this is asking for.


(2)Bit shift the copy once per scan. That is fine.

(3)Mispeld suggested to count bit shifts within the 2016 range. Wouldn't this be 2016 bit shifts?

(4)Keep track of shifting true or untrue bits. (5) and (6) count the true vs untrue bits. That makes sense but what bit am I going to examine for true or untrue.

Sorry for the questioning but this might be a little over me head. I'm just not seeing the end result.

I tried putting this into logic but I'm really unsure of when to make the COP of the 63 DINTS true.

Thanks to any willing to lend advice!
 
I will illustrate what I was trying to describe by example. In this approach, the result will indicate all conveyor gaps -- their size and distance from the the end of the conveyor. Since the problem description specifies the 2016 element bit-shift array (i.e., 63 element DINT array) is clock-shifted while the conveyor runs, and the conveyor speed is constant, the result will be expressed in bit counts, which can then be converted to time.

Consider a 20 element bit-shift array with the following values:

0 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0

Assume the left-most bit is the end of the conveyor and right-most is beginning.

The edge finding results after 20 bit-shifts will be in arrays:

Zeros[]: 0, 6, 9, 13, 19
Ones[]: 3, 8, 11, 18, size (20)

You can then use this pair of arrays to compute gap sizes and distance of gap to end as follows:

Gap[n] = Ones[n] - Zeros[n] = 3, 2, 2, 5, 1
Distance[n] = Zeros[n] = 0, 6, 9, 13, 19

So, for example, a 5-element gap is due to arrive in 13 elements. Elements are converted to time based on BSL clock rate and conveyor speed.

My suggestion for computing the Zeros[] and Ones[] array values assumes this process is not time critical, using 2016 scans to fill these arrays. At start of an update cycle, clear (FLL) the Zeros[] and Ones[] arrays, copy the actual conveyor state into a working array of 63 DINTS, initialize a Scan_Count to one, initialize Gap_Count to zero, and set a Zero/One flag to Zero. (To simplify the situation, always assume there is a one-element gap (zero) at the end, represented by Zeros[0] always equal to zero.)

While in the update cycle (e.g. 0 < Scan_Count < 2016) Do:

1. Is the working bit-shift end element 0 or 1?
1a. If 0 and "One Flag" set -> Store Scan_Count in Ones[Gap_Count], Set "Zero Flag", and Increment Gap_Count.
1b. If 1 and "Zero Flag" set -> Store Scan_Count in Zero[Gap_Count] and Set "One Flag"
2. (always) Increment Scan_Count
3. (always) BSL working bit-shift array

After Scan_Count >= 2106, if "Zero Flag" is set move 2016 into Ones[Gap_Count]

Following 2016 bit-shifts, the Ones[] and Zeros[] arrays will indicate edge locations, and gap information can be computed as described earlier. Worst-case, these edge locations will need to be 1008 element-arrays (i.e., if the working array alternates zeros and ones at each element). They can be reduced to the maximum number of products on the conveyor at any time. In any case it is advisable to limit-check the Gap_Count before using it as an array index.

You could do this 2016-step process one scan at a time, or all at once through a subroutine. It would also be possible to indirectly index through the 63 DINTs instead of bit-shifting the working array. There are also methods to keep track of the gaps as the conveyor state array is filled and shifted instead of repeatedly doing the 2016-step process. Of course, it is only necessary to trigger the 2016-step process when the conveyor state changes.
 
Last edited:
1) 80FPM = 1 pulse per 0.75seconds.

2) some pseudo code...

Code:
ONS(Encoder)

  /* stuff entering */
  If ProductSensor = 0
     Count = Count + 1
  Else
     If Count > Threshold
         CountFIFO.Load Count
         PosFIFO.Load Pos
     EndIf
     Count = 0
     Pos   = 2016
  EndIf

  /* stuff in the middle */
  For i = 0 to FIFO1.Pos 
     PosFIFO[i] = PosFIFO[i] - 1  //decerement all of the gap positions by 1
     TimeTo[i] = (PosFIFO[i] - CountFIFO[i]) / Speed
     DurationOf[i] = CountFIFO[i] / Speed
  EndFor

  /* stuff exiting */
  If Pos[0] <= 0     //If the gap has left the conveyors, delete it
     CountFIFO.Unload -> Nothing
     PosFIFO.Unload -> Nothing
  EndIf
  If (PosFIFO[0] - CountFIFO[0]) <= 0  //If the gap is starting to leave the conveyors, decrease its size
     CountFIFO[0] = CountFIFO[0]-1
  EndIf
EndONS
 
Since the array is rather large, you probably don't want to do counts on a bit by bit basis doing single bit shifts in a loop, as that would take a considerable amount of time. Since rslogix has limited higher math functions, I'd use an algorithm that counts the leading number of zeros in a word without loops, such as the example I got from Wikipedia:

function clz3(x)
if x = 0 return 32
n ← 0
if (x & 0xFFFF0000) = 0: n ← n + 16, x ← x << 16
if (x & 0xFF000000) = 0: n ← n + 8, x ← x << 8
if (x & 0xF0000000) = 0: n ← n + 4, x ← x << 4
if (x & 0xC0000000) = 0: n ← n + 2, x ← x << 2
if (x & 0x80000000) = 0: n ← n + 1
return n

Here's some psuedocode intended to count the number of bits to the first bit that is off, then counts to the number bits past that point that stay off. The difference is the gap. If the gap isn't big enough, the leading bits are masked and the process repeats looking for the next gap. LEADINGZEROMASK is an array that corresponds to words with the number of leading zero matching the index, the rest of the bits are ones.

I=0
LZ=0
A=Array
E=0
B = INVERT(A)
C=0
CHECK1:
B=B AND LEADINGZEROMASK[C]
C=CountLeadingZeros(B)
IF C==32 then LZ=LZ+32; I=I+1; A=Array; B=INVERT(A); goto Check1
H=I
J=C
Check2:
D=A AND LEADINGZEROMASK[J]
F=0
E=CountLeadingZeros(D)
IF E==32 then F=F+32; H=H+1; A=Array[H]; goto Check2
G=F+E-LZ-C
if (G<10) AND (LZ+C < 55) goto Check1
 
Consider a 20 element bit-shift array with the following values:
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0

Assume the left-most bit is the end of the conveyor and right-most is beginning.

The edge finding results after 20 bit-shifts will be in arrays:

Zeros[]: 0, 6, 9, 13, 19
Ones[]: 3, 8, 11, 18, size (20)


OK, I'm going to study this solution and give it a shot. I will likely have more questions, However. I'm a little confused with this... Above, you said bit 0 is an edge, I agree, you said 6 is an edge, it is a trailing edge. then you said 9, it is a leading edge. You said 13, it is a trialing edge and 19, is also a trailing edge. Maybe I'm wrong but wouldn't it be, 0,6,10,13 and 19 all as trialing edges.

Likewise, you said for ones... 3,8,11, and 18.. I see 1,8,11 and 16 as trialing edge ones.

Am I looking at this wrong, as bits 3 and 18 are actually 0 not 1 in my brain? That's not saying much but I'm wondering where I'm miss interpreting this section of bits. I see it as right being bit 0 and left being bit 19.

Thank you immensely for the help with this. It seems like a tough piece of code to get my head around for some reason.
 
...but I'm wondering where I'm miss interpreting this section of bits. I see it as right being bit 0 and left being bit 19.

Yes, that is my bad. In the example I wrote the bits in the reverse order of how they are normally shown (i.e., I wrote them LSB to MSB instead of MSB to LSB).

This is a better illustration, with bits shifting in from the right, the beginning of the conveyor, using the BSL instruction:

1 1 1 1 1 1 1 1 1 1
9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

0 1 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0

Edge Arrays:

Zeros[]: 0, 6, 9, 13, 19
Ones[]: 3, 8, 11, 18, size (20)

In your case this bit array will not stop at 19, but continue to 2015 across 63 DINTs. I hope this is less confusing.
 
Yes, that is my bad. In the example I wrote the bits in the reverse order of how they are normally shown (i.e., I wrote them LSB to MSB instead of MSB to LSB).

This is a better illustration, with bits shifting in from the right, the beginning of the conveyor, using the BSL instruction:

1 1 1 1 1 1 1 1 1 1
9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

0 1 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0


Edge Arrays:

Zeros[]: 0, 6, 9, 13, 19
Ones[]: 3, 8, 11, 18, size (20)

In your case this bit array will not stop at 19, but continue to 2015 across 63 DINTs. I hope this is less confusing.

No, sorry, the Edge Arrays become:

Zeros[]: 0, 2, 9, 12, 16
Ones[]: 1, 7, 11, 14, size (20)

These numbers are offsets from the MSB of the 20-bit, bit-shift array. They are not bit positions.
This is important because your view of edges is from the end of the conveyor, which makes the gap/distance math convenient.

To be clear, where the following says "working bit-shift end element" it means the MSB of DINT[63] of the bit shift array (i.e., the end of the conveyor).

While in the update cycle (e.g. 0 < Scan_Count < 2016) Do:

1. Is the working bit-shift end element 0 or 1?

Gee, I hope this is the last correction.
 
The attached files show a Logix Ladder implementation of the bit shifting algorithm I attempted to describe earlier. There tends to be "gotchas" when translating an idea into a running program. In this case, the most trouble was caused by the BSL being a transitional instruction, meaning it needs to see a false-to-true transition to execute. I took the approach to toggle on every other scan which doubles overall time (e.g., 4000 scans instead of 2000). There are other ways to deal with the transition problem, such as using LBL/JMP that avoid the doubled scan.

This example only uses a 2-DINT bit shift array (64 bits), but can be easily extended. The test case results are based on the end-of-conveyor view (the Most Significant Bit of the shift array), which assumes the start of the conveyor is represented by the LSB.

Breaking into multiple jpegs was not my first choice in attempting to post this.

Gap1of4.jpg Gap2of4.jpg Gap3of4.jpg Gap4of4.jpg GapTestCase1.jpg
 
Run a RTO Timer. Use shift bit location to Capture RTO ACC and reset RTO. This will tell you how big the Time gap is between products. If Time Gap is greater than Alarm Value Then Alarm output.

Rung 1. RTO
Rung 2. XIC Shift Bit Location, MOV RTO.ACC to Time Gap and (RES) RTO.
Rung 3. GRT RTO.ACC 1000 DIV Time Gap, 1000 = Time Gap Seconds.
Rung 4. GRT Time Gap Seconds, Time Gap Alarm Value then OTL Alarm Output
Rung 5. XIC Shift Bit Location OTU Alarm Output.
 
...There are other ways to deal with the transition problem, such as using LBL/JMP that avoid the doubled scan.

Follow-up: Since the code does not use state information from the BSL control word (e.g., .DN, .POS), the technique of preceding the BSL with a reset (RES) is effective in addressing the transition requirement. This has the benefit of eliminating the Scan Count, halving the required scans, and simplifying the code.
 
Good Morning.

I want to say thank you to Mispeld and others that contributed to my post.
I am still working on this. However, due to holiday scheduling and machine installs, among trying to use up vacation time, I haven't had a lot of desk time the last week or so.
I plan getting right back on this problem in the New Year if not over Xmas if I get some free time from the little ones and all the holiday madness.

I just wanted to let you know that I have read everything you posted as well as printed off the samples you posted. It really looks complicated but I'm confident that I will understand it once I get to play with it on my test bench.

Again, I wanted to recognize the effort you put into this solution Mispled. Thank you!!!
 
You're welcome, I appreciate the feedback.

The attached PDF files have the simplified version described in my last follow-up (using (RES) to force BSL on every scan). This is the preferred approach.

One other thing I will point out is that the bit shift instructions do not require an overall length equal to a multiple of 32; any in-range value can be specified for the BSL Length. You will replace the 64 Length with 2016, based on the original project description, and size the Ones[], Zeros[], and Gaps[] arrays as the maximum number of gaps on the conveyor at any time (1008 to be absolutely safe). Set the MaxGap (constant) tag equal to this array size.
 

Similar Topics

Scenario: Two different cutting machines drills material and put that on two different stock piles. The stock piles can have more than one cut...
Replies
2
Views
1,428
Product tracking based on time and position. I'll be using a 1769-L16ER-BB1B processor. There will also be an HMI involved, but it will be for...
Replies
24
Views
18,205
I'm a newbie to tracking concept. I have assigned a project to handle product tracking. Product should be delivered to destination without any...
Replies
10
Views
9,762
Guys I have a monoblock that tracks a bottle through the machine using shift registers and an encoder. We typically have a reject system on the...
Replies
14
Views
3,390
Gents: I have an application coming up that I would like to get some opinions on. I have a conveyor that will be running 100FPM that I will need...
Replies
14
Views
6,089
Back
Top Bottom