problem in rlmodbusclient with negative values
Closed this issue · 9 comments
Hi!
I've encounter a problem writting signed integer with function:
writePresetSingleRegister(int slave, int adr, int value)
the problematic line is:
data[2] = value/256; data[3] = value & 0x0ff;
where I think we find a calculation error in value/256 , changing this, perhaps a little bit out of control operation (unsigned char = int/int), with a bit moving operation solve the issue for me.
data[2] = value>>8; data[3] = value & 0x0ff;
So that, I can now correctly write/read signed integers to a PLC.
Also:
- perhaps we should also check int (32 bits) limits to fit in a 16 bits INT/WORD
- perhaps we should treat address also in the way: addr>>8 to avoid possible problems? (I'm not sure as address should be always unsigned)
- perhaps we should build another abstraction layer where writeInt, writeFloat, etc.?
cheers, and thanks for the effort!
pd: tests I did:
----- FOR VALUE: 32643 -----
RLMODBUSCLIENT: old telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:127 lowvalue:131
RLMODBUSCLIENT: new telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:127 lowvalue:131
----- FOR VALUE: -32643 -----
RLMODBUSCLIENT: old telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:129 lowvalue:125
RLMODBUSCLIENT: new telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:128 lowvalue:125
----- FOR VALUE: 255 -----
RLMODBUSCLIENT: old telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:0 lowvalue:255
RLMODBUSCLIENT: new telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:0 lowvalue:255
----- FOR VALUE: -255 -----
RLMODBUSCLIENT: old telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:0 lowvalue:1
RLMODBUSCLIENT: new telegram, slave:1 , highaddress:3 lowaddress:232, highvalue:255 lowvalue:1
Hi
What are you trying to achieve?
craig
Hi Rainer!
I already know modbus is simply communicating unsigned bytes, but I feel a bit confused with the function, as it allows signed int (32bit) as parameter!
Taking care of the line I say, we can use the function for both 16-bit WORD and 16-bit INT. (I've tested it in a Schneider M340 PLC)
just now it's only for 16-bit WORD. So another solution could be accept only unsigned 16 bit int as parameter. (libmodbus does that)
at least it's what a I think :-D I don't feel 100% sure about.
cheers!
Joa
Hi Rainer!
ok, I'm not used to use union's :-S so the best sollution you think I guess it will the best.
For now I've been using an upper layer.
So I like the point of view of communications staying the simplest and other tools above for managing more complex data.
my questions are:
- why not use bit moving operation here?
- perhaps at least we should, at documentation, inform that function really expects a 16 bit unsigned int?
Joa
Hello Joa,
up to now i did not really use the github issue tracker.
May be github should be used more in future.
I added the solution with the union now to the repository. See:
https://github.com/pvbrowser/pvb/blob/master/rllib/lib/rlmodbus.h
Within the Doxygen comment an example for using the union is included.
If you feel that we should have more "conveniance methods" for the different data types,
please send a patch that does it the way you would do it.
Rainer
perfect!
ps: have you got any other platform for issues and/or patches? I really don't like github either :-D
There is a little playground at https://github.com/pvbrowser/pvbaddon
There we could create demos / templates that solve a problem we are currently working on.
Within that code we could extend our libraries / document our solution.
Later the extensions can be pulled into the main repository or our documentation.
any other platform ?
There is https://groups.yahoo.com/neo/groups/pvbrowser/conversations/topics
But people do no longer seem to like it.