Splitting a word into integers

TheWaterboy

Lifetime Supporting Member + Moderator
Join Date
May 2006
Location
-27.9679796,153.419016
Posts
1,905
I have to take a 16 bit N register and split some of the bits into separate integers. example:

Bits 0-1 = integer with a value from 0-3
Bit 2 is a bool = easy one
Bits 3-12 = another integer value from 0-1023
remainder are bools
How do I split a word in this way? Is Mask and shift the only way?
 
I have to take a 16 bit N register and split some of the bits into separate integers. example:

Bits 0-1 = integer with a value from 0-3
Bit 2 is a bool = easy one
Bits 3-12 = another integer value from 0-1023
remainder are bools
How do I split a word in this way? Is Mask and shift the only way?


I think I have seen a PLC instruction that does this in one go, but I forget which manufacturer that was. [Update: @Phrog30 knew it]

Mask and divide* is an equivalent alternative if there is no multi-bit-shift instruction, but yes, those are the most direct ways I can think of.

* or divide then mask, to get around a non-zero sign bit
 
For positive integers with a zero most-significant bit Divide and then AND mask should work - assuming the PLC does a normal truncating integer division. It may not work in a PLC that insists on doing roundoff with integer division. Some processors divide integer 5 by integer 3 to get a result of integer 2.

I'm not sure how well divide and mask can work when starting with a negative number.

Shift and Mask solutions are best done in that order - shifting first and then masking. C programmers tend to do that because you do not have to worry as much about what the processor is doing with the shift - if it is pushing in a carry bit, doing sign extension, etc.

The non-elegant PLC solution is to initially zero all the bits of the result register and then load it bit by bit from the parts of the original register using contact and coil logic. It sounds crude but at least you're not at the mercy of how the PLC chooses to do it's math. It's more rungs but they're not hard to understand.
 
Would a MVM work? TheWaterboy wants bits 3-12 to represent and integer (0-1023). Those bits need to be "moved" to bit 0 of an integer. As Phrog30 says, this is what BTD does. Map "these bits" to "those bits".
 
For positive integers with a zero most-significant bit Divide and then AND mask should work - assuming the PLC does a normal truncating integer division. It may not work in a PLC that insists on doing roundoff with integer division. Some processors divide integer 5 by integer 3 to get a result of integer 2. ...


d'Oh! I knew that, but forgot!
 
Single-instruction alternative to MVM+[shift or divide]:

  • CPT tenbits_12_to_3 (sixteenbits AND 8184)/8
mask of 8184 = (2**13)-8
Code:
$ python
Python 3.8.8 [...]
>>> bin(8184)[COLOR=Blue][COLOR=Black]
'0b[/COLOR][B][COLOR=Blue][B]1111111111[/B][/COLOR][/B][COLOR=Black]000[/COLOR][B]'[/B][/COLOR]
[COLOR=Blue][B]   2109876543[/B][COLOR=Black]210[/COLOR][/COLOR]
[COLOR=Blue][B]   111[/B][/COLOR]
 
I always have to preface my comments with "I know nothing about rslogix", almost.
Is it accurate that the OP is RSLogix 500 and BTD is RSLogix 5000?
 
Is it accurate that the OP is RSLogix 500
we don't know?
and BTD is RSLogix 5000?
yes, also RSLogix 5/PLC-5.

P.S. MVM+shift is less useful than AND+shift here as MVM does not clear higher bits. Does BTD clear destination INT's bits outside its mask?

P.P.S. this could also be done with two shifts, left then right, assuming the right-shift does not fill with 1s from the left when the sign bit is 1; divide will always fill with 1s from the left, for negative signed integers, so, if unsigned integers are used, then extra steps must be taken when the high bit in the range is the sign bit.
 
Last edited:
Oh, and CCW? Yeah, it has a multi-bit right shift, but the manual has not a whit of a whisper of a ghost of a clue what it does about the sign bit

yyy.png


ROTFLOL
 
Is it accurate that the OP is RSLogix 500 and BTD is RSLogix 5000?

I really need to work on my reading comprehension :) This is an important distinction, I should have paid closer attention to that detail. OP doesn't mentions SLC specifically, but does mention "N" data files.

  • BTD in RSLogix5 = Yes
  • BTD in RSLogix500 = No
  • BTD in RSLogix5000 = Yes
 
Sorry for missing the model number. I work in a silo and forget there are other models :)

The source is a ML1400 so Logix 500. The eventual designation of all this will be a CLX so BTD is available on that end, but I would prefer to convert it at the source.

I will be back at this in about 4 hours (if things go well this morning) and try again.
 

Similar Topics

Any one know how to take a floating point number and convert it so that it can be split to span 2 16-bit words in the +/- 0x7fffffff hex format...
Replies
18
Views
5,234
I am close to wits end and would appreciate any new perspective. Cannot go into minutia, but here is a rough rundown of the system and issue we...
Replies
26
Views
9,197
Would it be wise / safe to split a 24vdc input from a switch to a PLC and relay? I currently have 14 of the same type of equipment that each have...
Replies
2
Views
1,514
Any one know of way to split a 4-20 mA signal 4 ways? Do they even make such a device? Thanks
Replies
12
Views
3,609
I have an application where I need a single SSI encoder to connect to both a safety controller (SICK Flexi Soft) and a general-purpose PLC...
Replies
3
Views
2,060
Back
Top Bottom