gpt4 book ai didi

在 C 中使用 Modbus 创建一个简单的客户端/服务器

转载 作者:太空狗 更新时间:2023-10-29 16:53:25 30 4
gpt4 key购买 nike

我目前正在从事一个项目,该项目将允许不同的自动化设备进行通信。为此,我想创建一个使用 modbus 协议(protocol)进行通信的客户端和服务器。我不确定现在是否要使用 ModBus/TCP、ModBus/RTU 或 ModBus/ASCII。

我在 C 中搜索了客户端/服务器示例,我可以找到库,但没有简单的通信示例。我想从头开始,所以图书馆不是我要找的东西。

我想问的是,是否有人可以给我一个用 C 编写的简单代码,用于使用 Modbus 进行通信的客户端和/或服务器,因为我不确定我将使用任何类型的 Modbus 是什么一个很大的帮助(RTU/TCP/ASCII)。

越简单越好,我希望代码演示的是,例如:对服务器的初始化、请求、应答、关闭连接。

非常感谢您的宝贵时间。

最佳答案

三件事:

  1. 当您开发自己的客户端和服务器组件时,我建议您仅在严格要求或方便且开放的情况下使用 Modbus(即其他制造商必须能够通过以下方式与您的客户端或服务器组件通信)标准化协议(protocol) - Modbus 适合)。
  2. 请注意,Modbus TCP 不仅仅是 TCP/IP 上的 Modbus RTU(/ASCII)(仍然允许,当然,UDP 也将被允许)。需要考虑一些重要的差异。
  3. 我知道您需要更深入地了解 Modbus。到那时,一旦您的 C 程序中有一个开放的串行 channel 或(监听)TCP 套接字,您就可以从简单的 Modbus 请求/响应开始。

看看这个short but quite complete description ,以及此 constantly updated library 的文档.


这是基于 libmodbus 的 Linux 的 super 简化 RTU 示例.
请允许我对 C99 的紧凑性进行一些放松。
在现实世界中,您还应该正确处理 SIGTERM 等信号...
对于 2.6.28 及更高版本的 Linux 内核,还有一个 modbus_rtu_set_serial_mode(RS232 与 RS485)函数。您可能会发现其他库可以在您的平台上更轻松地使用 RS485。

主片段

//Create a new RTU context with proper serial parameters (in this example,
//device name /dev/ttyS0, baud rate 9600, no parity bit, 8 data bits, 1 stop bit)
modbus_t *ctx = modbus_new_rtu("/dev/ttyS0", 9600, 'N', 8, 1);
if (!ctx) {
fprintf(stderr, "Failed to create the context: %s\n", modbus_strerror(errno));
exit(1);
}

if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Unable to connect: %s\n", modbus_strerror(errno));
modbus_free(ctx);
exit(1);
}

//Set the Modbus address of the remote slave (to 3)
modbus_set_slave(ctx, 3);


uint16_t reg[5];// will store read registers values

//Read 5 holding registers starting from address 10
int num = modbus_read_registers(ctx, 10, 5, reg);
if (num != 5) {// number of read registers is not the one expected
fprintf(stderr, "Failed to read: %s\n", modbus_strerror(errno));
}

modbus_close(ctx);
modbus_free(ctx);

从属片段

//Prepare a Modbus mapping with 30 holding registers
//(plus no output coil, one input coil and two input registers)
//This will also automatically set the value of each register to 0
modbus_mapping_t *mapping = modbus_mapping_new(0, 1, 30, 2);
if (!mapping) {
fprintf(stderr, "Failed to allocate the mapping: %s\n", modbus_strerror(errno));
exit(1);
}


//Example: set register 12 to integer value 623
mapping->tab_registers[12] = 623;


modbus_t *ctx = modbus_new_rtu("/dev/ttyS0", 9600, 'N', 8, 1);
if (!ctx) {
fprintf(stderr, "Failed to create the context: %s\n", modbus_strerror(errno));
exit(1);
}

//Set the Modbus address of this slave (to 3)
modbus_set_slave(ctx, 3);


if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Unable to connect: %s\n", modbus_strerror(errno));
modbus_free(ctx);
exit(1);
}


uint8_t req[MODBUS_RTU_MAX_ADU_LENGTH];// request buffer
int len;// length of the request/response

while(1) {
len = modbus_receive(ctx, req);
if (len == -1) break;

len = modbus_reply(ctx, req, len, mapping);
if (len == -1) break;
}
printf("Exit the loop: %s\n", modbus_strerror(errno));

modbus_mapping_free(mapping);
modbus_close(ctx);
modbus_free(ctx);

关于在 C 中使用 Modbus 创建一个简单的客户端/服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29602698/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com