将线圈(位)写入Modbus PLC

时间:2017-12-03 07:14:35

标签: ios c swift4 modbus

写入Schneider Modicon M221 PLC时遇到问题。 我在Swift wrapper库周围使用LibModbus(在C中)。 我可以读取位并注册没有问题 - 只是似乎给他们 - 虽然我从设备获得“成功”响应。

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

斯威夫特(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”,但位状态保持不变。

开始怀疑这是施奈德专有的东西。

其他人都有过这方面的经验吗?

1 个答案:

答案 0 :(得分:1)

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

这里是SoMachine中设置的屏幕截图,以防其他人发现自己处于相同的情况:

enter image description here