首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用libmodbus实现“读/写”函数?(C代码)

如何使用libmodbus实现“读/写”函数?(C代码)
EN

Stack Overflow用户
提问于 2019-10-31 16:04:00
回答 2查看 2.8K关注 0票数 2

我要按照modbus-tcp规范进行读写。因此,我试图在linux环境中对客户机和服务器进行编码。(我会使用modbus-tcp与windows程序(作为客户端)进行通信。)

但这不像我想的那样,所以我请你来这里。

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

错误结果:

预期结果:

  1. “00.00”;你知道在哪里控制这部分吗?
  2. 您知道使用libmodbus实现‘读/写’函数的示例代码吗?

如果你知道的话,请告诉我信息。

代码语言:javascript
运行
复制
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;
EN

回答 2

Stack Overflow用户

发布于 2019-10-31 17:32:28

在Modbus函数之前看到的FF实际上是正确的。引用Modbus实现指南,第23页:

在TCP/IP上,MODBUS服务器使用其IP地址进行寻址,因此MODBUS单元标识符是无用的。必须使用0xFF值。

所以libmodbus只是坚持Modbus规范。因此,我假设问题在easymodbus中,显然期望您在查询中使用0x01作为单元id。

我想您不想搞乱easymodbus,所以您可以很容易地从libmodbus中解决这个问题:只需更改默认的单元id:

代码语言:javascript
运行
复制
modbus_set_slave(ctx, 1);

你也可以这样做:

代码语言:javascript
运行
复制
 rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
 ASSERT_TRUE(rc != -1, "Invalid broadcast address");

使您的客户端地址在网络中的所有从站,如果您有多个。

您有更多的信息和一个简短的解释,这个问题是从哪里来的函数

对于一个非常全面的例子,您可以检查单元测试

关于你的第5个问题,我不知道如何回答,你的意思是零应该是你想要写(或读)到线圈的状态(真或假)。在编写时,您可以使用函数modbus_write_bit(ctx, address, value)的value字段来更改它们。

票数 3
EN

Stack Overflow用户

发布于 2019-11-01 08:40:51

我非常感谢你的答复。

我使用您推荐的“单元测试服务器/客户端”代码测试了读/写功能。我已经检查了代码,但是仍然有很多事情我不知道。

但是,有一个地址值在使用单元测试服务器/客户端代码相互测试后起作用,还有一个地址值不起作用(您知道为什么吗?)

-Checked并发现UT_BITS_ADDRESS (地址值)值在0x130到0x150之间运行-“错误非法数据地址”发生在-0x130以下和0x150 -The地址以下的值上,我想要读/写的地址是0x0001到0x0004(您知道如何做吗?)

我想知道如何处理和传输数据,如TX部分的正确图片。

在这里输入图像描述

我在Linux环境中同时运行客户机和服务器,并且正在进行读/写测试。在错误的照片中.06..。<--我想知道如何修改FF部件(将值更改为01,如图所示)。

在这里输入图像描述

"modbus_set_slave“是modbus的功能吗?最后,我想与PC程序和Linux设备进行通信。那么我该用哪一部分功能呢?

我再次感谢你的关心。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58647230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档