写线圈(位)到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 中设置的屏幕截图,以防其他人遇到相同情况:
我在写入 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 中设置的屏幕截图,以防其他人遇到相同情况: