admin管理员组

文章数量:1134085

The program is coded in C++, and the PLC is Siemens 1515T. The connection was always good, but read/write were failed in a kind of interval manner.

The first time I run the program, libmodbus could establish the connection and made read/write successfully. The 2nd time I run the program, the connection was still good, but read/write were all failed with timed out error. And the 3rd time, read/write were good, and the 4th were failed, and so on.

I also tried Modbus Slave to simulate PLC, and everytime the program were good. The PLC guy and I totally have no idea about this situation.

Could anybody give us suggestion?

Code example:

bool ModbusDevice::connect() {
    static std::shared_ptr<spdlog::logger> logger = get_module_logger("PLC:connect");
    logger->debug("Connecting to IP:{} Port:{}", _ip_address, _port);
    mb_ctx = modbus_new_tcp(_ip_address, _port);
    modbus_set_debug(mb_ctx, TRUE);
    modbus_set_slave(mb_ctx, 1);
    modbus_set_response_timeout(mb_ctx, 10, 1000000);
    if (mb_ctx == nullptr) {
        logger->error("Unable to allocate libmodbus context.");
        return false;
    }
    modbus_set_debug(mb_ctx, FALSE);
    if (modbus_connect(mb_ctx) == -1) {
        logger->error("Connection failed with {}", modbus_strerror(errno));
        modbus_free(mb_ctx);
        mb_ctx = nullptr;
        return false;
    }
    is_connect=1;
    logger->info("Connected to Modbus device at {}:{}", _ip_address, _port);
    return true;
}

bool ModbusDevice::readRegister(int address, int &message, int num_registers=1) {
    static std::shared_ptr<spdlog::logger> logger = get_module_logger("PLC:readRegister_Int");
    logger->debug("Enter Address:{:#04x} Num:{}", address, num_registers);
    std::lock_guard<std::mutex> lock(mutex);
    if (mb_ctx == nullptr) {
        logger->error("[PLC:readRegister_Int] Not connected to any Modbus device.");
        return false;
    }

    auto *value = new uint16_t[num_registers];
    uint16_t result;

    if (modbus_read_registers(mb_ctx, address, num_registers, value) == -1) {
        logger->error("Failed to read register with {}", modbus_strerror(errno));
        delete[] value;
        return false;
    } else {
        message = static_cast<int>(value[0]);
        logger->info("Address:{:#04x} Num:{} Result:{}", address, num_registers , message);
        return true;
    }
}

Error Logs:

Connecting to 10.40.103.132:502
Loading System is running, DO NOT CLOSE!!!
[00][01][00][00][00][06][01][06][00][63][00][00]
Waiting for a confirmation...
[00][01][00][00][00][06][01][03][00][14][00][01]
Waiting for a confirmation...
ERROR timed out: select
error Failed to read register with timed out

本文标签: clibmodbus readwrite got success and timed out result in a kind of interval mannerStack Overflow