如何使用libmodbus进行“读/写”功能?(C代码)

问题描述 投票:0回答:1

我将根据modbus-tcp规范进行读取/写入。因此,我正在尝试在linux环境中对客户端和服务器进行编码。(我将使用modbus-tcp与Windows程序(作为客户端)进行通信。)

但是它不能按我的要求工作,所以我在这里问你。

  1. 我正在测试作为客户端的linux和作为服务器的easymodbus的客户端代码。
  2. 我使用了libmodbus代码。
  3. 我想读取线圈(0x01)和写入线圈(0x05)。
  4. 使用libmodbus执行代码时,从单元ID部分打印出'ff'。(根据手册,对于modbus-tcp,应输出01。我不知道为什么要打印'ff'(附照片)。

enter image description here

enter image description here

  1. '[00] [00] .... [00]';你知道在哪里控制这部分吗?
  2. 您是否拥有或知道使用libmodbus实现'读/写'功能的示例代码?

如果有人知道,请告诉我信息。

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 modbus-tcp
1个回答
1
投票

您在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的值字段进行更改。

© www.soinside.com 2019 - 2024. All rights reserved.