Modbus serial - failed to read

Hi,

I have a problem with my serial modbus setup (small Arduino based nodes using SimpleModbusSlaveNG).
The symptoms are similar to what was described in this thread:
https://groups.google.com/forum/#!category-topic/openhab/modbus/gdtZCWvSP_U but I’m running openhab 1.7.1.

With one slave, even with default 200ms polling I see no errors in the log. As soon as I enable other slaves I get continuous stream of this:

2015-10-17 22:18:50.515 [ERROR] [i.modbus.io.ModbusRTUTransport] - Last request: 02 03 00 00 00 05 85 fa
2015-10-17 22:18:50.517 [ERROR] [i.modbus.io.ModbusRTUTransport] - failed to read: Error reading response
2015-10-17 22:18:50.518 [ERROR] [w.m.io.ModbusSerialTransaction] - execute try 1 error: I/O exception - failed to read
2015-10-17 22:18:51.063 [ERROR] [i.modbus.io.ModbusRTUTransport] - Last request: 47 03 00 00 00 05 8b 6f
2015-10-17 22:18:51.064 [ERROR] [i.modbus.io.ModbusRTUTransport] - failed to read: Error reading response
2015-10-17 22:18:51.066 [ERROR] [w.m.io.ModbusSerialTransaction] - execute try 1 error: I/O exception - failed to read
2015-10-17 22:18:51.842 [ERROR] [i.modbus.io.ModbusRTUTransport] - Last request: 02 03 00 00 00 05 85 fa
2015-10-17 22:18:51.845 [ERROR] [i.modbus.io.ModbusRTUTransport] - failed to read: Error reading response
2015-10-17 22:18:51.846 [ERROR] [w.m.io.ModbusSerialTransaction] - execute try 1 error: I/O exception - failed to read

relevant part of openhab.cfg:

modbus:serial.test2.id=2
modbus:serial.test2.connection=/dev/ttyUSB1:9600:8:none:1:rtu
modbus:serial.test2.type=holding
modbus:serial.test2.length=5

modbus:serial.test36.id=36
modbus:serial.test36.connection=/dev/ttyUSB1:9600:8:none:1:rtu
modbus:serial.test36.type=holding
modbus:serial.test36.length=5

modbus:serial.test71.id=71
modbus:serial.test71.connection=/dev/ttyUSB1:9600:8:none:1:rtu
modbus:serial.test71.type=holding
modbus:serial.test71.length=5

I spent a couple of days/nights trying to track this down. I assumed that this is caused by some collision on the bus (multiple threads polling at the same time?) so I added some more locks to force serialization of the requests (in both binding code and jamod) but the problem doesn’t want to go away.

I also noticed that there is one transaction object for each ModbusSlave and it’s not guarded so one can easily overwrite it if you for example click on a switch item while there’s an ongoing polling in the background. This leads to things like this:

2015-10-17 19:20:15.053 [INFO ] [.b.modbus.internal.ModbusSlave] - ModbusSlave error getting responce from slave:java.lang.ClassCastException: net.wimpi.modbus.msg.WriteSingleRegisterResponse cannot be cast to net.wimpi.modbus.msg.ReadMultipleRegistersResponse

Adding “synchronized (transaction)” here and there seems to fix this but the original “failed to read” problem persists. Actually, with fast polling I’m even able to get the “failed to read” errors with one slave plus clicking on the switch item in the UI.

I’m currently out of ideas so if anyone has any experience with this error or some other info which might be useful to track this down, please share :smile:

Regards
Jacek

Hi,
a couple of points there:

a) Turn verbosity of the logger up, by adding that to logback.xml

    <logger name="net.wimpi.modbus" level="trace"/>

(further information: https : //groups.google.com/d/topic/openhab/3GJwQu1CUS0)

b) There are currently a couple of troubles with the modbus serial module [2], including that it is unable to handle more than one modbus:serial.*.id [1] and a receive problem with (at least) the raspicomm module [3]
see:

So, try your connection with a single modbus:serial.*.id and I’m sorry to tell you, that there is nobody working on the Problems [1] and [3] right now.
Best

[1] Modbus RS485 · Issue #626 · openhab/openhab1-addons · GitHub
[2] https://groups.google.com/d/categories/openhab/modbus
[3] (new users can only put two links in a post, wtf) github .com/openhab/openhab/issues/2843

Hi,

Thanks for the hints. I gave up trying to fix openhab’s internal support for modbus/rtu.
I found another solution which works around some/most of the problems I described.
I added an additional service between openhab and the serial adapters used for modbus communication.
I used http://mbus.sourceforge.net/ which works as a modbus/tcp <-> modbus/rtu gateway.
Then I changed the configuration of openhab to use modbus/tcp which seems to work way better than the serial version.
Additional bonus is that now I can connect to the slaves from outside of openhab with some standalone modbus clients without disabling the modbus parts in openhab.

This setup is not perfect but fixes some of the problems and opens some additional possibilites so for now I’ll keep it running like this.

Regards
Jacek

Hello
Excuse me for my bad english

I made a similar network with Arduino. I think I have the same problem.
I saw that the time between each call to the slave is huge.
Reading time is very slow.
Modbus: poll = 10 or less, not resolved.

Could slave timeout causes the problem?

Regards.

Note that in openhab.cfg the modbus:poll parameter is in milliseconds so 10 is very fast polling. Default is 200 and I have it set to 1000 currently.

In my modbus arduino actually:

#define baud 19200
#define timeout 100
#define polling 20
#define retry_count 40

All in ms. I Have 11 Slaves (aprox 10 registers for slave). Master it takes 1 sec in scan all.
For me, is slow. 1000ms is very very slow. I’m opinion.

  1. I’m not sure I understand your setup. From your defines it seems that your master is an arduino not openhab. Correct me if I’m wrong.
  2. AFAIK the polling interval in openhab doesn’t mean delay between each poll operation but interval for each slave so even with 5 slaves if I have poll = 1000, each slave will be polled every 1s, not every 5s. I think this is where the original problem comes from: even with poll = 10000, all slaves are polled around the same time and then nothing is happening for 10s.
  3. again, using mbusd as a “proxy” between serial bus and openhab seems to handle the queuing of requests properly so you might want to give it a try.

This is a bit off-topic, but following up on the suggested workaround. That is, using a Modbus/TCP <-> Modbus/RTU gateway.
I’m planning on using a hardware gateway box, and really just want to confirm that the OH Modbus binding will try to work with multiple serial RTU slaves on one TCP gateway. So far as I can see, that just requires the binding to honour the “unit ID” address in the TCP package (which is normally redundant for a true TCP slave)

From the description of the software gateway workaround, it seems like it should work?

This may be a “nobody knows”, in which case I will try to add my own results at some later date.

The serial support in the binding really needs to be worked on.

You cannot send a couple of commands at a time and then somehow hope that some clients respond after a while. You can do so in Modbus TCP to a certain extent but that doesn’t work at all in Modbus serial!

Being a Modbus serial master works like this:

  1. Look at your queue, get the next client id, function code and data
  2. Wait 1,7ms (if you are doing 19200 baud or more)
  3. send the command
  4. start to listen, wait for data until timeout (modbus specs call for 1.x seconds here - which is a bit too much for most clients but some of them are really slow…), start again at 2 or stop doing anything and throw an error if there is no response
  5. if data starts to flow, receive and determine the end of the message by measuring the time between the received bytes. A gap of 1,7ms marks the end of the message. Of course, if you are the only Master on the bus, which is the only setup officially supported by plain Modbus, the gap will be indefinite. :smile:
  6. determine whether the CRC is correct
  7. parse the message,
  8. Look at your queue and get the next client id, function code and data, go back to 2

However accurately measuring time in the range of one or two milliseconds is impossible to do in Java, I suppose. Fortunately, we don’t really need to do that.

1 Like

IIRC the only difference between TCP and RTU versions of Modbus is the CRC. The slave ID is needed in both to properly address the devices.

[quote=“skazi, post:10, topic:3430, full:false”]
IIRC the only difference between TCP and RTU versions of Modbus is the CRC.[/quote]

That is not the only difference. In fact Modbus TCP embeds Modbus RTU into IP packets but without CRC. The important difference is somewhere else: There is no collision management in Modbus RTU at all and therefore no packet stack in Modbus serial clients. You can only talk to one client at a time. This is something I tried to point out in my earlier post. The serial port has to be locked until a client response has been received or a timeout interrupt has occured.

[quote]The MODBUS Serial Line protocol is a Master-Slaves protocol. Only one master (at the same time) is connected to the bus, and one
or several (247 maximum number) slaves nodes are also connected to the same serial bus. A MODBUS communication is always
initiated by the master. The slave nodes will never transmit data without receiving a request from the master node. The slave nodes
will never communicate with each other. The master node initiates only one MODBUS transaction at the same time.
[/quote] from the Modbus Implementation Guidelines http://www.modbus.org/docs/Modbus_over_serial_line_V1.pdf page 7

The timeout used in openhab’s modbus binding is also way too short, this can cause all sorts of problems with slow clients.

[quote]Typically the Response time-out is from 1s to
several second at 9600 bps [/quote] quoted from http://www.modbus.org/docs/Modbus_over_serial_line_V1.pdf page 10

Best regards.

This is clear (at least for me). RS485 is not Ethernet and Modbus/RTU is way different from Modbus/TCP when we go to the lower layers. What I meant is that in the Modbus payload, the slave ID is present in both versions and the only difference is in the CRC which would be redundant in the TCP version.

The current implementation of Modbus/RTU in openhab has many issues in my opinion, the timeout is only one of them. If you look at the sources in: bundles/binding/org.openhab.binding.modbus/src/main/java/net/wimpi/modbus/util/SerialParameters.java you’ll see something like this:

/**

  • Constructs a new SerialParameters instance with
  • default values: 9600 boud - 8N1 - ASCII.
    */
    public SerialParameters() {
    m_PortName = “”;
    m_BaudRate = 9600;
    m_FlowControlIn = SerialPort.FLOWCONTROL_NONE;
    m_FlowControlOut = SerialPort.FLOWCONTROL_NONE;
    m_Databits = SerialPort.DATABITS_8;
    m_Stopbits = SerialPort.STOPBITS_1;
    m_Parity = SerialPort.PARITY_NONE;
    m_Encoding = Modbus.DEFAULT_SERIAL_ENCODING;
    m_ReceiveTimeout = 500; //5 secs
    m_Echo = false;
    }//constructor

If I’m not mistaken, the timeout is in milliseconds which makes either the code or the comment incorrect.
In reality the timeout depends largely on the slaves (not only on the transmission speeds) and should probably be configurable.

You are probably right. My experience is that the timeout is definitely 500ms and not 5 seconds, therefore the comment is wrong and yes this must be configurable. Anyway, defaulting to 5 secs seems to be a good idea.
Have you tried to measure the time your Modbus devices need to respond or increased the timeout value? If the devices are way faster than 500ms we can rule out bus collisions due to timeouts on the openhab side of the bus.

If the binding worked correctly, it would be no problem to set the polling interval to zero milliseconds by default. A working binding would trigger all devices listed in the conf one after the other and always wait until timeout if there is no response… :smile:

Before I found mbusd, I tried to increase this timeout to 5000 to match the comment but it didn’t help much.
In my current setup, with mbusd added to the chain, the openhab’s Modbus/RTU implementation is not used at all so it’s hard to compare.
Anyway even with the TCP version I still see collisions when the write operation (i.e. clicking a switch in the gui) hits some periodic poll operation.

Collisions in Modbus TCP should not cause any issues. The devices will handle whatever request comes first and then take care of the next request.

Do these collisions in TCP that you mentioned cause any error messages in the openhab log or how do you know that they occur at all?

Maybe they’re not real “collisions” but openhab shows the infamous “ModbusSlave error getting responce from slave” when I trigger some write operation from the GUI. I’m guessing it’s not really queuing this operation until the current read is finished or something like this and then complaining about not getting the response from the read operation.
When I was testing it without the mbusd (which seems to do some queuing internally) I was getting lots of the “error getting responce” as soon as I added second slave to the config.

Yeah that’s a well known problem with the binding and serial modbus. As I’ve already pointed out in some other forum posts: the binding is unusable with >1 serial devices. Right now ssalonen is working on the binding and among other things is probably going to fix this issue :sunglasses: Let’s hope for the best.

I have the same problem.
My config is raspberry + RS485pi +2 Modbus kwh meter.