More Tidbits, a challenge.

Join Date
Apr 2002
Location
No income tax, no capital gains tax. Freedom!
Posts
8,389
How does one find the least significant bit WITHOUT:
1 checking for a bit being set in each bit position.
2 looping.
3 using lookup tables.
4 using the encode instruction.

Most should not even try. I will be surprised if anyone gets this.

Hint. This works well on just about any processors that have floating point processors. That is a big hint.

Steve Kemp's question got me thinking about how I find the LSB.
 
Peter, I'm a little confused as to what you are refering to as a least significant bit. In class we learned that this is the far most right bit of a word or element. A dibble is four bits or one BCD word in any position. If we are looking for this one, all we have to do is address that position. utoh
 
BDKuhns said:
Peter, I'm a little confused as to what you are refering to as a least significant bit. In class we learned that this is the far most right bit of a word or element.
Correct.

BDKuhns said:

A dibble is four bits or one BCD word in any position.
The problem has nothing to do with BCD or nibbles.


BDKuhns said:

If we are looking for this one, all we have to do is address that position. utoh

What if you have 16 alarms and the highest priority alarm is indicated by the least significant bit of a word being set. You don't know ahead of time which bit might be set. You can test each bit one at a time but that is inefficient. In Steve's case he would need to test all 32 bits one at a time. Most PLCs have an decode instruction that will scan a register starting at the LSB and working toward the MSB until a set bit is found. The decode instruction then returns the number of the set bit.

But what if your PLC does not have a decode instruction? What then?
 
I don't know what PLC you have but this is what you want
in AllenBradley version:


N7:10 - input word to be tested
N7:11 - negative of N7:10
N7:12 - result in binary form
N7:13 - result in decimal form

-------------[SUB 0 N7:10 N7:11]

-------------[AND N7:10 N7:11 N7:12]

-------------[ENC N7:12 N7:13]

 
Panic Mode got the first half.

I guess I haven't been very clear. Panic mode got some of the trick but may be not for the right reason. The idea was what do you do when you don't have the encode instruction.

Most cpu chips do not have an encoder or decode instruction. I don't know of any. The trick here is to isolate the LSB set as Panic Mode suggests. The convert the result to a floating point number. The bit position is encoded in the exponent part of the floating point number. The mantissas will always be the same. Now shift the floating point number right 23 bits for move the exponent into the lowest 8 bits of the register. Next subtract 127 because the exponent is in excess 80H format ( an exponent of 0 is represented by 127 in IEEE format ). Tre result is the bit number. This saves having to scan for each bit being set. This would take only a handful of instructions on a S7.

Back in the dark ages I programmed mini computers that didn't have encode and decode instructions. This is how we found the number of LSB that was set only our floating point numbers weren't in IEEE format.
 
The formula is:
2^x = y
x = lny / ln2
x is the bit position and y is the value of the memory word. To recieve the bit position, x must be incremented by 1. There are cases with no set bit and those with a prefix bit.
Code:
      L     #m_word                     // Load input data word
      L     0                           // special case: input word is 0
      ==I   
      SPB   a
      L     #m_word
      L     -32768                      // special case: MSB is set  
      ==I   
      SPB   b
      L     #m_word
      ITD                               // conversions for logarith operation
      DTR   
      LN                                // Natural Logarithm of input data word
      L     2.000000e+000
      LN                                // Generate Natural Logarithm of 2
      /R    
      RND   
      L     1
      +D                                // add 1 to bit position
      T     #bit_pos                    // Transfer bit position to output
      BEA   
a:    L     0
      T     #bit_pos                    // bit position 0
      BEA   
b:    L     16
      T     #bit_pos                    // bit position 16
 
Ron, I was thinking of something far simpler.

instructions such as LN take a long time to execute.

Code:
msb:  L     MD   100     // THIS IS THE PART 
      L     MD   100     // PANIC MODE
      NEGD               // GOT
      AD                 // RIGHT
      JZ                 // NO BITS SET
      DTR                // CONVERT DOUBLE TO REAL
      SRD   23           // SHIFT RIGHT LEAVING ONLY THE EXPONENT
      -D    DW#127       // IEEE ADDS 127 TO THE BINARY EXPONENT
      AD    DW#16#1F     // CLEAR SIGN BIT THAN MAY BE SET
      JU    EXIT
NONE: L     L#-1         // CODE FOR NO BITS SET
EXIT: BEU                // BIT# OR -1 IN ACCUM

I don't have my S7 at home to test this but I am sure it is close.
THis is much faster than looping.

The actual code I use our motion product. This executes in .166 microseconds.

Code:
_lsb	negi	ar2,r0    ; PANIC MODE GOT
	and	ar2,r0    ; THE PART RIGHT
	float	r0,r0     ; CONVERT TO FLOATING POINT
	pushf	r0        ; THE TWO INSTUCTION CONVERT
	pop	r0        ; THE FLOATING POINT TO DWORD
	lsh	-24,r0    ; SHIFT RIGHT TO GET RID OF THE MANTISSA
	rets

Note. The above code uses a dsp and it does not use IEEE format but this is close enough.

About 20 years ago I was using similar code on a HP1000 mini computer with a CISC instruction set. CISC stands for Crippled Instruction Set Computer in this case.
 
Geez 20 years ago I did good to understand how to compute current draw on a line...didnt know Ohms law then.

Personally I feel good, since you stated:
Ron, I was thinking of something far simpler.

I have to "WORK" thru these things...ever noticed how the S7 300/400 seems to make more sense using STL?

I feel good now, its STL and its high level math...maybe there are simpler ways but I found a way.
 
You have seen the first part before.

Panaic Mode obviously remembered the trick of isolating the LSB or searched for the same thread. I bet he remembered.

The second part of the trick is finding the bit position by using the exponent of the result of converting the bit to a float. This too is a very old trick though I think it is new here.
 
I felt sting for 'not having the other part' (specially because
my solution does work and I didn't see that this was speed contest or that it had to work on S7).
I am not sure about execution speed but my code
is definitelly shorter.
And about SUB and AND, yeah, i remembered. ;-)
 
Last edited:
Panic Mode, no sting intended.

It was Sunday and things are slow on the weekend. Steve's question got me thinking about this old trick. I just thought it was the right time to share it.

One doesn't need to isolate the bit IF the ENC instruction is used. The Rockwell's encode instruction does that for you. The point was to find the bit number of the LSB that was set without the ENC instruction. How did people solve this problem before there were ENC instructions. For that matter, most microcontrollers and DSP do not have an ENC instruction an must resort to these type of tricks. Even with DSP I still need to use these types of tricks.

This is a peek under the hood.
Now everyone knows what is happening when one use a ENC instruction.

I bet Panic Mode will not forget this trick if he ever comes across a PLC without a ENC instruction and he needs to use one.
 
Peter:

The first half of the trick is great. The second half makes me wonder . . .

Is there a clean way to do this on a AB PLC-5 (which doesn't have the ENC instruction)?

By the time I finish duplicating your 2 examples in "PLC5 speak":

MOV to the Float
COP to an Integer
Bitshift
Adjust for the IEEE "127" normalization
Look for the special cases of "1" and "-1"

and finally get my number,

I think that 16 XIC's or using LN functions aren't such bad ideas. Am I missing something simple?

Marc

PS: For those interested, here's a technote that talks about the AB float registers:

http://domino.automation.rockwell.c...85C2838CBFC456D285256AFB00695031?OpenDocument


and another one that talks about exchanging float values between AB flavors:

http://domino.automation.rockwell.c...C9B5EA04DF66D67B85256AFB006AAE6C?OpenDocument
 

Similar Topics

I didn't want to hijack the thread so I started this one. It isn't strictly related to PLC but the techniques could be useful in PLCs too...
Replies
3
Views
5,983
Assume there is a set of 16 bits in N7:0. What is the result in N7:1 SUB 0 N7:0 N7:1 AND N7:0 N7:1 N7:1
Replies
8
Views
5,602
Hello, i need to use P_Intlk and feed the Status interlock OK bit to a P_DOut block. However, there's 17 interlocks for this output. How can I...
Replies
1
Views
107
Hi everyone, recently i worked with a cmore panel and have the question that how can clear alarm list whit remote form,right now only can with...
Replies
0
Views
107
Hello, friends, I am trying to upgrade a system that uses an Onrom incremental encoder (E6B2-CWZ6C) connected to a Danfoss VFD (FC360), but now...
Replies
4
Views
271
Back
Top Bottom