TwinCAT3 Modbus-TCP Client/Server使用

目录


一、环境配置和准备

1、PLC中安装TF6250-Modbus-TCP库

PLC地址

安装库文件

PLC硬件环境设置、库文件安装、防火墙设置等,参见博客文章:TwinCAT3中ModbusTCP Server和C# Client连接-CSDN博客

2、勾选TF6250的license

3、PLC工程中添加Tc2_ModbusSrv库文件

4、分别创建测试ModbusTCP测试的Server和Client程序

将创建的程序添加到Task中。

二、PLC作为Client端

1、设置测试电脑IP地址

测试电脑IP地址和PLC的IP地址在一个网段内。

2、运行MobusTCP测试工具

使用测试工具ModSim32,创建ModbusTCP Server服务端。端口号默认502,测试软件默认IP地址是计算机本地地址。

3、PLC端程序编写

定义变量:ModbusTCP Server服务端ip地址

Server_IpAddress	:STRING:='192.168.1.33';        //ModbusTCP Server服务端ip地址

(1)读取离散量输入

定义变量

	02: Input Status 读取//
	fbReadInputs      : FB_MBReadInputs;						(*读取离散量输入功能块*)
	bReadInputs       : BOOL;									(*读取离散量输入执行条件*)
 	nQuantityinput    : WORD:=1 ;								(*读取离散量输入个数*)
 	nMBAddrinput      : WORD:=1 ;								(*读取离散量输入起始地址*)
 	arrDatainput      : BYTE;									(*存放离散量输入的值*)

程序

nUnitID:Modbus-Tcp从站号。如果实际中不知道从站号多少,默认写1就行。

fbReadInputs(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1 , 							//Modbus-Tcp从站号
	nQuantity:=nQuantityinput , 			//读取离散量输入个数
	nMBAddr:= nMBAddrinput, 				//读取离散量输入 Modbus起始地址
	cbLength:= SIZEOF(arrDatainput), 		//存放离散量输入变量的个数
	pDestAddr:=ADR(arrDatainput), 			//存放离散量输入变量指针起始地址
	bExecute:=bReadInputs , 				//读取离散量输入执行条件
	tTimeout:=T#1S ,    
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	cbRead=> );

运行测试1,单个离散量读操作:

对10002写1

PLC读取

读取个数是1,nQuantityinput值为1

起始地址nMBAddrinput写1对应的寄存器是10002。离散变量实际地址=10001+nMBAddrinput

读取

运行测试2,多个离散量读操作:

对10002写1、10003写1、10004写1

PLC读取

设置读取个数是3。读取出来的值是7。(三个位都为1,就是7)

(2)读取线圈

定义变量

    fbReadCoils       			: FB_MBReadCoils;				(*读取线圈功能块*) 
 	bReadCoils        			: BOOL; 						(*读取线圈执行条件*)      
 	nQuantitycoils    			: WORD :=3;  					(*读取线圈个数*) 
 	nMBAddrcoils      			: WORD :=1;  					(*读取线圈起始地址*) 
 	arrDatacoils      			: BYTE;							(*存放线圈的值*)

PLC程序

fbReadCoils(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502 ,							//Modbus-Tcp端口号 
	nUnitID:=1 , 							//Modbus-Tcp从站号
	nQuantity:=nQuantitycoils , 			//读取线圈个数
	nMBAddr:=nMBAddrcoils , 				//读取线圈 Modbus起始地址
	cbLength:=SIZEOF(arrDatacoils) , 		//存放线圈变量的个数
	pDestAddr:=ADR(arrDatacoils) , 			//存放线圈变量指针起始地址
	bExecute:=bReadCoils , 					//读取线圈执行条件
	tTimeout:= T#1S, 
	bBusy=> , 
	bError=>, 
	nErrId=> , 
	cbRead=> );

运行测试,多个线圈读操作:

对线圈00005/00006/0007/0008/00009写1操作

PLC

nMBAddrcoils:读取线圈的地址

nQuantitycoils:读取的线圈个数

线圈的实际地址=00001+nMBAddrcoils。

00005对应的nMBAddrcoils地址设置就是4。

5个线圈的值都是ON,即31

PLC中数据显示,2进制、10进制、16进制显示设置

(3)单个线圈写操作

定义变量

    fbWriteSingleCoil       	: FB_MBWriteSingleCoil;			(*写入单个线圈功能块*)
 	bWriteSingleCoil            : BOOL;							(*写入单个线圈执行条件*)
 	nMBAddrWriteSingleCoil      : WORD := 3;					(*写入单个线圈Modbus 地址*)
 	nValueWriteSingleCoil       : WORD := 16#FF00;				(*16#FF00:True;16#0000:False*)

PLC程序

fbWriteSingleCoil(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:= 502, 						//Modbus-Tcp端口号
	nUnitID:= 1, 							//Modbus-Tcp从站号
	nMBAddr:=nMBAddrWriteSingleCoil , 		//写入单个线圈Modbus起始地址
	nValue:=nValueWriteSingleCoil , 		//写入单个线圈的值:16#FF00:True;16#0000:False
	bExecute:=bWriteSingleCoil , 			//写入单个线圈执行条件
	tTimeout:=T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );

运行测试,单个线圈写操作:

对线圈00004写操作

线圈地址nMBAddrWriteSingleCoil值设置:3。(线圈地址=00001+nMBAddrWriteSingleCoil)

nValueWriteSingleCoil值设置:

TRUE:16#FF00,即10进制65280。

FALSE:16#0000,即10进制0。

(4)多个线圈写操作

变量定义

  	fbWriteCoils       			: FB_MBWriteCoils;				(*写入线圈功能块*)
  	bWriteCoils      			: BOOL;							(*写入线圈执行条件*)
  	nQuantityWriteCoils 		: WORD := 10;					(*写入离散量输入个数*)
  	nMBAddrWriteCoils   		: WORD := 14;					(*写入离散量输入起始地址*)
  	arrDataWriteCoils   		: ARRAY[1..2] OF  BYTE  := [16#11, 16#33];(*写入离散量输入的值*)

PLC程序

fbWriteCoils(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1 , 							//Modbus-Tcp从站号
	nQuantity:= nQuantityWriteCoils , 		//写入线圈个数
	nMBAddr:=nMBAddrWriteCoils , 			//写入线圈Modbus起始地址
	cbLength:=SIZEOF(arrDataWriteCoils), 	//写入线圈的变量个数
	pSrcAddr:=ADR(arrDataWriteCoils), 		//写入线圈的变量指针起始地址
	bExecute:=bWriteCoils , 				//写入线圈的执行条件
	tTimeout:=T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );

运行测试,多个线圈写操作:

写16个线圈,线圈地址从00006开始。(00001+nMBAddrWriteCoils,nMBAddrWriteCoils设置值为5)。

1个BYTE是8位,8位都是1即BYTE值是255。

BYTE数组arrDataWriteCoils长度为2、即16位。最多可以写16个线圈操作。

注意:的线圈BYTE个数要和数组长度相同,16个线圈2个BYTE。对应否则会报错。)

(5)读取输入寄存器值

变量定义

    fbReadInputRegs    : FB_MBReadInputRegs;		(*读取输入寄存器功能块*)
 	bReadInputRegs     : BOOL;						(*读取输入寄存器执行条件*)
 	nQuantityInputRegs : WORD := 3;					(*读取输入寄存器个数*)
 	nMBAddrInputRegs   : WORD:= 2;					(*读取输入寄存器起始地址*)
 	arrDataInputRegs   : ARRAY [1..3] OF WORD;		(*存放输入寄存器的值*)

PLC程序

fbReadInputRegs(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1, 							//Modbus-Tcp从站号
	nQuantity:=nQuantityInputRegs, 			//读取输入寄存器个数
	nMBAddr:=nMBAddrInputRegs  , 			//读取输入寄存器Modbus起始地址
	cbLength:= SIZEOF(arrDataInputRegs),	//存放输入寄存器变量的个数和指针起始地址
	pDestAddr:=ADR(arrDataInputRegs), 		//存放输入寄存器变量指针起始地址
	bExecute:= bReadInputRegs  , 			//读取输入寄存器执行条件
	tTimeout:=T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	cbRead=> );

运行测试,多个输入寄存器读操作:

给30003、30004、30005赋值

PLC读

寄存器地址30003=30001+nMBAddrInputRegs,nMBAddrInputRegs设置值2

多三个寄存器

注意:读的寄存器个数要和数组长度相同,否则会报错。)

(6)读取保持寄存器值

变量定义:

    fbReadRegs        			: FB_MBReadRegs;				(*读取保持寄存器功能块*)
 	bReadRegs         			: BOOL;     					(*读取保持寄存器执行条件*) 
 	nQuantityregs     			: WORD:=2;   					(*读取保持寄存器个数*)
 	nMBAddrregs       			: WORD:=24;   					(*读取保持寄存器起始地址*)
 	arrDataregs       			: ARRAY [1..2] OF WORD;			(*存放保持寄存器的值*)

PLC程序:

fbReadRegs(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502,							//Modbus-Tcp端口号
	nUnitID:= 1, 							//Modbus-Tcp从站号
	nQuantity:=nQuantityregs, 				//读取保持寄存器个数
	nMBAddr:=nMBAddrregs , 					//读取保持寄存器Modbus起始地址
	cbLength:=SIZEOF(arrDataregs) , 		//存放保持寄存器变量的个数
	pDestAddr:=ADR(arrDataregs) , 			//存放保持寄存器变量指针起始地址
	bExecute:=bReadRegs, 					//读取保持寄存器执行条件
	tTimeout:= T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	cbRead=> );

运行测试,多个保持寄存器读操作:

读保持寄存器40005、40006

寄存器首地址40005=40001+nMBAddrregs,设置nMBAddrregs值为4。读两个寄存器。

注意:读的寄存器个数要和数组长度相同,否则会报错。)

(7)单个保持寄存器写操作

变量定义:

 	fbWriteSingleReg            : FB_MBWriteSingleReg;			(*写入单个寄存器功能块*)
 	bWriteSingleReg             : BOOL;							(*写入单个寄存器执行条件*)
 	nMBAddrSingleReg            : WORD := 4;					(*写入单个寄存器Modbus 地址*)
 	nValueSingleReg             : WORD := 16#1234;				(*写入单个寄存器数值*)

PLC程序:

fbWriteSingleReg(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1 , 							//Modbus-Tcp从站号
	nMBAddr:=nMBAddrSingleReg, 				//写入单个保持寄存器起始地址
	nValue:=nValueSingleReg, 				//写入单个寄存器数值
	bExecute:=bWriteSingleReg , 			//写入单个寄存器的执行条件
	tTimeout:=T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );	

运行测试,单个保持寄存器写操作:

写保持寄存器40005。40005=40001+nMBAddrSingleReg,设置nMBAddrSingleReg值为4

(8)多个保持寄存器写操作

变量定义:

  	fbWriteRegs         		: FB_MBWriteRegs;				(*写入保持寄存器功能块*)
  	bWriteRegs          		: BOOL;							(*写入保持寄存器个数*)
  	nQuantityWriteRegs  		: WORD := 4;					(*写入保持寄存器个数*)
  	nMBAddrWriteRegs    		: WORD := 4;					(*写入保持寄存器起始地址*)
  	arrDataWriteRegs			: ARRAY[1..4] OF WORD := [1122, 3344, 5566, 7788];(*写入保持寄存器的值*)

PLC程序:

fbWriteRegs(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1 ,							//Modbus-Tcp从站号
	nQuantity:=nQuantityWriteRegs , 		//写入保持寄存器个数
	nMBAddr:= nMBAddrWriteRegs , 			//写入保持寄存器起始地址
	cbLength:= SIZEOF(arrDataWriteRegs), 	//写入变量的个数和指针起始地址
	pSrcAddr:=ADR(arrDataWriteRegs) , 		//写入变量指针起始地址
	bExecute:= bWriteRegs , 				//写入保持寄存器的执行条件
	tTimeout:=T#1S  , 
	bBusy=> , 
	bError=> , 
	nErrId=> );

运行测试,多个保持寄存器写操作:

写保持寄存器40003、40004、40005,寄存器首地址40003=40001+nMBAddrWriteRegs,设置nMBAddrWriteRegs值2

注意:寄存器个数要和数组长度相同,否则会报错。)

三、PLC作为Server端

1、PLC程序

(1)寄存器变量定义

    arr1							AT%MB0			:ARRAY[1..5]		OF		WORD;		//起始地址是12289
	arr2							AT%MB10			:ARRAY[1..10]		OF		WORD;		//起始地址是12294

2、Client客户端工具

使用测试工具ModScan32模拟ModbusTCP Client客户端。

打开ModScan32

根据Server服务端PLC 中定义的寄存器,做如下设置

MB0对应的起始地址是12289。

寄存器说明:一个MW寄存器对应两个MB寄存器,比如MW0是MB0、MB1组成。一个12289对应一个MW0寄存器,即对应MB0、MB1。

3、通讯测试

(1)客户端写操作

客户端ModScan32对服务端PLC的寄存器写操作

PLC服务端接收的

(2)PLC服务端写操作

PLC寄存器写

客户端ModScan32接收的

四、PLC中使用服务端和客户端程序进行寄存器操作

1、PLC程序

(1)服务端程序

PLC服务端程序不变,就定义读写的寄存器变量

变量定义

    arr1							AT%MB0			:ARRAY[1..5]		OF		WORD;		//起始地址是12289
	arr2							AT%MB10			:ARRAY[1..10]		OF		WORD;		//起始地址是12294

(2)客户端程序

变量定义

Server_IpAddress	:STRING:='192.168.1.21';
	03: Holding Register 读取&写入
 	fbReadRegs        			: FB_MBReadRegs;				(*读取保持寄存器功能块*)
 	bReadRegs         			: BOOL;     					(*读取保持寄存器执行条件*) 
 	nQuantityregs     			: WORD:=5;   					(*读取保持寄存器个数*)
 	nMBAddrregs       			: WORD:=12288;   				(*读取保持寄存器起始地址*)			//	寄存器地址=40001+nMBAddrregs
 	arrDataregs       			: ARRAY [1..5] OF WORD;			(*存放保持寄存器的值*)
  
  	fbWriteRegs         		: FB_MBWriteRegs;				(*写入保持寄存器功能块*)
  	bWriteRegs          		: BOOL;							(*写入保持寄存器个数*)
  	nQuantityWriteRegs  		: WORD := 10;					(*写入保持寄存器个数*)
  	nMBAddrWriteRegs    		: WORD := 12294;				(*写入保持寄存器起始地址*)			//	寄存器地址=40001+nMBAddrWriteRegs
  	arrDataWriteRegs			: ARRAY[1..10] OF WORD := [11, 22, 33, 44,55,66,77,88,99,100];		(*写入保持寄存器的值*)
  
 	fbWriteSingleReg            : FB_MBWriteSingleReg;			(*写入单个寄存器功能块*)
 	bWriteSingleReg             : BOOL;							(*写入单个寄存器执行条件*)
 	nMBAddrSingleReg            : WORD := 4;					(*写入单个寄存器Modbus 地址*)
 	nValueSingleReg             : WORD := 16#1234;				(*写入单个寄存器数值*)
//

PLC程序

fbReadRegs(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502,							//Modbus-Tcp端口号
	nUnitID:= 1, 							//Modbus-Tcp从站号
	nQuantity:=nQuantityregs, 				//读取保持寄存器个数
	nMBAddr:=nMBAddrregs , 					//读取保持寄存器Modbus起始地址
	cbLength:=SIZEOF(arrDataregs) , 		//存放保持寄存器变量的个数
	pDestAddr:=ADR(arrDataregs) , 			//存放保持寄存器变量指针起始地址
	bExecute:=bReadRegs, 					//读取保持寄存器执行条件
	tTimeout:= T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	cbRead=> );
	
fbWriteRegs(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1 ,							//Modbus-Tcp从站号
	nQuantity:=nQuantityWriteRegs , 		//写入保持寄存器个数
	nMBAddr:= nMBAddrWriteRegs , 			//写入保持寄存器起始地址
	cbLength:= SIZEOF(arrDataWriteRegs), 	//写入变量的个数和指针起始地址
	pSrcAddr:=ADR(arrDataWriteRegs) , 		//写入变量指针起始地址
	bExecute:= bWriteRegs , 				//写入保持寄存器的执行条件
	tTimeout:=T#1S  , 
	bBusy=> , 
	bError=> , 
	nErrId=> );
		
fbWriteSingleReg(
	//sIPAddr:='169.254.0.1' , 				//modsim32的IP地址
	sIPAddr:=Server_IpAddress , 				//modsim32的IP地址
	nTCPPort:=502, 							//Modbus-Tcp端口号
	nUnitID:=1 , 							//Modbus-Tcp从站号
	nMBAddr:=nMBAddrSingleReg, 				//写入单个保持寄存器起始地址
	nValue:=nValueSingleReg, 				//写入单个寄存器数值
	bExecute:=bWriteSingleReg , 			//写入单个寄存器的执行条件
	tTimeout:=T#1S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );	

2、通讯测试

(1)寄存器说明

一个MW寄存器对应两个MB寄存器,比如MW0对应12289、12289对应MB0、MB1

PLC 客户端程序中变量

读寄存器地址=40001+nMBAddrregs        则MB0对应设置nMBAddrregs12288

写寄存器地址=40001+nMBAddrWriteRegs        

(2)PLC的Client程序读操作

先给服务端的寄存器赋值

PLCServer程序读

(3)PLC的Client程序写操作

PLC客户端写寄存器

PLC服务端接收到客户端写的寄存器

五、测试工程下载

https://download.csdn.net/download/panjinliang066333/88609166

工程包括:

(1)客户端、服务端PLC程序

(2)TF6250-Modbus-TCP库文件安装软件

(3)ModbusTCP测试工具

模拟客户端:modscan32

模拟服务端:modsim32

(4)倍福官方简单测试参考

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2023年12月26日
下一篇 2023年12月26日

相关推荐