I am using a energy meter named RISH 3430 which says it uses Modbus RS-485.
I am writing a c code to fetch the register values. i.e. Input Registers having functional code 04 and the register number starts from 30001.
I am using the function called
I am not getting the values properly. may be the register number which I'am using is not correct..
any suggestions please reply
First Make sure you are reading 2 consecutive registers as the manual says. This means that all data is 32 bit. Typical Modbus devices use the Motorola byte order of HiLo where a hex value of 0x0001 would be a decimal value of 1, it it uses the Intel format which is a byte order of LoHi then the same hex value would be 256.
Now since all data is stored as 32 bit data it could be sending the data as a Dword(unsigned 32 bit integer), a Long(signed 32 bit integer), or as an IEEE Floating point number. My experience with reading data from these types of meters is that they store all data as raw integer values and apply scaling accordingly. SO for example if the volts were displayed as 50.25 on the meter display then they would be stored as 5025 or 0x13A1.
Also, it does not look like the data is stored contiguously so you will not be able to do block reads of multiple data points with out getting errors. That means it will take a lot longer to read all of the changing data in a single poll cycle.
1. It could be as simple as the 'one-offset' issue; the difference between cardinal and ordinal numbering.
A Cardinal Number is a number that says how many of something there are, such as one, two, three, four, five.
An Ordinal Number is a number that tells the position of something in a list, such as 1st, 2nd, 3rd, 4th, 5th etc.
The actual Modbus address for any memory/register/address range starts at zero, a cardinal number.
But the convention used to represent memory/register/address locations starts at (x)00001 where x identifies the function code's memory table. (x) value for FC 04 (read input registers) is (3). So the first (ordinal) memory location is (3)0001 for 5 digit addressing (1-9999) or (3)00001 for 6 digit addressing (1-65535). The (x) value is NOT used in the PDU or Modbus telegram, it's only for helping humans identify which function code the register is associated with.
The RISH documentation attempts to explain this by providing both the (3)xxxx (ordinal) register addresses and the high/low byte values that the Modbus PDU message uses (which are one less than the cardinal value)
The graphic at the link below shows the actual hexadecimal values for a sample Modbus RTU message that polls (3)0001. Note that starting address (3)0001 is hex 00 00, or zero, the first cardinal value in the FC04 memory table, and the value (3) used to identify the register as an input register for human beings, is not part of the message, because Modbus knows that it is function code 04.
2. The documentation states that the data format is IEE754 32 bit floating point (FP) format, the standard in the industry.
That means that each data value uses two (contiguous/adjacent/sequential) Modbus 16 bit registers to get the 32 bit floating point (real) value.
The Volts1 value in (3)0001 uses both (3)0001 and (3)0002 registers. Each FC04 read must fetch two registers, not just one register
The catch is that there are four recognized word-byte orders for 32 bit floating point. Only two are commonly used.
If your interpretation of the 32 bits does not match with the word-byte order of the source data, the value will be way off, like in millions. An incorrect word-byte order value does not even appear to be a valid, something like 2.17^-16
For an explanation of the word-byte order used for FP, see's Chipkin's explanation here:
Are you getting a response that includes some form of data or are you
getting an error response or no response at all?
I don't know about the meter you're using, but the yokogawa power meters
that I use all the data is stored as floating point. You have to take
two of the 16-bit registers you get back, manipulate them into the proper
format, and convert them to a 32-bit floating-point.