简体   繁体   中英

Modbus MSW is always 0

I have a energy meter EM340 with the following modbus spec:

Modicom address Physical address Length (words) VARIABLE ENG.UNIT Data Format Notes
301025 0400h 2 kWh (+) TOT – INTeger part INT32 Value=INT(kWh)*1 Example: if kWh=1234.567, value=1234
301027 0402h 2 kWh (+) TOT – DECimal part INT32 Value=DEC(kWh)*1000 Example: if kWh=1234.567, value=567 (Note: the MSW is always 0)

What does this mean: the MSW is always 0 ?

Anything in minimalmodbus I need to be aware of when reading 0402h?

The relevant manual for the device is available here . Page 7 of this states:

For all the formats the byte order (inside the single word) is MSB->LSB. In INT32, UINT32 and UINT64 formats, the word order is LSW-> MSW

So "MSW" = "Most Significant Word". A Modbus holding/input register is 16 bits (or one word); to hold larger values (eg INT32) the value is spread across multiple registers. The Modbus spec does not provide any guidance as to how this should be done so it's device specific. The above tells you that, for this device, the least significant word will be stored in the lowest register. For example 0xFFFF0000 could be stored as reg1 = 0x0000 and reg2 = 0xFFFF.

Note: the MSW is always 0

"kWh (+) TOT – INTeger part" is an INT32 which is two 16-bit words. As per the above this will be stored over two registers (LSW = reg 0x402 and MSW = reg 0x403). The comment indicates that the MSW (register 0x403) will always be 0 and can, potentially, be ignored (indicating that the data is actually a UINT16).

One element of this that I am uncertain of is that the spec says this is an INT32, so a signed value. Generally this would mean that the highest bit is a sign bit (set if the value is negative). However as the MSB is always 0 the full value cannot be negative. This makes sense because this is the decimal portion of a larger number (reg 0x400/0x401) so the sign bit will be in that value.

DECimal part
Value=DEC(kWh)*1000

This appears to confirm the above. As this value is the decimal portion multiplied by 1000 the valid values will be 0-999 (because 1000/1000 = 1 which is not part of the decimal part). So all potential values fit within an INT16.

Note: The above is my interpretation of the document; I've never used one of these units. (and may have misread).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM