ABB机器人ModBusTCP通讯编程案例分享 | 您所在的位置:网站首页 › 三菱plc与pc通讯指令说明书区别大吗 › ABB机器人ModBusTCP通讯编程案例分享 |
ModBusTCP简介
MODBUS TCP是结合了MODBUS协议和TCP/IP网络标准,它是MODBUS协议在TCP/IP上的具体实现,数据传输时在TCP报文中插入MODBUS 应用数据单元,Modbus协议赋予TCP端口号为502,这是目前在仪表与自动化行业中分配到的端口号,所使用的硬件接口为以太网接口。 MODBUS TCP信息帧包含了报文头、功能码、数据三部分内容,其中消息报文头由四部分构成,共7个字节,与MODBUS RTU相比,MODBUS TCP中不存在CRC校验,校验部分由TCP/IP协议和以太网的链路层来完成。 信息帧内容结构:MBAP报文头 数据单元(ADU) 传输标识 协议标识 长度 单元标识符 功能码 数据 2 byte 2 byte 2 byte 1 byte 1 byte n byte 信息帧内容解读:传输标识 2个字节长度,标志Modbus询问/应答的传输,一般默认是00 00 协议标识 2个字节长度,00 00 表示Modbus协议 长度 2个字节长度,即从单元标识符以后的数据字节个数 单元标识符 1个字节长度,相当于MODBUS RTU通信中的从站站号(slave id) 功能码 1个字节长度,可用于读取设备数据或者往设备中写入数据 数据 根据读取数据长度的不同,由n个字节组成。 功能码(决定是写数据还是读取数据):功能码 描述 访问类型 PLC地址 数据类型 操作数量 01H 线圈寄存器 读 00001-09999 位 单/多 02H 离散输入寄存器 只读 10001-19999 位 单/多 03H 保持寄存器 读 40001-49999 字 单/多 04H 输入寄存器 读 30001-39999 字 单/多 05H 线圈寄存器 写 00001-09999 位 单个 06H 保持寄存器 写 40001-49999 位 多个 0FH 线圈寄存器 写 00001-09999 位 多个 10H 保持寄存器 写 40001-49999 字 多个 Modbus Tcp通信格式举例03H功能码(读取一个或多个保持寄存器的数值)使用举例: 发送(hex): 传输标识符 协议标识符 长度标识符 站号 功能码 首个寄存器地址 读取的寄存器个数 00 00 00 00 00 06 01 03 00 00 00 03 接收(hex): 传输标识符 协议标识符 长度标识符 站号 功能码 读取的字节数 第1、2、3个寄存器的数值 00 00 00 00 00 09 01 03 06 03 E8 13 88 02 8A 06H功能码(写一个保持寄存器的值)使用举例: 发送(hex): 传输标识符 协议标识符 长度标识符 站号 功能码 寄存器地址 写入寄存器的数值 00 00 00 00 00 06 01 06 00 00 00 0A 接收(hex): 传输标识符 协议标识符 长度标识符 站号 功能码 寄存器地址 写入寄存器的数值 00 00 00 00 00 06 01 06 00 00 00 0A 10H功能码(写多个保持寄存器的值)使用举例: 接收(hex): 传输标识符 协议标识符 长度标识符 站号 功能码 首个寄存器地址 写入寄存器个数 写入字节数 写入寄存器的值 00 00 00 00 00 0D 01 10 00 00 00 03 06 00 00 0A 00 0B 00 0F 接收(hex): 传输标识符 协议标识符 长度标识符 站号 功能码 首个寄存器地址 写入寄存器个数 00 00 00 00 00 06 01 10 00 00 00 03 ABB机器人ModBusTCP通讯实现案例ABB机器人并没有提供标准的MODBUS相关处理函数,要使用ModBusTCP,可以使用普通socket收发,按照ModBusTCP格式进行数据传输。由于ABB机器人没有专用的通讯指令,因此只能作为客户端。客户端连接程序可以放在初始化程序中,每次运行连接一次即可。 ABB机器人配置需求: MODBUS/TCP基于以太网,故ABB机器人在使用时需要有616-1PCINTERFACE选项。MODBUS/TCP通讯介质使用普通网线连接控制柜网口即可。 ABB机器人端程序编写: 定义所需变量及初始化socket通讯:VAR socketdev socket_modbus; ! 定义一个套接字数据类型 VAR byte send_byte{13}; ! 定义一个字节数据类型数组 VAR rawbytes send_rawbyte; ! 定义一个原始数据字节容器 VAR rawbytes recv_rawbyte; ! 定义一个原始数据字节容器 VAR num recv_val; VAR num reg_val; PROC Init_ModbusTcp() SocketClose socket_modbus; ! 关闭套接字 SocketCreate socket_modbus; ! 创建套接字 SocketConnect socket_modbus,"127.0.0.1", 50000; ! 指定连接IP和端口号 ENDPROC PROC Close_ModbusTcp() SocketClose socket_modbus; ! 关闭套接字 ENDPROC 读取一个16位无符号整型数值:FUNC num Read_HoldingReg_Uint(num addr) send_byte{1}:= 0X00; ! 传输标志符 send_byte{2}:= 0X00; ! 传输标志符 send_byte{3}:= 0X00; ! 协议标志符 send_byte{4}:= 0X00; ! 协议标志符 send_byte{5}:= 0X00; ! 数据长度高8位 send_byte{6}:= 0X06; ! 数据长度低8位 send_byte{7}:= 0X01; ! 站号 send_byte{8}:= 0X03; ! 功能码: 03H 读取一个保持寄存器数值 send_byte{9}:= addr DIV 256; ! 数据地址高8位 send_byte{10}:= addr MOD 256; ! 数据地址低8位 send_byte{11}:= 0X00; ! 数据个数高8位 send_byte{12}:= 0X01; ! 数据个数低8位 (以word计数) !\Data 表示数组的格式发送字节数据类型 !\NoOfBytes表示指定发送的字节数 SocketSend socket_modbus\Data:=send_byte\NoOfBytes:=12; TPWrite "read_uint addr:" + ValToStr(addr); SocketReceive socket_modbus\rawdata:=recv_rawbyte; UnpackRawBytes recv_rawbyte\Network,10,recv_val\IntX:=UINT; TPWrite "read_uint recv:" + ValToStr(recv_val); RETURN recv_val; ENDFUNC 读取一个32位浮点型数值:FUNC num Read_HoldingReg_Real(num addr) send_byte{1}:= 0X00; ! 传输标志符 send_byte{2}:= 0X00; ! 传输标志符 send_byte{3}:= 0X00; ! 协议标志符 send_byte{4}:= 0X00; ! 协议标志符 send_byte{5}:= 0X00; ! 数据长度高8位 send_byte{6}:= 0X06; ! 数据长度低8位 send_byte{7}:= 0X01; ! 站号 send_byte{8}:= 0X03; ! 功能码: 03H 读取多个保持寄存器数值 send_byte{9}:= addr DIV 256; ! 数据地址高8位 send_byte{10}:= addr MOD 256; ! 数据地址低8位 send_byte{11}:= 0X00; ! 数据个数高8位 send_byte{12}:= 0X02; ! 数据个数低8位 (以word计数) !\Data 表示数组的格式发送字节数据类型 !\NoOfBytes表示指定发送的字节数 SocketSend socket_modbus\Data:=send_byte\NoOfBytes:=12; TPWrite "read_real addr:" + ValToStr(addr); SocketReceive socket_modbus\rawdata:=recv_rawbyte; UnpackRawBytes recv_rawbyte\Network,10,recv_val\float4; TPWrite "read_real recv:" + ValToStr(recv_val); RETURN recv_val; ENDFUNC 写入一个16位无符号整型数值:PROC Write_HoldingReg_Uint(num addr, num val) send_byte{1}:= 0X00; ! 传输标志符 send_byte{2}:= 0X00; ! 传输标志符 send_byte{3}:= 0X00; ! 协议标志符 send_byte{4}:= 0X00; ! 协议标志符 send_byte{5}:= 0X00; ! 数据长度高8位 send_byte{6}:= 0X06; ! 数据长度低8位 send_byte{7}:= 0X01; ! 站号 send_byte{8}:= 0X06; ! 功能码:06H 写入一个保持寄存器数值 send_byte{9}:= addr DIV 256; ! 数据地址高8位 send_byte{10}:= addr MOD 256; ! 数据地址低8位 send_byte{11}:= val DIV 256; ! 数值高8位 send_byte{12}:= val MOD 256; ! 数值低8位 !\Data 表示数组的格式发送字节数据类型 !\NoOfBytes表示指定发送的字节数 SocketSend socket_modbus\Data:=send_byte\NoOfBytes:=12; TPWrite "write_uint send:" + ValToStr(val); SocketReceive socket_modbus\rawdata:=recv_rawbyte; UnpackRawBytes recv_rawbyte\Network,11,recv_val\IntX:=UINT; TPWrite "write_uint recv:" + ValToStr(recv_val); ENDPROC 写入一个32位浮点型数值:PROC Write_HoldingReg_Real(num addr, num val) send_byte{1}:= 0X00; ! 传输标志符 send_byte{2}:= 0X00; ! 传输标志符 send_byte{3}:= 0X00; ! 协议标志符 send_byte{4}:= 0X00; ! 协议标志符 send_byte{5}:= 0X00; ! 数据长度高8位 send_byte{6}:= 0X06; ! 数据长度低8位 send_byte{7}:= 0X01; ! 站号 send_byte{8}:= 0X10; ! 功能码:10H 写入一个保持寄存器数值 send_byte{9}:= addr DIV 256; ! 数据地址高8位 send_byte{10}:= addr MOD 256; ! 数据地址低8位 send_byte{11}:= 0X00; ! 寄存器个数高8位 send_byte{12}:= 0X02; ! 寄存器个数低8位 send_byte{13}:= 0X04; ! 字节数量 FOR i FROM 1 TO 13 DO PackRawBytes send_byte{i}, send_rawbyte\Network,i,\Hex1; ENDFOR PackRawBytes val, send_rawbyte\Network,14,\float4; SocketSend socket_modbus\rawdata:=send_rawbyte; TPWrite "write_real send:" + ValToStr(val); UnpackRawBytes send_rawbyte\Network,14,recv_val\float4; TPWrite "write_real val:" + ValToStr(recv_val); SocketReceive socket_modbus\rawdata:=recv_rawbyte; UnpackRawBytes recv_rawbyte\Network,9,recv_val\IntX:=UINT; TPWrite "write_real recv:" + ValToStr(recv_val); ENDPROC 调用函数实现数值读写操作:Init_ModbusTcp; Write_HoldingReg_Uint 100, 1; ! 在地址100处写入数值1 Write_HoldingReg_Real 200, 1.1; ! 在地址200处写入数值1.1 reg_val = Read_HoldingReg_Uint(100); ! 读取地址100处的整型数值 reg_val = Read_HoldingReg_Real(200); ! 读取地址200处的浮点型数值 Close_ModbusTcp; |
CopyRight 2018-2019 实验室设备网 版权所有 |