我将根据modbus-tcp规范进行读取/写入。因此,我正在尝试在linux环境中对客户端和服务器进行编码。(我将使用modbus-tcp与Windows程序(作为客户端)进行通信。)
但是它不能按我的要求工作,所以我在这里问你。
如果有人知道,请告诉我信息。
ctx = modbus_new_tcp("192.168.0.99", 502);
modbus_set_debug(ctx, TRUE);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n",
modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
tab_rq_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
memset(tab_rq_bits, 0, nb * sizeof(uint8_t));
tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
memset(tab_rp_bits, 0, nb * sizeof(uint8_t));
nb_loop = nb_fail = 0;
/* WRITE BIT */
rc = modbus_write_bit(ctx, addr, tab_rq_bits[0]);
if (rc != 1) {
printf("ERROR modbus_write_bit (%d)\n", rc);
printf("Address = %d, value = %d\n", addr, tab_rq_bits[0]);
nb_fail++;
} else {
rc = modbus_read_bits(ctx, addr, 1, tab_rp_bits);
if (rc != 1 || tab_rq_bits[0] != tab_rp_bits[0]) {
printf("ERROR modbus_read_bits single (%d)\n", rc);
printf("address = %d\n", addr);
nb_fail++;
}
}
printf("Test: ");
if (nb_fail)
printf("%d FAILS\n", nb_fail);
else
printf("SUCCESS\n");
free(tab_rq_bits);
free(tab_rp_bits);
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
return 0;
您在Modbus功能实际上正确之前看到的FF
。引用Modbus Implementation Guide,第23页:
在TCP / IP上,使用其IP地址寻址MODBUS服务器;因此,MODBUS单元标识符无效。必须使用值0xFF。
所以libmodbus只是坚持Modbus规范。那么,我假设问题出在easymodbus中,这显然希望您在查询中使用0x01
作为单位ID。
我想您不想弄乱easymodbus,因此您可以从libmodbus很容易地解决此问题:只需更改默认单位ID:
modbus_set_slave(ctx, 1);
您也可以使用:
rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
ASSERT_TRUE(rc != -1, "Invalid broadcast address");
如果您有多个,则使您的客户端寻址网络中的所有从属。
您可以在libmodbus man page for modbus_set_slave
function中获得更多信息并简要说明此问题的出处。
有关非常全面的示例,您可以检查modbus_set_slave
关于您的第5个问题,我不知道该如何回答,您所指的零应该是您要向线圈写入(或读取)的状态(真或假)。为了进行写入,您可以使用函数libmodbus unit tests的值字段进行更改。