C语言使用libmodbus库的Modbus TCP协议读取设备中的数据
- 2019 年 12 月 20 日
- 筆記
libmodbus是一个跨平台的modbus C语言库,目前支持的平台有:Linux, Mac OS X, FreeBSD, QNX以及Windows,其官网是:https://libmodbus.org,其源代码托管在github libmodbus,其安装和使用很简单,本人在Windows10下的Visual Studio2017以及在CentOS7下都使用过。 由于本人最近从事的工作是环保设备方面的,很多时候设备采用简单的Modbus工业协议,比如非甲烷总烃分析仪的Modbus地址定义如下表:
Modbus地址定义表
名称 |
数据 |
地址 |
系数 |
值 |
---|---|---|---|---|
系统参数 |
仪器状态 |
1 |
1 |
0 |
系统参数 |
运行状态 |
2 |
1 |
1 |
系统参数 |
控制指令 |
3 |
1 |
8 |
采样时间 |
年 |
10 |
1 |
2019 |
采样时间 |
月 |
11 |
1 |
11 |
采样时间 |
日 |
12 |
1 |
14 |
采样时间 |
时 |
13 |
1 |
14 |
采样时间 |
分 |
14 |
1 |
26 |
采样时间 |
秒 |
15 |
1 |
22 |
TVOC |
状态 |
20 |
1 |
0 |
TOVC |
峰面积 |
21 |
0.01 |
1908 |
总烃 |
浓度 |
22 |
0.01 |
254 |
CH4 |
状态 |
23 |
1 |
0 |
CH4 |
峰面积 |
24 |
0.01 |
1729 |
CH4 |
浓度 |
25 |
0.01 |
200 |
NMHC |
状态 |
26 |
1 |
0 |
NMHC |
峰面积 |
27 |
0.01 |
0 |
NMHC |
浓度 |
28 |
0.01 |
57 |
苯 |
状态 |
29 |
1 |
8 |
苯 |
峰面积 |
30 |
0.01 |
0 |
苯 |
浓度 |
31 |
0.01 |
0 |
甲苯 |
状态 |
32 |
1 |
8 |
甲苯 |
峰面积 |
33 |
0.01 |
0 |
甲苯 |
浓度 |
34 |
0.01 |
0 |
乙苯 |
状态 |
35 |
1 |
8 |
乙苯 |
峰面积 |
36 |
0.01 |
0 |
乙苯 |
浓度 |
37 |
0.01 |
0 |
间二甲苯 |
状态 |
38 |
1 |
8 |
间二甲苯 |
峰面积 |
39 |
0.01 |
0 |
间二甲苯 |
浓度 |
40 |
0.01 |
0 |
对二甲苯 |
状态 |
41 |
1 |
8 |
对二甲苯 |
峰面积 |
42 |
0.01 |
0 |
对二甲苯 |
浓度 |
43 |
0.01 |
0 |
间-对二甲苯 |
状态 |
44 |
1 |
8 |
间-对二甲苯 |
峰面积 |
45 |
0.01 |
0 |
间-对二甲苯 |
浓度 |
46 |
0.01 |
0 |
苯乙烯 |
状态 |
47 |
1 |
8 |
苯乙烯 |
峰面积 |
48 |
0.01 |
0 |
苯乙烯 |
浓度 |
49 |
0.01 |
0 |
邻二甲苯 |
状态 |
50 |
1 |
8 |
邻二甲苯 |
峰面积 |
51 |
0.01 |
0 |
邻二甲苯 |
浓度 |
52 |
0.01 |
0 |
非甲烷总烃分析仪有三个关键参数,即总烃、CH4、NMHC的浓度,对应Modbus寄存器地址分别为:22,25,28,获取对应寄存器数据后还需要乘以0.01
相应的代码如下:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <time.h> #include "modbus.h" //#include <windows.h> int main(int argc, char* argv[]) { // 定义存放数据的数组 uint16_t tab_reg[20] = { 0 }; const char* ip = "15.18.23.56"; int port = 502; // 创建libmobus TCP实例 modbus_t *pmbs_ctx = modbus_new_tcp(ip, port); modbus_set_debug(pmbs_ctx, 1); modbus_set_slave(pmbs_ctx, 1); // 设置从机地址 // 连接设备 int nRet = modbus_connect(pmbs_ctx); // 连接失败 if (-1 == nRet) { printf("connect failed:%sn", modbus_strerror(errno)); modbus_free(pmbs_ctx); return -1; } // 设置Modbus超时时间 struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000000; //设置modbus超时时间为1000毫秒 modbus_set_response_timeout(pmbs_ctx, tv.tv_sec, tv.tv_usec); // 每隔1秒钟发送Modbus TCP请求,读取对应寄存器并打印出数据 while (true) { printf("--------------------------------------------------n"); // 读取保持寄存器的值,起始地址为22,寄存器个数为10,读取到tab_reg数组中 int regs = modbus_read_registers(pmbs_ctx, 22, 10, tab_reg); // 获取当前时间 // 获取系统时间 time_t now_time = time(NULL); // 获取本地时间 struct tm* t_tm = localtime(&now_time); // 将时间转换为秒 //time_t mk_time = mktime(t_tm); // 输出当前时间 printf("当前数据时间为:%04d-%02d-%02d %02d:%02d:%02dn", t_tm->tm_year + 1990, t_tm->tm_mon + 1, t_tm->tm_mday, t_tm->tm_hour, t_tm->tm_min, t_tm->tm_sec); /*SYSTEMTIME sysTm; GetLocalTime(&sysTm); printf("%4d-%02d-%02d %02d:%02d:%02d.%03d 星期%1dn", sysTm.wYear, sysTm.wMonth, sysTm.wDay, sysTm.wHour, sysTm.wMinute, sysTm.wSecond, sysTm.wMilliseconds, sysTm.wDayOfWeek);*/ // 名称 数据 地址 系数 值 // 总烃 浓度 22 0.01 254 // CH4 浓度 25 0.01 200 // NMHC 浓度 28 0.01 57 printf("总烃的浓度为:%.3f ppmVn", tab_reg[0] * 0.01); printf("CH4的浓度为:%.3f ppmVn", tab_reg[3] * 0.01); printf("NMHC的浓度为:%.3f ppmVn", tab_reg[6] * 0.01); printf("--------------------------------------------------n"); Sleep(1000); } // 关闭modbus连接 modbus_close(pmbs_ctx); //释放modbus资源,使用完libmodbus需要释放掉 modbus_free(pmbs_ctx); getchar(); return 0; }
运行测试:
Connecting to 15.18.23.56:502 -------------------------------------------------- [00][01][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><01><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 当前数据时间为:2109-12-11 18:13:37 总烃的浓度为:3.050 ppmV CH4的浓度为:2.310 ppmV NMHC的浓度为:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][02][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><02><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 当前数据时间为:2109-12-11 18:13:38 总烃的浓度为:3.050 ppmV CH4的浓度为:2.310 ppmV NMHC的浓度为:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][03][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><03><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 当前数据时间为:2109-12-11 18:13:39 总烃的浓度为:3.050 ppmV CH4的浓度为:2.310 ppmV NMHC的浓度为:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][04][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><04><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 当前数据时间为:2109-12-11 18:13:40 总烃的浓度为:3.050 ppmV CH4的浓度为:2.310 ppmV NMHC的浓度为:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][05][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><05><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 当前数据时间为:2109-12-11 18:13:41 总烃的浓度为:3.050 ppmV CH4的浓度为:2.310 ppmV NMHC的浓度为:0.740 ppmV --------------------------------------------------