ABB机器人ModBusTCP通讯编程案例分享 您所在的位置:网站首页 三菱plc与pc通讯指令说明书区别大吗 ABB机器人ModBusTCP通讯编程案例分享

ABB机器人ModBusTCP通讯编程案例分享

2024-06-03 14:06| 来源: 网络整理| 查看: 265

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 实验室设备网 版权所有