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:%s\n", 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:%02d\n", 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 星期%1d\n", 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 ppmV\n", tab_reg[0] * 0.01);
printf("CH4的浓度为:%.3f ppmV\n", tab_reg[3] * 0.01);
printf("NMHC的浓度为:%.3f ppmV\n", 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
--------------------------------------------------