ABB机器人与西门子1200/1500进行modbus tcp通讯

通过modbus通讯,我们可以使用真实的机器人或者robotstudio与plc进行一个通讯,可以通过自己的电脑进行纯虚拟仿真,不管是有没有设备都可以进行调试。

本项目测试设备:
一个实体的plc 1214FC DC/DC/DC
一台实体的机器人 ABB120
一台虚拟的机器人 120

plc
robotstudio
实体机器人

1.数据类型

1.1plc数据类型讲解

首先得明白需要通讯的数据是一个什么类型的数据,有多少个位?例如:我要给机器人发一个或接收一个Real(浮点数),一个浮点数在PLC这边是占4个位(记住这是重点)。
如果不知道一个数据占多少个位,我们可以从plc里面查看。

在这里插入图片描述
创建一个DB块,在里面建立一些数据,选择浮点型并且在设置中取消优化访问块(点击数据块——右击属性——找到优化的访问块取消打勾)。从上面我们可以看到偏移量从0~3刚好是四个位。
在这里可以一个数据块放很多不同的数据类型,但是要注意要调用的数据,偏移量的位置要与机器人相对应,否则会出现数据读取错误或者乱码的问题。

1.2机器人数据类型讲解

对于机器人这边,它对存储的数据类型没有太多的要求。基本使用NUM就可以存储plc绝大多数的常用类型。这里没什么值得注意的,plc那边有多少个数据,机器人这边就建立多少个变量或数组的大小。重要的是下面的报文解读。

2.报文解析

授人以鱼不如授人以渔,机器人本来就是没有modbus通讯的。要实现modbus通讯,我们只能通过报文的解读手搓modbus协议。如果对我下面的报文解读不理解或者需要更详细的可以去看看这位博主的文章,他会有更详细我解读。我这边只是举一个例子,可以根据我的例子自行修改。

下面是关于写数据的:
先看代码

    PROC write32float(num slaveID,num start,num length,num arrayValue{*})
        VAR byte byte_send{13};
        VAR rawbytes raw_data;
        ClearRawBytes raw_data;					//清空原始自己的内容
        byte_send{1}:=0X00;
        byte_send{2}:=0X00;
        byte_send{3}:=0X00;
        byte_send{4}:=0X00;						//没有太具体的要求可以不管它
        byte_send{5}:=(length*4+7) DIV 256;
        byte_send{6}:=(length*4+7) mod 256;
        byte_send{7}:=slaveID;
        byte_send{8}:=0X10;
        byte_send{9}:=start div 256;
        byte_send{10}:=start mod 256;
        byte_send{11}:=length*2 div 256;
        byte_send{12}:=length*2 mod 256;
        byte_send{13}:=length*4;
        FOR i FROM 1 TO 13 DO 
            PackRawBytes byte_send{i},raw_data,(RawBytesLen(raw_data)+1)\Hex1;
        ENDFOR 
        FOR i FROM 1 TO length DO
            PackRawBytes arrayValue{i},raw_data\Network,(RawBytesLen(raw_data)+1)\Float4;
        ENDFOR 
        SocketSend modbustcp_plc\RawData:=raw_data;
    ENDPROC 

关于四个输入变量它们分别是:设备号起始地址数据长度存放的数组

接下来我们看rawbytes,这是一个原始字节,它是用来存放需要接收或者发送到plc那边的数据。机器人需要进num的数据转换成可以给plc读取到的数据。

modbus 常用功能代码

注意不同的功能码所对应的报文有所不同

十进制十六进制功能数据类型
010x01读取 多个线圈
020x02读取 多个离散量输入量
030x03读取 多个保持寄存器16进制整型
040x04读取 多个输入寄存器16进制整型
050x05写入 单个线圈
060x06写入 单个寄存器16进制整型
150x0F写入 多个线圈
160x10写入 多个寄存器16进制整型

我们再看byte_send数组

第1,2位 00 01 交互标识
第3,4位 00 00 协议标识
第5,6位 00 06 后面报文长度 有6位
第 7 位  设备地址,发送什么,响应什么(一般是多个设备需要标记的到时候用到)
第 8 位 功能码(程序使用的是0x10 写入多个寄存器)
第9,10位00 01 起始地址
第11,12位 00 10查询线圈长度(就是往后读取多少给数据)
第13位 是后面数据的字节

先看第 5 ,6位。为什么是 4+7,其实这是一个固定的计算方法。4 是因为一个浮点数有4位,所以如果发10个浮点数出去,那就是104。那后面的 加7就是从第五位开始数6~12刚好7位。而后面 DIVMOD* 256只是做一个转换成十六进制的操作。

那其实报文已经讲过了,那具体发送一些什么样的数据,我没讲!那么请看下面的操作。

下半部分的代码

        FOR i FROM 1 TO 13 DO 
            PackRawBytes byte_send{i},raw_data,(RawBytesLen(raw_data)+1)\Hex1;
        ENDFOR 
        FOR i FROM 1 TO length DO
            PackRawBytes arrayValue{i},raw_data\Network,(RawBytesLen(raw_data)+1)\Float4;
        ENDFOR 
        SocketSend modbustcp_plc\RawData:=raw_data;

第一次循环是把上半部分的报文存入 RawBytesLen
第二次是把 arrayValue数组里面的数据打包进去
这里需要注意的是raw_date\Network 是指大端输入还是小端输入
而后面的**\Float4**就是以浮点数的形式存入

最后的socketsend就不用说了,把打包好的数据发送出去。这样plc就可以收到了。

读数据:

读取和写入的其实差不多,来看代码!!!

    PROC ReadHoldingRegister(num slaveID,num start,num length,inout num arrayValue{*})
        VAR byte byte_send{12};
        VAR byte byte_receive{72};
        byte_send{1}:=0X00;
        byte_send{2}:=0X00;
        byte_send{3}:=0X00;
        byte_send{4}:=0X00;
        byte_send{5}:=0x00;
        byte_send{6}:=0x06;
        byte_send{7}:=slaveID;
        byte_send{8}:=0X03;
        byte_send{9}:=start div 256;
        byte_send{10}:=start mod 256;
        byte_send{11}:=length*2 div 256;
        byte_send{12}:=length*2 mod 256;    
        SocketSend modbustcp_plc\Data:=byte_send;
        SocketReceive modbustcp_plc\data:=byte_receive;

        Get32Float byte_receive,length*2,arrayValue;

    ENDPROC
    proc  Get32Float(byte recebuffer{*},num length,inout num arrayValue{*})
        VAR byte receive{4};
        VAR rawbytes raw_data;
        VAR num value;
        VAR num nCount:=1;
        FOR i FROM 1 TO length*2 STEP 4 DO 
            FOR j FROM 1 TO 4 DO 
                receive{j}:=recebuffer{9+i+(j-1)};
            ENDFOR
            ClearRawBytes raw_data;
            FOR t FROM 4 TO 1 DO 
                PackRawBytes receive{t},raw_data,(RawBytesLen(raw_data)+1)\Hex1;
            ENDFOR 
            UnpackRawBytes raw_data,1,value\Float4;
            arrayValue{nCount}:=value;
            Incr nCount;   
        ENDFOR
    ENDPROC 

功能码差不多,看Get32Float就可以了。先是把打包好的功能码(不带数据)发送给plc,然后我们就可以收到plc发过来的数据。Get32Float就是解包这些数据的,关键也就UnnpackRawBytes这个命令。具体不知道这个函数怎么使用,可以去看ABB的手册。没有的也可以私信我,给你发。

差点忘记了这个 VAR byte byte_receive{72};,因为ABB的数组不能像C语言或者python那种一样可以给你自动生成数组长度,所以我们要自己去计算。4*15+12=72,4是指一个浮点数有四个位,15是指数据的长度,12是报文的长度。

3.实现代码(例子)

3.1博图代码

博图的代码比较简单,plc作为一个服务器,机器人是客户端。

首先添加一个modbus tcp协议的功能块,这是一个服务器的功能块。

在这里插入图片描述

然后建立两个DB块,一个用来存储跟机器人链接的IP地址等数据,另一个就是存储跟机器人交互的数据。

图一:
在这里插入图片描述
图二:
在这里插入图片描述
两个图片其实没什么太大的区别,那我还放出来干嘛!!!

图一是连接真实际机器人的设置
图二是连接虚拟机器人的设置(robotstudio)
两个的ID和IP不一样,ID为什么不一样上面有讲了,不废话。IP不一样是我在调试的时候发现,如果指定PC的IP,有时候会出现连接不上的问题。或者两个块只连接了其中一个,另一个一直报错。

在这里插入图片描述

3.2RAPID代码

module  modbustcp
    VAR socketdev modbustcp_plc;
    VAR intnum it1;
    VAR intnum it2;
    VAR intnum it3;
    PERS num arrayValue_pose{15};  
    VAR num value;
    PROC interupt()
        IDelete it1;
        CONNECT it1 WITH jt;
        isignaldi robot_stop,1,it1;
        IDelete it2;
        CONNECT it2 WITH write_plc;
        ITimer 0.24,it2;
    ENDPROC 
    TRAP read_plc
        ReadHoldingRegister 1,0,15,arrayValue_pose;
    ENDTRAP 
    TRAP write_plc
        write32float 1,0,15,arrayValue_pose;
    ENDTRAP 
    
    PROC modbus_socket(string address,num port)
        SocketClose modbustcp_plc;
        SocketCreate modbustcp_plc;
        SocketConnect modbustcp_plc,address,port;
    ENDPROC
    
    PROC write32float(num slaveID,num start,num length,num arrayValue{*})
        VAR byte byte_send{13};
        VAR rawbytes raw_data;
        ClearRawBytes raw_data;
        byte_send{1}:=0X00;
        byte_send{2}:=0X00;
        byte_send{3}:=0X00;
        byte_send{4}:=0X00;
        byte_send{5}:=(length*4+7) DIV 256;
        byte_send{6}:=(length*4+7) mod 256;
        byte_send{7}:=slaveID;
        byte_send{8}:=0X10;
        byte_send{9}:=start div 256;
        byte_send{10}:=start mod 256;
        byte_send{11}:=length*2 div 256;
        byte_send{12}:=length*2 mod 256;
        byte_send{13}:=length*4;
        FOR i FROM 1 TO 13 DO 
            PackRawBytes byte_send{i},raw_data,(RawBytesLen(raw_data)+1)\Hex1;
        ENDFOR 
        FOR i FROM 1 TO length DO
            PackRawBytes arrayValue{i},raw_data\Network,(RawBytesLen(raw_data)+1)\Float4;
        ENDFOR 
        SocketSend modbustcp_plc\RawData:=raw_data;
    ENDPROC 
    
    PROC ReadHoldingRegister(num slaveID,num start,num length,inout num arrayValue{*})
        VAR byte byte_send{12};
        VAR byte byte_receive{72};
        byte_send{1}:=0X00;
        byte_send{2}:=0X00;
        byte_send{3}:=0X00;
        byte_send{4}:=0X00;
        byte_send{5}:=0x00;
        byte_send{6}:=0x06;
        byte_send{7}:=slaveID;
        byte_send{8}:=0X03;
        byte_send{9}:=start div 256;
        byte_send{10}:=start mod 256;
        byte_send{11}:=length*2 div 256;
        byte_send{12}:=length*2 mod 256;    
        SocketSend modbustcp_plc\Data:=byte_send;
        SocketReceive modbustcp_plc\data:=byte_receive;

        Get32Float byte_receive,length*2,arrayValue;

    ENDPROC
    proc  Get32Float(byte recebuffer{*},num length,inout num arrayValue{*})
        VAR byte receive{4};
        VAR rawbytes raw_data;
        VAR num value;
        VAR num nCount:=1;
        FOR i FROM 1 TO length*2 STEP 4 DO 
            FOR j FROM 1 TO 4 DO 
                receive{j}:=recebuffer{9+i+(j-1)};
            ENDFOR
            ClearRawBytes raw_data;
            FOR t FROM 4 TO 1 DO 
                PackRawBytes receive{t},raw_data,(RawBytesLen(raw_data)+1)\Hex1;
            ENDFOR 
            UnpackRawBytes raw_data,1,value\Float4;
            arrayValue{nCount}:=value;
            Incr nCount;   
        ENDFOR
    ENDPROC 
    
pric main()

	modbus_socket "192.168.125.1",520;
	interupt;

endproc 

ENDmodule  

机器人的代码就这样了,上面讲的很清楚了。如果需要项目源码什么的,就私信吧。开摆!!!!

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ABB机器人与电脑可以通过TCP/IP协议进行通信。TCP/IP是一套用于互连网络的通信协议,由传输控制协议TCP)和网络互连协议IP)组成。 首先,要建立ABB机器人与电脑之间的TCP/IP通信连接,需要在机器人和电脑上配置相应的网络设置。机器人和电脑应处于同一局域网中,可以通过交换机、路由器等设备连接在一起。 在机器人端,需要运行ABB机器人控制器的软件,通过设置IP地址、子网掩码和默认网关等参数,使其与局域网中的其他设备进行通信。使用ABB机器人控制器的软件可以访问机器人的相关状态信息,控制机器人的运行和操作。 在电脑端,需要配置一台能够支持TCP/IP通信的计算机,可以是Windows、Linux等操作系统。通过设置电脑的网络属性,使其与机器人在同一网络中,并与机器人建立连接。在电脑上安装ABB提供的相关软件,如ABB RobotStudio等,可以通过该软件实现对机器人的控制。 一旦机器人和电脑建立了TCP/IP通信连接,就可以进行数据传输和命令控制。电脑可以向机器人发送指令,如启动、停止、移动到指定位置等等。机器人可以将执行状态、传感器数据等信息发送回电脑。通过TCP/IP通信,ABB机器人可以与电脑实现实时的数据交互和控制。 总而言之,ABB机器人与电脑之间的TCP/IP通信是通过配置网络设置和运行相应的软件实现的。它使得机器人能够与计算机进行数据传输和命令控制,实现更加灵活和智能的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

畵颜卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值