I’m using Lumel’s SM2 module and getting result that I cannot translate it, because I never worked with modbus before. Documentation says that value is located in two successive 16-bite registers.
With this code:
var serialPort = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
var rtuInterface = new ModbusRtuInterface(serialPort);
var master = new ModbusMaster(rtuInterface);
ushort[] result = master.ReadHoldingRegisters(1, 7004, 2);
i’m getting results 17912 and 38912. When I translate in into binary form, It doesn’t match with possible values from documentation in any way. I’m using Spider and library from codeshare. Any advice would be appreciated
I am well familiar with Modbus. Data was originally encoded as 2 bytes for each register in the Modbus map giving a 16 bit value but later devices used 2 registers to encode 32 bit values.
Can you share what the register configuration is for your device you are talking to? i.e. what is the value supposed to represent number wise and what is the scaling etc.
For example, I have a Variable Speed Drive on my desk that is modbus and the register for speed setting is described like this.
Logic address: 3202
Type: INT
Unit: 0.1
The type here is critical as it indicates if the value can be negative. UINT would indicate a pos value only. Your code gets back UINT. Type can also be WORD indicating a status bit register.
The UNIT here indicates that the value is stored as 10 times the real value.
If you have the Modbus information for your device, I can work out what the encoding should be.
On page 13, at the bottom, it shows a typical read of 2 registers, which should return 4 bytes but page 14, at the top, shows that it returns 8 which is wrong. Modbus RTU protocol is 16 bit per register.
Page 17 shows that the system is encoded as 32 bit data so you will have to read 2 registers and then OR them together after shifting the 1st 16 bit value 16 bits to the left. Assuming the same HI LO order that is Modbus?
Same for your 7004 register. Read out 7004 and 7005, shift 7004 left 16 bits and add the 2 together (or OR them)
The manuals explanation of the Modbus message is very wrong. There is NO 4 bytes transmitted for each out. To read 2 registers, you need to read 4.
PS> This is the document they refer to and it has nothing in there showing 4 byte data
@ tvinko - Looks like you’re using my Modbuslibrary.
Modbus uses big endian encoding, C# is little endian. (Don’t shoot at me if it’s the other way around, I can never remember :whistle:
My Modbus library already makes this conversion internally, so the 16 bit register values are correct encoded for C#.
But if you look at them byte wise, they might be in opposite order to what your module spec says.
But to generate an 32 bit value from 2 16 bit register values it should work as follows:
result = master.ReadHoldingRegisters(1, 7004, 2);
uint value = ((uint)result[0]) << 16) | result[1];
Depending on your module you might have to exchange result[0] and [1].
The fact that the document shows this to only have 16 bits, you are getting a value for the upper 16 bits and they should be ZERO according to my interpretation.
What do you get if you read registers 7202 and 7204 (page 21 of the manual)
Read out 2 registers for each as the docs show everything is 32 bit.
The confusing part is that there is no indication of the how it’s endian encoded anywhere in the docs that I could find.
Maybe little progress here.
When I read some other register (7613) i get value float value 1, which is expected state.
But, i don’t know, what to do with value, that i get from register Status 2 (7502)
Here is the procedure:
17912 from register1 and 38912 from register 2 -> 45 F8 98 00
Convert “45 F8 90 00” to float with Float Point Conversion. Btw, great application downloadable from link that Dave provided. Result is 7955 (attachment)
The problem is that 7955 to binary doesn’t give me any meaningful…