Modbus FC22 (0x16) Mask Write Register


Thread Starter



I'm having trouble understanding Modbus Function Code FC22 (0x16) Mask Write Register.

Modbus aside, as I understand it if I was to write a single bit inside a register I could use an AND or OR mask depending on the value. eg, Register && AND_mask, Register || OR_mask.

I can't relate this to the functions algorithm of:

Result = (Current Contents AND And_Mask) OR (Or_Mast AND (NOT And_Mask)

Please could somebody explain this algorithm a little more for me, and maybe give an example of how to write to a specific bit inside an integer using this function. That would really help!

Thanks in advance


Each bit has an 'and mask' and an 'or mask'.

In Pascal.

Here is the mask for 16 bits.<pre>
reverseBitMask:array[1..16] of integer = (32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1);

For the 'and mask' you would send the 'not' of the mask for the bit to change.

x:=not reverseBitMask[bitNumber]; // andMask

For the 'or mask' you would either send the normal mask for the bit if setting the bit and the 'not' of the mask if clearing the bit.

if true then
x:=reverseBitMask[bitNumber] //set bit, orMask
x:=not reverseBitMask[bitNumber]; //clear bit, orMask

In the device receiving the command:

holdingRegister[registerAddress]:=(holdingRegister[registerAddress] and andMask) or (orMask and not andMask);</pre>
Just think about what the command is trying to accomplish. It is trying to use a word to only cause a change in specific bits. The other bits would not be changed.

In the PI-MBUS-300 document it has a good example, page 66.

Good luck,


Lynn August Linse

First, make sure your device supports it, or you waste your time trying to understand. Other than a Modicon PLC, I have never seen that function supported by any commercial products.
Thanks Mark, I get it now :)

I checked out the hardware beforehand. I'm using an M340 PLC and the function now works fine! Thanks for pointing that out though Lynn, it's useful for me to know that a lot of hardware might not support it!
But if we need to change for example multiple bits at the same time, how do we calculate the Masks? Like If I want to change bits 3, 5, 7 of a register how do i calculate the AND and OR masks?