The meter doesn't have that setting, as far as I know.
If it's not much of a wrongdoing, I think I'll use this modified version.
It is a bit strange, indeed. First time using modbus and comimg across something like this.
Thank you for helping me all along.
Posts made by odious
-
RE: Modbus RTU getValue() parameters
-
RE: Modbus RTU getValue() parameters
Hello again, and sorry for the delayed response.
The value displayed on the meter is 1000 decimal ( = 3E8 hex). The response I get is:FOUR_BYTE_BCD: 8030000 EIGHT_BYTE_FLOAT: -1.0835797112716513E193 EIGHT_BYTE_FLOAT_SWAPPED: 1.03213875566E-310 EIGHT_BYTE_INT_SIGNED: -1728537831661371392 EIGHT_BYTE_INT_UNSIGNED: 16718206242048180224 FOUR_BYTE_FLOAT: -2.47452E24 TWO_BYTE_BCD: 803 TWO_BYTE_INT_UNSIGNED: 59395
The response structure is four bytes, as follows. (I know this from meter's documentation):
LowBit 1 | HighBit 1 | LowBit 2 | HighBit 2
Using FOUR_BYTE_BCD, I can expect:
E8 | 03 | 00 | 00
but every number > 9 is treated like 0, so E becomes 0 and disappears.
To overcome this, I've changed bcdNibbleToInt(...) like below:
private static String bcdNibbleToString(byte b, boolean high) { int n; if (high) n = (b >> 4) & 0xf; else n = b & 0xf; if (n > 9){ switch (n){ case 10: n = 0xA; break; case 11: n = 0xB; break; case 12: n = 0xC; break; case 13: n = 0xD; break; case 14: n = 0xE; break; case 15: n = 0xF; break; } if(n > 15) n = 0; } return String.format("%1X", n); }
and these lines in bytesToValue(...)
if (dataType == DataType.FOUR_BYTE_BCD) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 4; i++) { sb.append(bcdNibbleToString(data[offset + i], true)); sb.append(bcdNibbleToString(data[offset + i], false)); } return sb.toString(); }
This is for my particular case and it works.
I'm not exactly sure what kind of format to expect from the meter, but as long as this works, I guess I'll stick to it. -
RE: Modbus RTU getValue() parameters
You're probably right.
To be fair, I'm not really sure why this is working.
The thing is, any other DataType returns me numbers I cannot transform into useful data.
I know this because the slave is a meter which displays a measured value.
By using FOUR_BYTE_BCD I get the hex values corresponding to the numbers displayed.
Unfortunately, the meter's documentation isn't very explicit, and I couldn't find anything better online.
I'm going to test and investigate further. -
RE: Modbus RTU getValue() parameters
I think I've managed to solve my problem.
I've tweaked ModbusLocator a bit, by changing bcdNibbleToInt():if (n > 9){ switch (n){ case 10: n = 0xA; break; case 11: n = 0xB; break; case 12: n = 0xC; break; case 13: n = 0xD; break; case 14: n = 0xE; break; case 15: n = 0xF; break; }
Now the result I get in Java as res:
Object res = master.getValue(locator);
is exactly the same as the one from Docklight.
-
RE: Modbus RTU getValue() parameters
I have another little problem right now:
Let's say my meter counter has the value 1000 displayed.
The correct response is "E8 03 00 00", which I get in Docklight.
(E8 is low-bit, so I actually get 03 E8, which is 1000 in decimal - correct)
Interestingly enough, the response I get in Java is "8 03 00 00" - the E disappears.
Is there any way to solve this ? The Locator is the one from above.
Thanks again. -
RE: Modbus RTU getValue() parameters
Thanks a lot, it really helped me. It turns out what I needed was this:
ModbusLocator locator = new ModbusLocator(1, RegisterRange.HOLDING_REGISTER, 1, DataType.FOUR_BYTE_BCD);
-
Modbus RTU getValue() parameters
Hello,
I want to use modbus4j to communicate with a slave device via serial.
The correct hex interogation is: 01 03 00 01 00 01 D5 CA - I tested this in another program(Docklight) and I got the desired response.
How would I go about translating this as parameters for getValue()?
What I've done was to create a ModbusFactory instance, set the serial params and create a ModbusMaster.
Now I need to do something like master.getValue(...);
I've read the documentation, but I'm not entirely sure what's the correct approach for this method's parameters.
I need a bit of help.
Thank you. -
RE: Modbus RTU getValue() parameters
Hello,
I want to use modbus4j to communicate with a slave device via serial.
The correct hex interogation is: 01 03 00 01 00 01 D5 CA - I tested this in another program(Docklight) and I got the desired response.
How would I go about translating this as parameters for getValue()?
What I've done was to create a ModbusFactory instance, set the serial params and create a ModbusMaster.
Now I need to do something like master.getValue(...);
I've read the documentation, but I'm not entirely sure what's the correct approach for this method's parameters.
I need a bit of help.
Thank you.