Windows10中VS2017环境下使用libmodbus库Modbus TCP读取设备的数据

时间:2022-07-25
本文章向大家介绍Windows10中VS2017环境下使用libmodbus库Modbus TCP读取设备的数据,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

libmodbus库中使用Modbus TCP协议

TCP(IPv4)环境 TCP后端实现了用于通过TCP / IPv4网络进行通信的Modbus变体。它不需要校验和计算,因为底层TCP会处理相同的功能。

//例子:
	modbus_t *ctx;
	int rc = 0;
	// 以下申请内存块,用以保存接收数据
	uint16_t *tab_rp_registers = (uint16_t*)malloc(10 * sizeof(uint16_t));
	memset(tab_rp_registers, 0, 10 * sizeof(uint16_t));

	// TCP
	// 创建Modbus TCP连接,IP是15.18.200.23,端口502
	ctx = modbus_new_tcp(15.18.200.23", 502);		// 创建一个TCP类型的容器
	modbus_set_debug(ctx, TRUE);					// 设置Debug模式

	if (modbus_connect(ctx) == -1)					// TCP 模式下连接Server
	{
		fprintf(stderr, "Connection failed:%sn", modbus_strerror(errno));
		modbus_free(ctx);
		return -1;
	}

	// 读取非甲烷总烃的关于总烃、甲烷、NMHC这3个寄存器(寄存器地址分别为22,25,28)中的浓度
	// 从寄存器地址22开始读取,读10个寄存器到data数组中
	//进行读取测试,起始地址为22,读取寄存器数目为10
	rc = modbus_read_registers(ctx, 22, 10, tab_rp_registers);

	printf("----------------- 甲烷/非甲烷总烃分析仪 TE_5900 -------------------------------n");
	printf("CH4的浓度为:%.3f ppmV,NMHC的浓度为:%.3f ppmV,总烃的浓度为:%.3f ppmVn",
		tab_rp_registers[3] / 100.0f, tab_rp_registers[6] / 100.0f, tab_rp_registers[0] / 100.0f);

创建Modbus TCP环境 modbus_t *modbus_new_tcp(const char *ip, int port); ip:希望连接的服务器ip地址

port:要使用的 TCP 端口。将端口设置为MODBUS_TCP_DEFAULT_PORT使用默认值之一 (502)。使用大于或等于1024的端口号很方便, 因为没有必要拥有管理员权限。

返回:成功返回指向modbus_t结构体的指针。否则, 它应返回 NULL 并将 errno 设置为An invalid IP address was given.

下面使用Modbus TCP协议读取甲烷/非甲烷总烃 (5900)设备中总烃、甲烷、NMHC这3个寄存器(寄存器地址分别为22,25,28)中的浓度。

非甲烷总烃设备的Modbus寄存器地址定义表

例如,要读取非甲烷总烃设备的总烃、甲烷CH4、NMHC非甲烷总烃对应的浓度, 相关监测因子参数的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

在Windows10下VS2017中,使用libmodbus库,使用Modbus TCP协议读取对应寄存器中的数据

相关C语言测试代码如下:

#include <stdio.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include "modbus.h"			// 引入libmodbus库

#pragma comment(lib, "modbus.lib")

int modbus_tcp_client_test02()
{
	// 主机地址:15.18.200.23 主机端口:502
	modbus_t *ctx;
	int rc = 0;
	// 读取的寄存器起始地址
	int addr = 22;
	// 读取的寄存器数据个数
	int nb = 10;
	// 用于保存接收数据
	uint16_t *tab_rp_registers;

	// TCP
	// 创建Modbus TCP连接,IP是15.18.200.23,端口502
	ctx = modbus_new_tcp("15.18.200.23", 502);		// 创建一个TCP类型的容器
	modbus_set_debug(ctx, TRUE);					// 设置Debug模式

	if (modbus_connect(ctx) == -1)					// TCP 模式下连接Server
	{
		fprintf(stderr, "Connection failed:%sn", modbus_strerror(errno));
		modbus_free(ctx);
		return -1;
	}
	
	// 以下申请内存块,用以保存接收数据
	tab_rp_registers = (uint16_t*)malloc(nb * sizeof(uint16_t));
	memset(tab_rp_registers, 0, nb * sizeof(uint16_t));

	// 读取非甲烷总烃的关于总烃、甲烷、NMHC这3个寄存器(寄存器地址分别为22,25,28)中的浓度
	// 从寄存器地址22开始读取,读10个寄存器到data数组中
	//进行读取测试,起始地址为22,读取寄存器数目为10
	rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers);
	
	printf("----------------- 甲烷/非甲烷总烃分析仪 TE_5900 -------------------------------n");
	printf("CH4的浓度为:%.3f ppmV,NMHC的浓度为:%.3f ppmV,总烃的浓度为:%.3f ppmVn", 
		tab_rp_registers[3] / 100.0f, tab_rp_registers[6] / 100.0f, tab_rp_registers[0]/ 100.0f);

	return 0;
}

int main(int argc, char *argv[])
{
	modbus_tcp_client_test02();

	getchar();
	system("pasue");

	return 0;
}

在VS2017中的运行结果如下图所示: