Trouble with floats

So in the tag viewer I’m unable to get floats to show up correctly, they are all 0, if I use modpoll the value comes through correctly. The diagnostics shows that the value is good with a scientific notation value. It’s my first time with floats so I’m sure I’m just not using the tags properly.

Thanks,

Jake

Check that the tag offset is correct (try moving up or down one register) and also play with two of the settings on the device connection:

  1. Reverse Word Order
  2. One-Based Addressing

Also worth looking at: is this “scientific notation value” really close to 0 and modpoll is showing you a rounded number?

the scientific notation value is 2.4243e-41, modpoll shows 300, moving up and down a register gives an error, in that block there’s only 1 float register, if I get each register at a time the first is 0 and the second is like 17,302. The opc item path is using the HRF prefix.

how do I reverse the byte order?

Reverse byte order is counter to the Modbus spec, so we don’t directly support it, but you could try to do so from a script:

def int32BE_to_float32LE(i): 
	from java.lang import Float, Integer
	return Float.intBitsToFloat(Integer.reverseBytes(i))

The word order reversal is an advanced option on the driver settings.

Reversing byte order requires @PGriffith’s scripting workaround.

2 Likes

I figured it out, think it’s because the modbus protocol is big endian, I had my software store the data as such. Thanks everybody.

Had the same problem fo you @codersmurf. Just solve it playing with play with Reverse Word Order and One-Based Addressing, also being aware of the Modbus spec.

Many thanks to all!

Where would you install this script.

On the Value Changed Event?

how should the tag be setup? as an int or float?

-Phil

Try reading this before messing with that:

https://docs.inductiveautomation.com/display/DOC/About+Modbus+Addressing

There are some special register types like HRBCD and such that will grab the data with conversions.

I had to deal with this issue in order to get the weight off of truck scales. I was was able to get it to work by pulling the two input registers in question in 16bit unsigned format. Whenever they change (via a tag change gateway script) the following gateway script runs.

import struct

def combine_modbus_words_to_float(tag_path1, tag_path2, output_tag_path):
def swap_bytes(word):
# Swap the bytes within the word
return ((word & 0x00FF) << 8) | ((word & 0xFF00) >> 8)

def combine_words_to_hex(word1, word2):
    # Combine the high-order and low-order bits
    combined_int = (word1 << 16) | word2
    # Convert to hexadecimal string
    combined_hex = format(combined_int, '08x')
    return combined_hex

def hex_to_float(hex_str):
    # Convert hex string to integer
    int_value = int(hex_str, 16)
    # Pack the integer into bytes and unpack as float
    combined_float = struct.unpack('!f', struct.pack('!I', int_value))[0]
    return combined_float

# Read Modbus values
a = system.tag.readBlocking([tag_path1])[0].value
b = system.tag.readBlocking([tag_path2])[0].value

logger = system.util.getLogger("ModbusScript")

# Log raw values
logger.info("Raw values: {}, {}".format(a, b))

# Swap the bytes within each word
a_swapped = swap_bytes(a)
b_swapped = swap_bytes(b)

# Convert individual words to hexadecimal after swapping
a_hex = format(a_swapped, '04x')
b_hex = format(b_swapped, '04x')

# Log hexadecimal representations
logger.info("Hexadecimal representation of the first word (swapped): {}".format(a_hex))
logger.info("Hexadecimal representation of the second word (swapped): {}".format(b_hex))

# Combine swapped words into a single hexadecimal representation
combined_hex = combine_words_to_hex(a_swapped, b_swapped)
logger.info("Combined hexadecimal representation: {}".format(combined_hex))

# Convert combined hexadecimal to floating-point value 
combined_float_value = hex_to_float(combined_hex)
logger.info("Combined floating-point value: {}".format(combined_float_value))

# Write the result to another tag
system.tag.writeBlocking([output_tag_path], [combined_float_value])

image