stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.33k stars 1.71k forks source link

multiple slaves with RTU communication #18

Closed artopta closed 12 years ago

artopta commented 13 years ago

Hi!

I've got a problem with RTU communication. On an RTU link (RS485) I've got one master and two slaves.

The problem is, that when a master starts a "modbus_read_input_registers" communication. The starting message arrives for both of the slave. The one, which is addressed acknowledges the message, creates the reply and sends it back. The other one, with different salve id, receives the first message, it sees that he is not the one who is addressed, so does nothing.

But when it receives the reply of the first slave, it reports an error, because of the wrong CRC. The problem is that, the reply is a longer message, and the second slave doesent see that, and checks the CRC from false part of the reply message.

How should I handle this situation?

Thanks in advance, Tamas

artopta commented 13 years ago

Hi guys!

I thought I will let you know, how I have solved this problem.

Instead of reading out a register, I'm reading out coils. If I want to be specific, then 24 bits. Because in this case all the messages have the same size.

In my case, because I try to read out two int-s, with one message, this means that each of the integers is 12 bit long, so the biggest number is 2047.

Regards, Tamas

stephane commented 12 years ago

Could provide the response received by the second slave? I don't understand why the second slave doesn't ignore the reply.

bartold commented 12 years ago

I have the same problem as artopta. The reply from the first slave will be seen as a new request in the other slaves. The receivefilter as I can see is made for real requests not replies. I made some debugs today and I can reproduce the problem. I don't really know how to solve this but maybeI can see two ways 1) enhance the filter but how to know when it's an reply 2) start with the adresscontrol and do the best as possible with the filter. Maybe I'm totally wrong. Regards Bertil

bartold commented 12 years ago

Hi again

Opening COM8 at 9600 bauds (N, 8, 1) Waiting for a indication...

<11><03><00><01><00><02><97><5B> Set an incorrect number of values [11][03][02][00][00][79][87] Waiting for a indication... <01><03><00><01><00><02><95> Set an incorrect number of values Request for slave 1 ignored (not17) Waiting for a indication... <01><03><04><00><1D><00><30><6A> Error CRC received 306A != CRC calculated 4DAA Quit the loop: Invalid CRC The correct answer is: 01 03 04 00 1D 00 30 6A 21 with dec value 29 and 48 The first answer in the logfile is from libmodbus slave itself and the second with address 1 is a controller. As you can see libmodbus see the second slave answer with address 1 as a request Any idea how to solve this Regards Bertil
stephane commented 12 years ago

libmodbus isn't time based so it doesn't wait for a fixed period to analyze request. A solution based on sleep and flush, can't be used as the slave we won't able to answer to next valid indication from master.

I think about some ideas to fix this issue but I'm not sure about the best solution.

  1. suppose the message is an indication and compute the length based on this assumption, if CRC is wrong, compute again the length as a confirmation (to read the missing bytes). Drawbacks, the indication must be shorter than the confirmation to avoid timeouts and it computes CRC whereas we don't care about the query.
  2. suppose the first message is an indication (as actually) if the not for us (as slave) toggle a flag to indicate reply_to_ignore next time. Read the indication (don't compute the CRC?). Next time, check the flag and compute the length as confirmation, toggle the flag. Each time the query is for us toggle the flag. Return 0 if not for us.

It's certainly possible to mix the 2 solutions to achieve more robust management.

stephane commented 12 years ago

Hey Folks,

Please test!