modbus通信减少等待超时的时间

时间:2014-08-07 16:32:07

标签: c++ connection-timeout modbus

我正在编写一个需要通过modbus连接到各种PLC的C ++应用程序,这些PLC的IP由用户输入提供。目前,当用户输入无法连接的IP时,我的程序会挂起大约2分钟,试图连接并且我的应用程序挂起2分钟不是一个选项。

示例程序说明了问题和我尝试的修复:

#include <modbus/modbus.h>
#include <string>
#include <errno.h>

#include <iostream>

#define PRINT_TIMEVAL(timeval) std::cout << "timeval sec: " << timeval.tv_sec << " usec: " << timeval.tv_usec << std::endl;

int main()
{
    std::string ip = "192.168.2.5";
    int port = 502;
    int slaveNum = 1;
    int address = 1;
    int nb = 1;

    struct timeval currentTimeout;

    struct timeval responseTimeout;
    responseTimeout.tv_sec = 1;
    responseTimeout.tv_usec = 0;

    struct timeval byteTimeout;
    byteTimeout.tv_sec = 1;
    byteTimeout.tv_usec = 0;

    modbus_t *mb = modbus_new_tcp(ip.c_str(), port);
    modbus_set_debug(mb, true);
    modbus_set_error_recovery(mb, MODBUS_ERROR_RECOVERY_NONE);
    modbus_flush(mb);
    modbus_set_slave(mb, slaveNum);

    modbus_get_response_timeout(mb, &currentTimeout);
    PRINT_TIMEVAL(currentTimeout);

    modbus_set_response_timeout(mb, &responseTimeout);

    modbus_get_response_timeout(mb, &currentTimeout);
    PRINT_TIMEVAL(currentTimeout);

    modbus_get_byte_timeout(mb, &currentTimeout);
    PRINT_TIMEVAL(currentTimeout);

    modbus_set_byte_timeout(mb, &byteTimeout);

    modbus_get_byte_timeout(mb, &currentTimeout);
    PRINT_TIMEVAL(currentTimeout);

    std::cout << "About to connect to " << ip << std::endl;
    int errno;
    if((errno = modbus_connect(mb)))
    {
        std::cout << "Error when connecting: " << modbus_strerror(errno) << std::endl;
    }
    std::cout << "Done connecting to " << ip << std::endl;

    modbus_close(mb);
    modbus_free(mb);

    return 0;
}

正如您所看到的,我已尝试将响应和字节超时变量设置为1秒(我还尝试过500和5000微秒)。当我读取超时值时,它们已被正确设置,因此我假设它们与初始连接尝试没有任何关系。我还尝试将错误恢复模式显式设置为none,以防它尝试自行重新连接。

我想在x时间之后停止modbus_connect或者在尝试通过modbus连接之前检查IP是否有效的另一个命令,这也需要在短时间后超时时间。

我使用的是libmodbus 3.0.1-2版本

2 个答案:

答案 0 :(得分:1)

问题出在我的libmodbus版本(3.0.1)上,这是当前的发行版本。在那个版本中,他们使用的是linux connect命令,但他们没有传递NONBLOCKING标志,因此connect将被阻止2m7s。我们通过升级到libmodbus v3.1.1解决了这个问题,它被标记为不稳定但未处于活动开发状态(它们是在v3.1.2上开发的)。不幸的是,该版本的libmodbus不适用于Windows。

答案 1 :(得分:0)

使用线程侦听每个设备并将这些消息推送到可以在不占用其他线程的情况下处理的队列。