Dectect morethan 1 bit set in a byte.

Darbs003

Member
Join Date
Aug 2010
Location
wigan
Posts
2
Hi there,

Can any tell me a simple way of decting if more than one bit is set in a byte.
when using a S7 400.

Cheers
 
L MB 10
L B#16#0
==I
JCN a1
S M 1.2
JU a2
a1: R M 1.2
a2: NOP 0

I think this code will solve your problem.

M1.2 = 1 if MB10 == 0
M1.2 = 0 if mb10 <> 0
 
Need to dectect when more than one bit position is high, not when the value of the byte is not zero. any more ideas?
 
One implementation:-

Code:
FUNCTION FC 5 : BOOL
TITLE =
VERSION : 0.1

VAR_INPUT
  byData : BYTE ; 
END_VAR
VAR_TEMP
  b1Bitset : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =
      SET   ; 
      R     #b1Bitset; 
      R     #RET_VAL; 
      L     #byData; 
      SRW   1; //bit 0
      JZ    S1; 
      SET   ; 
      S     #b1Bitset; 
S1:   SRW   1; //bit 1
      JZ    S2; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
      S     #b1Bitset; 
S2:   SRW   1; //bit 2
      JZ    S3; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
      S     #b1Bitset; 
S3:   SRW   1; //bit 3
      JZ    S4; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
      S     #b1Bitset; 
S4:   SRW   1; //bit 4
      JZ    S5; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
      S     #b1Bitset; 
S5:   SRW   1; //bit 5
      JZ    S6; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
      S     #b1Bitset; 
S6:   SRW   1; //bit 6
      JZ    S7; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
      S     #b1Bitset; 
S7:   SRW   1; //bit 7
      JZ    S8; 
      A     #b1Bitset; 
      S     #RET_VAL; 
      BEC   ; 
S8:   BEU   ; 
END_FUNCTION
 
Yeah, that is nice.

Code:
function fc5 : bool

var_input
    byIn : byte;
end_var

begin

l 0;
l byIn;
==I;
bec;
l -1;
+I;
aw;
l 0;
==I;
bec;
set;
s ret_val;

end_function;
For s7-400 there is some optimization to do, i just dont right now remember how four accus behave.
 
Last edited:
You can use logarithms to determine if one bit is set:
Code:
Log(x) / Log(2)

If the result has a non-zero decimal portion, more than one bit is set. If the result is an integer, only one bit is set.

Let's say you have a word value of 128:

Code:
Log(128) / Log(2) = 7.0
There is no remainder, so only one bit (Bit 7) is set.

Let's say you have a word value of 129:
Code:
Log(129) / Log(2) = 7.01122
There is a remainder of 0.01122, therefore, more than one bit is set. In this case, Bit 7 and Bit 0.

To implement this logic in a PLC:

  1. Compute the logarithm and store the result in a floating point type register (REAL, etc).
  2. Copy the result to an Integer register. In most PLC's this will round or truncate any decimal portion in the float.
  3. Compare the float to the integer. Most PLCs will convert the integer to a float for the comparison. If the floating point result has a non-zero decimal portion, the compare will fail. A non-zero decimal portion guarantees us that more than one bit is set.

The original poster asked for an example using Siemens, however all I've got handy at the moment is an AB implementation:
ABSingleBitTest.jpg

-Trevor
 
Last edited:
Slightly OT

I don't see a problem answering a question like this simply because the answer can also be found elsewhere.

Sure, 'bit-twiddling' is the preferred technique. When I'm working in C, bits are twiddled all over the place!

There are, however, situations where using an alternate technique may be warranted.

Not all PLC platforms are created equal, and not everyone has the knowledge or interest to implement the purist's solution. In many cases the larger process is of greater concern. A viable, working black-box-ish solution for the specific platform in use could be just what the doctor ordered.

In this case, I invested perhaps 5 minutes into my post, and it provided a much-needed morning break. It's a viable, working solution, as are some of the other suggestions above.

The next guy who searches this forum (or google, for that matter) now has an additional source of information that just might help.

Also - lately I've been getting a kick out of 'Let Me Google That For You': Count Two Bits


Cheers,
Trevor
 
Actually - if you read the original post - it's not 'TWO BITS' - it's 'MORE THAN ONE'. Which means, after eliminating the first if any are left there are 'MORE THAN ONE'. It doesn't matter if there are exactly two.
 
A simple bit hack should do it.

J := I AND NOT(I - 1)
If J<>I then more than one bit is set in I.

----------------------------------------------------------
Example 1

I = 1010

J := I-1 which is 1001
bitwise NOT J to get 0110
bitwise AND J with I to get 0010

J <> I so I <> n2 and therefore more than one bit must set.

---------------------------------------------------------------------------
Example 2

I = 0100
J := I-1 which is 0011
bitwise NOT J to get 1100
bitwise AND J with I to get 0100

J = I so I has only one bit set.
 
Last edited:
Certain bit hacks are so useful that they are worth memorizing. This is one of them. The j := i AND NOT (i-1) hack has several other uses besides just checking for more than one set bit. I use it in state machines all the time.
 

Similar Topics

See the screenshot of EIP tag list. We are trying to read in a digital input that is hard-wired. It is shown here as I31.1. I believe we cannot...
Replies
7
Views
282
A couple days ago I accidentally toggled an alwasyoff bit. The issue is it was set up as a single OTU on a rung, nothing else, and used as XICs...
Replies
3
Views
226
Hi I have an old panel builder 32 that I’m replacing for a factory talk me hmi . In the plc for the old panel builder there is a coms bit for the...
Replies
0
Views
74
Hello, Haven't been on in a while. I need to generate a bit level pdf of the I/O for RSLogix 500. I can generate a report but it just shows the...
Replies
1
Views
158
I tried researching but I still don't quite get it. As far as I understood, it's used after a function is called in STL and then if the function...
Replies
1
Views
143
Back
Top Bottom