1.三方库网址
Python:
- pymodbus:
- GitHub: pymodbus
- Description: 一个用于 Python 的 Modbus 实现,支持 TCP 和 RTU(串行)通信。
- minimalmodbus:
- GitHub: minimalmodbus
- Description: 适用于 Python 的轻量级 Modbus RTU/ASCII master。
Java:
- j2mod:
- GitHub: j2mod
- Description: 用于 Java 的 Modbus 协议实现。
C/C++:
- libmodbus:
- GitHub: libmodbus
- Description: 一个用于 C 语言的 Modbus 协议库,支持 Modbus TCP 和 Modbus RTU。
JavaScript (Node.js):
- jsmodbus:
- GitHub: jsmodbus
- Description: 一个用于 Node.js 的 Modbus 协议库。
C#:
- NModbus:
- GitHub: NModbus
- Description: 适用于 C# 的 Modbus 协议库。
2.常见函数说明(针对c/c++)
(1) modbus_set_slave
int modbus_set_slave(modbus_t *ctx, int slave)
参数说明:
- ctx:指向 Modbus 上下文结构的指针,该结构包含了与 Modbus 通信相关的所有信息,如连接信息、通信参数等。
- slave:要设置的 Modbus 从机的地址。Modbus 通信中,每个从机都有一个唯一的地址,主机通过设置从机地址来与特定从机通信。
返回值:
- 如果设置从机地址成功,则返回值为 0;
- 如果出现错误,返回值为 -1,并且错误代码会被设置在
errno
变量中,可以通过modbus_strerror(errno)
函数获取错误信息。
功能:
modbus_set_slave
函数用于设置 Modbus 从机的地址,以便在之后的通信中与指定的从机进行通信。- 该函数会在 libmodbus 的上下文中设置从机地址,以确保后续的 Modbus 操作会发送到正确的从机。
示例用法:
modbus_t *ctx;
ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return -1;
}
// 设置 Modbus 从机地址为 1
if (modbus_set_slave(ctx, 1) == -1) {
fprintf(stderr, "Error setting Modbus slave address\n");
modbus_free(ctx);
return -1;
}
// 使用 ctx 进行后续的 Modbus 操作
(2)modbus_read_registers
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
参数说明:
- ctx:指向 Modbus 上下文结构的指针,包含了与 Modbus 通信相关的所有信息。
- addr:起始寄存器的地址,即要读取的保持寄存器的起始地址。
- nb:要读取的保持寄存器的数量。
- dest:存储读取结果的缓冲区,通常是一个
uint16_t
类型的数组。
返回值:
- 如果读取寄存器成功,则返回值为读取的寄存器数量;
- 如果出现错误,返回值为 -1,并且错误代码会被设置在
errno
变量中,可以通过modbus_strerror(errno)
函数获取错误信息。
功能:
modbus_read_registers
函数用于从 Modbus 从机读取连续的保持寄存器的值。- 该函数会从指定地址开始读取指定数量的保持寄存器的值,并将结果存储在提供的缓冲区中。
示例用法:
modbus_t *ctx;
ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return -1;
}
if (modbus_set_slave(ctx, 1) == -1) {
fprintf(stderr, "Error setting Modbus slave address\n");
modbus_free(ctx);
return -1;
}
// 从地址 0 开始读取 10 个保持寄存器的值
uint16_t data[10];
int num_read = modbus_read_registers(ctx, 0, 10, data);
if (num_read == -1) {
fprintf(stderr, "Error reading registers: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
// 打印读取的寄存器值
for (int i = 0; i < num_read; i++) {
printf("Register %d: %d\n", i, data[i]);
}
modbus_free(ctx);
在上面的示例中,首先创建了一个 libmodbus 上下文 ctx
,设置了从机地址,然后使用 modbus_read_registers
函数从从机地址为 1 的设备读取了起始地址为 0 的 10 个连续保持寄存器的值,并将结果存储在 data
数组中。最后打印了读取的寄存器值。
(3)modbus_write_register
int modbus_write_register(modbus_t *ctx, int addr, uint16_t value)
参数说明:
- ctx:指向 Modbus 上下文结构的指针,包含了与 Modbus 通信相关的所有信息。
- addr:要写入的寄存器的地址。
- value:要写入的寄存器的值。
返回值:
- 如果写入寄存器成功,则返回值为 1;
- 如果出现错误,返回值为 -1,并且错误代码会被设置在
errno
变量中,可以通过modbus_strerror(errno)
函数获取错误信息。
功能:
modbus_write_register
函数用于向指定地址的寄存器写入一个 16 位的值。- 该函数会将指定的值写入指定地址的寄存器。
示例用法:
modbus_t *ctx;
ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return -1;
}
if (modbus_set_slave(ctx, 1) == -1) {
fprintf(stderr, "Error setting Modbus slave address\n");
modbus_free(ctx);
return -1;
}
// 将值 100 写入地址为 0 的寄存器
int addr = 0;
uint16_t value = 100;
if (modbus_write_register(ctx, addr, value) == -1) {
fprintf(stderr, "Error writing register: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
printf("Successfully wrote value %d to register %d\n", value, addr);
modbus_free(ctx);
在上述示例中,首先创建了一个 libmodbus 上下文 ctx
,设置了从机地址,然后使用 modbus_write_register
函数将值 100 写入地址为 0 的寄存器。若写入成功,会打印成功写入的信息。
(4)modbus_new_rtu
modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bits, int stop_bits)
参数说明:
- device:串行端口设备的名称,如 "/dev/ttyUSB0"。
- baud:波特率(通信速率),如 9600。
- parity:奇偶校验位,可以是 'N'(无校验)、'E'(偶校验)或 'O'(奇校验)。
- data_bits:数据位的位数,通常为 8。
- stop_bits:停止位的位数,通常为 1。
返回值:
- 返回一个指向新创建的 Modbus 上下文结构的指针,如果创建失败则返回
NULL
。
功能:
modbus_new_rtu
函数用于创建一个 Modbus RTU 上下文,用于与串行设备进行通信。- 它会初始化 Modbus 上下文,并设置通信参数,以便与 Modbus 从机进行通信。
示例用法:
modbus_t *ctx;
ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return -1;
}
// 在这里可以继续配置 Modbus 上下文,并进行通信操作
modbus_free(ctx); // 使用完毕后记得释放上下文
在上述示例中,modbus_new_rtu
函数用于创建一个 Modbus RTU 上下文 ctx
,指定了串行设备的名称为 "/dev/ttyUSB0",波特率为 9600,无奇偶校验,8 位数据位和 1 位停止位。如果成功创建上下文,就可以继续配置该上下文并进行 Modbus 通信操作。最后,在使用完成后,需要通过 modbus_free(ctx)
函数释放上下文的资源。