Float 32 bit number from 2 modbus registers !

190 views (last 30 days)
Bambos
Bambos on 24 Feb 2019
Commented: Bambos on 24 Feb 2019
Hello Everyone,
I need some guidance about floating point numbers coming from modbus RTU, I'm working with RS485 serial interface.
No issues with modbus read. if i just read the values with the modbus read function, i have v1=36260 v2=17056 (??)
Code:
m = modbus('serialrtu','COM6','Timeout',5)
v1=read(m,'holdingregs',140,1,3)
v2=read(m,'holdingregs',141,1,3)
It seems that the final value is according the (IEEE 754) but is splited into 2 registers of 16bit. As i'm reading through internet, this is common in modbus protocol since is the maximum a register can hold is 16bit, so they use 2 registers with more and less significant order.
This is information from the datasheet of the metering device.
ModBUS address R/W Description Length (byte) Default value Meaning
________________________________________________________________________________________________________________
140 R VRMS ABC (MSB) [float – 32 bit] 2 0.0 Three-phase RMS voltage [Vrms] (Upper part)
141 R VRMS ABC (LSB) [float – 32 bit] 2 0.0 Three-phase RMS voltage [Vrms] (Lower part)
All values in 32bits are stored into 2 consecutive registers, for example:
VRMS A in floating point 32 bits is stored into registers 40140 and 40141, the Most significant word is the register 40140, the less significant word is the 40141.
So the 32bits value is obtained by the following relation: ???? ?=???40141+(???40140×216)
note! 40140 = read only holding register 140. [same thing in modbus language]
Abreviation:
“MS” = Most significant
“LS” = Less significant
“MSB” = Most significant Byte
“LSB” = Less significant Byte
“MSW” = Most significant Word (16 bits)
“LSW” = Less significant Word (16 bits)
“R” = Read only register
“RW” = Read and write register
“Unsigned 16 bits” = Unsigned 16 bits register
“Signed 16 bits” = 16 bits register with sign
“Float 32 bits” = Floating point single precision 32 bits (IEEE 754) register
“0x” = Hexadecimal Value
if i just read the values with the modbus read function, i have v1=36260 v2=17056 (??)
Final comment is that i used for test a modbus poll app https://www.modbustools.com/modbus_poll.html and it represents correctly the value if i change the view settings to Float Inverse - Description: Use this command to display data in floating point format. 2 Registers are used. Hi and Lo registers are swapped. IEEE 754 specification is used. This is representing the value correctly !!
Question:
How to get the correct value in matlab as a double numeric value with some decimals? For example 238.34985

Answers (1)

Steven Lord
Steven Lord on 24 Feb 2019
What is the class of v1 and v2 in your code above?
If they're 16-bit or 32-bit integers, take a look at the typecast and swapbytes functions.
  1 Comment
Bambos
Bambos on 24 Feb 2019
Current class is double - without forcing the variable type.
If i force the modbus read function with :
v1=read(m,'holdingregs',140,1,3,'uint16')
insteaf of
v1=read(m,'holdingregs',140,1,3)
is changing accordingly, but i don't see any help from that.
As i mentioned in first post, are Float32 ieee 754 standart, just splited in 2 registers with significance. Since are not clearly integers, maybe we have to take a step back and get the values to binary or hex format and reassemble again. I try a lot of functions like cast, typecast, i don't have yet any success.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by