stephane / libmodbus

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

RTU: modbus_set_slave() followed by modbus_read_inputs_bits() throws error as connection timed out #382

Closed modbusdev closed 7 years ago

modbusdev commented 7 years ago

libmodbus version = 3.0.6

OS and/or distribution = Ubuntu 14.04

Environment = Intel 64bit

Description

I am using libmodbus 3.0.6 version of the library. My application runs as modbus rtu poll that can send poll requests for 2 slave devices - id 1 and id 2. I am sending few poll messages for slave id 1 and then switching to slave id 2. Before sending poll message for slave id 2, I call modbus_set_slave() with slave id as 2. The set slave function returns 0 (success) and then I call modbus_read_input_bits() with appropriate values. But the poll message is not going out rather I am getting error as "Error: Connection timed out: Select". Even though the poll message for read inputs returned with an error I am sending an other poll message for different register address for the same slave (id 2) and that poll message goes out without any error and I also get response back from the slave device. The error happens only for the 1st poll message after the slave id has been changed. I tested the slave device with 'Modbus Poll' software to ensure that it is not problem with the slave devices.

Expected behaviour

Without any error poll message is expected to go out

Actual behaviour

ERROR Connection timed out: select

Steps to reproduce the behavior (commands or source code)

Modbus RTU device that sends out poll request to 2 slave ids - id 1 and id 2. After sending 5-6 poll requests for slave id 1, call set slave api with slave id as 2 and immediately call modbus read input bits api.

libmodbus output with debug mode enabled

[01][03][04][4C][00][14][85][22] Waiting for a confirmation...

<01><03><28><80><8E><00><02><67><71><00><04><00><01><9B><00><04><00><08><91><92><00><06><04><70><00><02><79><00><06><6F><95><00><02><00><03><91> [01][03][04][B0][00][14][45][12] Waiting for a confirmation... <01><03><28><25><36><48><9D><0E><49><13><7D><2D><48><17><48><19><40><48><1F><20><48><06><15><00><47><16><5A><48><89><23><48><20><14><48><7A><3D><7F> [02][02][03][E8][00][14][F8][46] Waiting for a confirmation... **ERROR Connection timed out: select Opening /dev/ttymxc2 at 9600 bauds (N, 8, 1)** [02][03][03][E8][00][14][C5][86] Waiting for a confirmation... <02><03><28><2E><3C><00><10><80><39><90><36><2E><14><28><3C><00><21><30><30><00><2E><3C><00><10><80><39><90><36><2E><14><28><3C><00><21><30><30><00><4E>
karlp commented 7 years ago

Do your devices have an requirements on time between requests? I suspect you're not meeting them.

modbusdev commented 7 years ago

@karlp I have to send 5 poll messages to slave id 1 and 2 poll messages to slave id 2 and all the messages have been configured to go out every 500ms. So in a loop I am sending poll messages starting with slave id 1 - send msg1 on response process it then send msg 2.... and set slave id 2 before sending msg1 for slave id 2. When I do that I am getting the error stated above. Slave devices have been configured with 3 second as connection timeout.

start loop

loop again

If I add wait for 35ms (minimum) between set slave id 2 and poll message 1 for slave id 2, everything works without any error.

Please follow this link for additional information and sample code http://stackoverflow.com/questions/34387820/multiple-rs485-slaves-with-libmodbus

karlp commented 7 years ago

yes. I believe you are not observing slave2's minimum time between frames. Becuase your host computer is "instant" compared to the modbus line, slave2 is seeing the response from slave1 and then "instantly" seeing the request from you. This is (probably) violating that devices minimum interframe timing, and fails. slave 1 never fails because it's after the 500ms delay. you have no delay between subsequent queries of the same device, but that's ok, because you're simply waiting for their response in those cases.

karlp commented 7 years ago

(separately, the "modbus_rtu_set_serial_mode(modbus, MODBUS_RTU_RS485);" call is almost defiinitely NOT what you want to do with a usb rs485 adapter.)

stephane commented 7 years ago

Thank you @karlp for your help.