pvbrowser/pvb

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.