06-30-2026 09:29 AM - edited 06-30-2026 09:42 AM
Hello everyone,
I'm looking for a way to programmatically apply a mask to specific bits in a register.
To explain this better, here's an example:
I have a variable called Value1.
This variable, along with others, is registered in a Modbus map that includes additional information about the variables.
This information is:
- Variable type: B, U2, U3, ..., S64, S16, S32, F32, etc.
- The register number where the variable is located
- The bit positions occupied by the variable
- The variable name
In this case, let’s say the variable shares the same register with other variables, so:
(hexAdd)[b]:(cs):(cbr) decAdd (msb..lsb) type varName
(0x9c40)[0]:(16):(15..0) 40000 (15..0) U16 GlobalVariable
(0x9c40)[0]:(16):(0..0) 40000 (0..0) B Value0
(0x9c40)[0]:(16):(8..1) 40000 (8..1) U7 Value1
(0x9c40)[0]:(16):(9..9) 40000 (9..9) B Value2
(0x9c40)[0]:(16):(15..10) 40000 (15..10) U6 Value3
Therefore, to modify only the value of Value1, I would have to apply a mask 0xFE01 = 0b1111111000000001 and then add the value I want to set, for example, 0x00012 = 0b0000000000010010.
This way, only Value1 would be modified. Value0, Value2, and Value3 would remain unchanged.
Right now, every time I want to apply a mask, I have to calculate it and write it manually. This isn’t difficult and isn't a problem to me.
But sometimes, depending on the Modbus map I’m using, the same variable occupies a different location inside the register.
Therefore, I would like the mask to be applied to be calculated automatically based on the information provided by the Modbus map.
I have attached the VIs I am using, as well as the VI I have been testing. I am a bit stuck and unsure how to continue, so I would appreciate any guidance.
If I haven't made myself clear, please let me know and I will answer any questions.
Thanks in advance.
Solved! Go to Solution.
07-01-2026 01:18 AM - edited 07-01-2026 01:20 AM
Well, I haven't looked at your code, but I figured it's a small fun challenge. I haven't done any real thinking and I wouldn't be surprised if others appear with cleaner solutions:
Some comments:
07-01-2026 08:33 AM
Hi tst,
First, thanks for your solution, it clarifies me some concepts and kinda worked.
But I find an issue in your example
If the variable is an U16 and all the bits fill the full register, the calculated mask is 0x0001 when it should be 0x0000.
I made some changes to fit with other VIs of mine and now works perfect.
Thank you again.
07-01-2026 08:49 AM - edited 07-01-2026 08:55 AM
Hi xespizua,
@xespizua wrote:
I made some changes to fit with other VIs of mine and now works perfect.
Some comments:
AutoMask.vi:
AutoValue.vi:
I recommend to create the basic information for your Modbus variable directly in the GetVariableDataFromModbusMap VI. I would store the relevant information in a (typedefined) cluster, including:
You may keep an array of that cluster to hold the information for all variables. (Use maps/sets/variant attributes to have a LUT of those clusters based on the variable name.)
This way you have all needed information for any of the following data manipulation functions - and you need to generate this information only once instead in each of those subVIs. Parsing strings is "slow", so parse just once!
(I also prefer to create bitmasks based on the LSB instead of counting downwards from MSB. IMHO that's the usual way to handle bitfields.)