写线圈(位)到Modbus PLC

Writing coil (bit) to Modbus PLC

我在写入 Schneider Modicon M221 PLC 时遇到问题。 我正在使用 Swift wrapper around the LibModbus 库(C 语言)。 我可以 读取 位和寄存器没问题 - 只是似乎无法 写入 给他们 - 尽管我从设备。

就像使用函数 05 将“true”写入位 0 一样简单。

Swift(4) 调用:

@objc func writeToPLC() {

    swiftLibModbus.writeBit(address: 0, status: true,
                            success: {
                                    print("writeBit Success")

    },
                            failure: { (error:NSError) in
                                print("Error in WriteBit")

    })

}

在 Swift/ObjC SwiftLibModbus 包装器中写入此函数:

func writeBit(address: Int32, status: Bool, success: @escaping () -> Void, failure: @escaping (NSError) -> Void) {
    modbusQueue?.async {
        if modbus_write_bit(self.mb!, address, status ? 1 : 0) >= 0 {
            DispatchQueue.main.async {
                success()
            }
        } else {
            let error = self.buildNSError(errno: errno)
            DispatchQueue.main.async {
                failure(error)
            }
        }
    }
}

写入库中的这些 C 函数:

int modbus_write_bit(modbus_t *ctx, int addr, int status){
return write_single(ctx, _FC_WRITE_SINGLE_COIL, addr,
                    status ? 0xFF00 : 0);
}

然后:

static int write_single(modbus_t *ctx, int function, int addr, int value){
int rc;
int req_length;
uint8_t req[_MIN_REQ_LENGTH];

req_length = ctx->backend->build_request_basis(ctx, function, addr, value, req);

rc = send_msg(ctx, req, req_length);
if (rc > 0) {
    /* Used by write_bit and write_register */
    uint8_t rsp[_MIN_REQ_LENGTH];
    //printf("Print %s, %s, %d ", req, rsp, rc);
    rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
    if (rc == -1)
        return -1;

    rc = check_confirmation(ctx, req, rsp, rc);

}

return rc;}

_FC_WRITE_SINGLE_COIL常数为0x05
_MIN_REQ_LENGTH 常量是 12

当 运行 时,我在控制台中得到 "writeBit Success",但位状态保持不变。

开始怀疑它是否是 Schneider 的专有产品。

还有其他人在这方面有经验吗?

好的,所以我发现我做错了什么。我没有正确设置单位 ID。当它应该是“255”时它是“1”。

这是 SoMachine 中设置的屏幕截图,以防其他人遇到相同情况: