BSL array

hauck7

Member
Join Date
Apr 2014
Location
MSP
Posts
4
Hey guys,
I have a question on a cycle tracking array I'm trying to set up.
I need to have a floating good/bad ratio on the last 100 processes.
I was looking at using a BSL instruction over 4 DINTs. That works fine. But I need to go back and look at the bit level and calculate how many of the 100 bits are 1's and how many are 0's. The only way I can think of is to set up a long calculation in structured text but that feels like the hard way.
Any suggestions on the easy way?
 
I hope you understand me

Hauck:
Please see attached figure.
This is FOR instruction, in my case my routine is called Pesaje_Codigo (spanish name, I live in colombia). your index must be 0-31 because we're going to check DINts, 32 bits.
Inside that routine you are going to compare separatedly the four DINTs 32 times 4 = 128 bits you said you have 100 bits.
Basically what your are going to do is compare 32 bits bit by bit, that's the reason for the index.
Index is the position of a dint array:
[0]=00000000000000000000000000000000
[3]=00000000000000000000000000001000 and so on.
Whenever you found a match, [for example: there is a 1 on position 7(index=7) you increase a counter, you must have 4 counters (accumulator max 32)] at the end of the index you have checked 32 bits of all four words.
then you have to add accumulator of the four counter and you have numbers of 1 bits found in all the 4 four words.
 
I was looking at using a BSL instruction over 4 DINTs. That works fine.
If you already have the BSL working (I hope by moving the real data to a temporary work area), then most of the work is done. Simply trigger the BSL 100 times, and count the 1 bits coming out at the last bit in the BSL 4-DINT range (Bit 3 of the 4th DINT). To count that bit, simply use a XIC for the address of Bit 3 of the 4th DINT to trigger an Up Counter.

You will need to do the 100 shifts for each time that you want to calculate the good/bad ratio. Divide the Counter ACC value by 100 to get the good/bad ratio, then reset the counter and reload the BSL to get ready for the next calculation.
 
Last edited:
You can try this. I wrote this code using RSlogix 5000's structured text program. The code simply iterates through the DINT tag 4 times and when done will compute the ratio of Good which are bits that are 1 vs Bad which are bits that are zero.



//First Iteration
IF NOT First_Iteration THEN
i := 0; //Initialize i so we always start counting from 0
FOR i:=0 TO 31 BY 1 //This FOR Loops lets you index i that way we can check each bit from 0...31 if they are Good = 1 or Bad = 0
DO
IF DINT_Tag. THEN //Check for Good bit
Accumulator1 := Accumulator1 + 1;

ELSE IF NOT DINT_Tag. THEN //Check for Bad Bit
Accumulator5 := Accumulator5 + 1;
END_IF;

IF i = 31 THEN //When we have reached the highest index exit the loop and start the Second iteration
First_Iteration := 1;
EXIT;
END_IF;

END_FOR;



//Second Iteration
IF NOT Second_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF DINT_Tag. THEN
Accumulator2 := Accumulator2 + 1;

ELSE IF NOT DINT_Tag. THEN
Accumulator6 := Accumulator6 + 1;
END_IF;

IF i = 31 THEN
Second_Iteration := 1;
EXIT;
END_IF;

END_FOR;



//Third Iteration
IF NOT Third_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF DINT_Tag. THEN
Accumulator3 := Accumulator3 + 1;

ELSE IF NOT DINT_Tag. THEN
Accumulator7 := Accumulator7 + 1;
END_IF;

IF i = 31 THEN
Third_Iteration := 1;
EXIT;
END_IF;

END_FOR;



//Fourth Iteration, we do it Four times becasue you want to get the ration of Good Vs Bad for a hundred bits, Four iterations is equal to 32*4 = 128
//We check 128 bits because 32*3 = 96 which wont meet our minimum requirement of 100 bits.
IF NOT Fourth_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF DINT_Tag. THEN
Accumulator4 := Accumulator4 + 1;

ELSE IF NOT DINT_Tag. THEN
Accumulator8 := Accumulator8 + 1;
END_IF;

IF i = 31 THEN
Fourth_Iteration := 1;
EXIT;
END_IF;

END_FOR;


//Once we are done iterating though all the iterations lets start adding all the Good bits and Bad bits then take the ratio
IF ((First_Iteration) AND (Second_Iteration) AND (Third_Iteration) AND (Fourth_Iteration)) THEN
Total_Bits_That_Are_1_Good := Accumulator1 + Accumulator2 + Accumulator3 + Accumulator4;
Total_Bits_That_Are_0_Bad := Accumulator5 + Accumulator6 + Accumulator6 + Accumulator8;
END_IF;

//When we take the ration (Good/Bad) we want to make sure we don't divide by zero, so we first check and see if the Bad bits have an accumilator
//value greater than 1 before we start to take the ratio.
IF (Total_Bits_That_Are_0_Bad > 0) AND (NOT Ratio_Has_Been_Calculated) THEN
Ratio_Good_Vs_Bad := ((Total_Bits_That_Are_1_Good)/(Total_Bits_That_Are_0_Bad));
END_IF;
 
Last edited:
Hey guys,
I have a question on a cycle tracking array I'm trying to set up.
I need to have a floating good/bad ratio on the last 100 processes.
I was looking at using a BSL instruction over 4 DINTs. That works fine. But I need to go back and look at the bit level and calculate how many of the 100 bits are 1's and how many are 0's. The only way I can think of is to set up a long calculation in structured text but that feels like the hard way.
Any suggestions on the easy way?


Keep track as you fill up the BSL.

When you start, every good part you increment a good part register. Every bad part you increment a bad part register. You are also loading the BSL.

Eventually you have, say, 90 in the "good" register and 10 in the "bad" regsiter.

When you get to 100, you examine the bit that is going to be "thrown away" when it comes off the BSL. If the bit coming off represents a good, you subtract one from the good register. If the bit coming off represents a bad, you subtract one from the bad register. Now your two registers add to 99 instead of 100.

But, now you look at the incoming result. It goes onto the end of the stack which is now back at 100. And, it increments the "good" count if it is a good process, or it increments the "bad" count if it's a bad process. Now, the "good" plus "bad" equals 100 again and you're done.

You are simply keeping a running average of your last 100 trials. Well, not really an average but it's the same method. Pretty straightforward, and you don't have to "evaluate" the BSL words with any other logic as you do the evaluation every time you update the BSL itself.
 
Last edited:
Pretty straightforward, and you don't have to "evaluate" the BSL words with any other logic as you do the evaluation every time you update the BSL itself.
I think this is the best proposed plan, so far.
 
Thanks for all the replies. I didn't realize I had more than the first one. I got the machine installed at the customers today so I have to get this working tomorrow. I'll reread the different methods you guys mentioned and roll with it. I'll let you know how it goes. Thanks again.
 
Here is the code that I ended up using.
Thanks to dbh6 for coming up with it.
I modified it a little bit at the end to get the data into the format I was looking for.

Thanks for the help and getting me pointed in the right direction. This was definitely much easier than the way I was going to take it.

Code:
//Zero out old counts and reset Iterations
Accumulator1 := 0;
Accumulator2 := 0;
Accumulator3 := 0;
Accumulator4 := 0;
Accumulator5 := 0;
Accumulator6 := 0;
Accumulator7 := 0;
Accumulator8 := 0;
First_Iteration := 0;
Second_Iteration := 0;
Third_Iteration := 0;
Fourth_Iteration := 0;

//First Iteration
IF NOT First_Iteration THEN
i := 0; //Initialize i so we always start counting from 0
FOR i:=0 TO 31 BY 1 //This FOR Loops lets you index i that way we can check each bit from 0...31 if they are Good = 1 or Bad = 0
DO
	IF Station_1.FIFO.FIFO_Data5[0].[i] THEN //Check for Good bit
	Accumulator1 := Accumulator1 + 1;

	ELSIF Station_1.FIFO.FIFO_Data5[0].[i] THEN //Check for Bad Bit
	Accumulator5 := Accumulator5 + 1; 
	END_IF;

	IF i = 31 THEN //When we have reached the highest index exit the loop and start the Second iteration
	First_Iteration := 1;
	EXIT;
	END_IF;

END_FOR;
END_IF;


//Second Iteration
IF NOT Second_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF Station_1.FIFO.FIFO_Data5[1].[i] THEN
Accumulator2 := Accumulator2 + 1;

ELSIF NOT Station_1.FIFO.FIFO_Data5[0].[i] THEN
Accumulator6 := Accumulator6 + 1; 
END_IF;

IF i = 31 THEN 
Second_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;


//Third Iteration
IF NOT Third_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF Station_1.FIFO.FIFO_Data5[2].[i] THEN
Accumulator3 := Accumulator3 + 1;

ELSIF NOT Station_1.FIFO.FIFO_Data5[0].[i] THEN
Accumulator7 := Accumulator7 + 1; 
END_IF;

IF i = 31 THEN 
Third_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;


//Fourth Iteration, we do it Four times becasue you want to get the ration of Good Vs Bad for a hundred bits, Four iterations is equal to 32*4 = 128
//We check 128 bits because 32*3 = 96 which wont meet our minimum requirement of 100 bits.
IF NOT Fourth_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF Station_1.FIFO.FIFO_Data5[3].[i] THEN
Accumulator4 := Accumulator4 + 1;

ELSIF NOT Station_1.FIFO.FIFO_Data5[0].[i] THEN
Accumulator8 := Accumulator8 + 1; 
END_IF;

IF i = 31 THEN 
Fourth_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;

//Once we are done iterating though all the iterations lets start adding all the Good bits and Bad bits then take the ratio
IF ((First_Iteration) AND (Second_Iteration) AND (Third_Iteration) AND (Fourth_Iteration)) THEN
Total_Bits_That_Are_1_Good := Accumulator1 + Accumulator2 + Accumulator3 + Accumulator4;
Total_Bits_That_Are_0_Bad := Accumulator5 + Accumulator6 + Accumulator6 + Accumulator8;
END_IF;

//When we take the ration (Good/Bad) we want to make sure we don't divide by zero, so we first check and see if the Bad bits have an accumilator
//value greater than 1 before we start to take the ratio.
IF ((First_Iteration) AND (Second_Iteration) AND (Third_Iteration) AND (Fourth_Iteration)) THEN
	IF Total_Bits_That_Are_1_Good <> 0 THEN 
		IF Station_1.Integers[35]<100 THEN
			Station_1.HMI.Real[29] := (Total_Bits_That_Are_1_Good / Station_1.Integers[35]) * 100;
		ELSE
			Station_1.HMI.Real[29] := (Total_Bits_That_Are_1_Good / 100) * 100;
		END_IF;
	ELSIF Total_Bits_That_Are_1_Good = 0 THEN 
		Station_1.HMI.Real[29] := 0;
	END_IF;
END_IF;
 
@ hauck7 i noticed a typo on my end, i have highlighted what you need to change in bold letters

//Zero out old counts and reset Iterations
Accumulator1 := 0;
Accumulator2 := 0;
Accumulator3 := 0;
Accumulator4 := 0;
Accumulator5 := 0;
Accumulator6 := 0;
Accumulator7 := 0;
Accumulator8 := 0;
First_Iteration := 0;
Second_Iteration := 0;
Third_Iteration := 0;
Fourth_Iteration := 0;

//First Iteration
IF NOT First_Iteration THEN
i := 0; //Initialize i so we always start counting from 0
FOR i:=0 TO 31 BY 1 //This FOR Loops lets you index i that way we can check each bit from 0...31 if they are Good = 1 or Bad = 0
DO
IF Station_1.FIFO.FIFO_Data5[0]. THEN //Check for Good bit
Accumulator1 := Accumulator1 + 1;

ELSIF Station_1.FIFO.FIFO_Data5[0]. THEN //Check for Bad Bit
Accumulator5 := Accumulator5 + 1;
END_IF;

IF i = 31 THEN //When we have reached the highest index exit the loop and start the Second iteration
First_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;


//Second Iteration
IF NOT Second_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF Station_1.FIFO.FIFO_Data5[1]. THEN
Accumulator2 := Accumulator2 + 1;

ELSIF NOT Station_1.FIFO.FIFO_Data5[0]. THEN
Accumulator6 := Accumulator6 + 1;
END_IF;

IF i = 31 THEN
Second_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;


//Third Iteration
IF NOT Third_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF Station_1.FIFO.FIFO_Data5[2]. THEN
Accumulator3 := Accumulator3 + 1;

ELSIF NOT Station_1.FIFO.FIFO_Data5[0]. THEN
Accumulator7 := Accumulator7 + 1;
END_IF;

IF i = 31 THEN
Third_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;


//Fourth Iteration, we do it Four times becasue you want to get the ration of Good Vs Bad for a hundred bits, Four iterations is equal to 32*4 = 128
//We check 128 bits because 32*3 = 96 which wont meet our minimum requirement of 100 bits.
IF NOT Fourth_Iteration THEN

i := 0;
FOR i:=0 TO 31 BY 1
DO
IF Station_1.FIFO.FIFO_Data5[3]. THEN
Accumulator4 := Accumulator4 + 1;

ELSIF NOT Station_1.FIFO.FIFO_Data5[0]. THEN
Accumulator8 := Accumulator8 + 1;
END_IF;

IF i = 31 THEN
Fourth_Iteration := 1;
EXIT;
END_IF;

END_FOR;
END_IF;

//Once we are done iterating though all the iterations lets start adding all the Good bits and Bad bits then take the ratio
IF ((First_Iteration) AND (Second_Iteration) AND (Third_Iteration) AND (Fourth_Iteration)) THEN
Total_Bits_That_Are_1_Good := Accumulator1 + Accumulator2 + Accumulator3 + Accumulator4;
Total_Bits_That_Are_0_Bad := Accumulator5 + Accumulator6 + Accumulator7 + Accumulator8;
END_IF;

//When we take the ration (Good/Bad) we want to make sure we don't divide by zero, so we first check and see if the Bad bits have an accumilator
//value greater than 1 before we start to take the ratio.
IF ((First_Iteration) AND (Second_Iteration) AND (Third_Iteration) AND (Fourth_Iteration)) THEN
IF Total_Bits_That_Are_1_Good <> 0 THEN
IF Station_1.Integers[35]<100 THEN
Station_1.HMI.Real[29] := (Total_Bits_That_Are_1_Good / Station_1.Integers[35]) * 100;
ELSE
Station_1.HMI.Real[29] := (Total_Bits_That_Are_1_Good / 100) * 100;
END_IF;
ELSIF Total_Bits_That_Are_1_Good = 0 THEN
Station_1.HMI.Real[29] := 0;
END_IF;
END_IF;
 
Ha, double checking your work? Thanks for the update. I didn't catch that. I'm only using the good tally with a cycle counter to calculate good part efficiency. Thanks again.
 
Double, triple, quadriple, and read the code backwards for any programming language then you would be surprised by how many typos you catch, the reading the code backwards part I learnt from a python programming book, it's an interesting theory because your brain is programmed to read from left to right which can make you skim throw code without paying to much attention to the little things but once you do it the other way around you have to think each time for what you are reading
 

Similar Topics

Hi all, I am trying to convert RSLogix 5000 program to Step7. I need to bit shift left my array of double integers for tracking the product on...
Replies
2
Views
515
I’m working on a conveyor project for work. We’re trying to install a few diverts to carry product directly to one of two trailer doors. I have...
Replies
5
Views
1,037
Hello friends, When I trigger once for an application, I want to shift the 15th bit in the word address by 10 bit , so; 1000 0000 0000 0000 ->...
Replies
3
Views
1,658
Hi everyone, we have a working part rejector already. The issue is the new encoder went from 100ppr to 1024ppr. Hardware is compactlogix...
Replies
4
Views
1,906
Sidenote: One of my favorite lessons back in school was learning about BSL in RSLogix 500, and making it work in a simulator. I've been waiting...
Replies
30
Views
8,012
Back
Top Bottom