尝试使用libmodbus
写在前面
之前的项目上使用了Python的minimalmodbus库,但是我感觉如果从站多了之后,性能会有所下降,所以一直想使用C语言来编写与传感器通信的程序,看看是否比Python更高效
libmodbus
从官网看libmodbus支持ModBus RTU和ModBus TCP模式,并且是开源软件。
目前有3.0.8和3.1.6两个版本,前者从2013年之后就没有更新过,推荐使用后者。
更多详情请参阅官方文档
编译安装libmodbus
根据其Github上的介绍,首先安装编译环境
apt-get install automake autoconf libtool gcc git -y
git clone https://github.com/stephane/libmodbus.git
cd libmodbus
./autogen.sh
./configure && make install
# 等待编译安装完成
# 测试
# 新建两个终端,分别运行tests目录下的
./unit-test-server
./unit-test-client
# 等待测试完成创建ModBus RTU环境
使用modbus_new_rtu来创建libmodbus rtu环境。函数详情:
modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit);
# 参数详情
# *device 通信端口
# baud 波特率
# parity 奇偶校验参数
# data_bit 数据位
# stop_bit 停止位当初始化完成,你需要使用 modbus_set_slave来设置从站id,使用modbus_connect来连接串口,以下是示例:
modbus_t *ctx;
ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return -1;
}
modbus_set_slave(ctx, YOUR_DEVICE_ID);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx); // modbus_free - free a libmodbus context 释放 libmodbus 环境
return -1;
}读取寄存器 modbus_read_registers
这里我用了一个温湿度传感器来做测试,之前的使用Python通过ModBus RTU 协议读取传感器数据也是一样。因为温湿度传感器自带显示界面,方便对比。
/*一个使用libmodbus库的测试程序*/
#include <stdio.h>
#include <modbus.h>
#include <errno.h>
int main(void)
{
modbus_t *ctx; // 创建一个指针
uint16_t tab_reg[32]; // 创建一个数组
int rc;
int i;
/*新建一个ModBus RTU 环境*/
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_set_slave(ctx, 1);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
/*读取一个寄存器地址*/
rc = modbus_read_registers(ctx,1,1,tab_reg);
if(rc == -1)
{
fprintf(stderr, "%s\n", modbus_strerror(errno));
return -1;
}
for (i = 0; i < rc; i++)
{
printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
}
modbus_close(ctx);
modbus_free(ctx);
return 0;
}保存为modbus_rtc.c,如果直接使用gcc编译会出现modbus.c:(.text+0x5c): undefined reference错误,相关链接:
gcc compile fail: undefined reference to `modbus_new_tcp'
libmodbus: how to compile application including libmodbus library?
解决方法在第二个链接里面:
在/etc/ld.so.conf.d/里面创建一个modbus.conf文件,写入/usr/local/lib,然后运行ldconfig -v。最后在编译的时候使用gcc <name>.c -o <name> -I /usr/local/include/modbus/ -lmodbus
这里我实际使用的是gcc modbus_rtu.c -o test -I /usr/local/include/modbus/ -lmodbus,然后运行./test


202表示现在温度是20.2度(我这里还没有做计算,因为传感器返回的就是202)。
接下来
接下来要做的就是将得到的数据写入到数据库里面。先到此为止吧。
参考资料:
https://github.com/stephane/libmodbus
https://libmodbus.org/
https://stackoverflow.com/questions/63142337/libmodbus-how-to-compile-application-including-libmodbus-library
https://github.com/stephane/libmodbus/issues/123
https://techoverflow.net/2019/06/20/how-to-fix-c-error-errno-undeclared/
评论已关闭