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

这篇具有很好参考价值的文章主要介绍了ABB机器人与西门子1200/1500进行modbus tcp通讯。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

1.数据类型

1.1plc数据类型讲解

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

abb机器人modbustcp协议配置,机器人,tcp/ip,服务器
创建一个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 常用功能代码

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

十进制 十六进制 功能 数据类型
01 0x01 读取 多个线圈
02 0x02 读取 多个离散量输入量
03 0x03 读取 多个保持寄存器 16进制整型
04 0x04 读取 多个输入寄存器 16进制整型
05 0x05 写入 单个线圈
06 0x06 写入 单个寄存器 16进制整型
15 0x0F 写入 多个线圈
16 0x10 写入 多个寄存器 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协议的功能块,这是一个服务器的功能块。

abb机器人modbustcp协议配置,机器人,tcp/ip,服务器

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

图一:
abb机器人modbustcp协议配置,机器人,tcp/ip,服务器
图二:
abb机器人modbustcp协议配置,机器人,tcp/ip,服务器
两个图片其实没什么太大的区别,那我还放出来干嘛!!!

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

abb机器人modbustcp协议配置,机器人,tcp/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  

机器人的代码就这样了,上面讲的很清楚了。如果需要项目源码什么的,就私信吧。开摆!!!!文章来源地址https://www.toymoban.com/news/detail-776338.html

到了这里,关于ABB机器人与西门子1200/1500进行modbus tcp通讯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ABB机器人将实时坐标发送给西门子PLC的具体方法示例

    本次以PROFINET通信为例进行说明,演示ABB机器人将实时坐标发送给西门子PLC的具体方法。 首先,要保证ABB机器人和PLC的信号地址分配已经完成,具体的内容可参考以下链接: S7-1200PLC与ABB机器人进行PROFINET通信的具体方法和步骤详解 交互的信号确认好之后,我们新建一个发送

    2024年02月02日
    浏览(34)
  • 西门子S7-1500与FANUC机器人进行EtherNetIP通信的具体方法示例

    具体方法可参考以下内容: 以下示例中TIA博途的版本为V17,本例中PLC做主站,机器人做从站 一、 西门子PLC一侧的组态设置和编程 首先,我们需要到下载所需的EtherNetIP通信库文件,大家可自行百度获取或者从以下链接获取: 西门子EtherNetIP Scanner通信库文件V17版本 打开博途软

    2024年02月09日
    浏览(93)
  • 西门子S7-1200使用LRCF通信库与安川机器人进行EthernetIP通信的具体方法示例

    准备条件: PLC:S7-1200 1214C DC/DC/DC 系统版本4.5及以上。 机器人控制柜:安川YRC1000。 软件:TIA V17 PLC做主站,机器人做从站。 具体方法可参考以下内容: 使用的库文件为西门子 1200系列 PLC 与机器人通过 EtherNet/IP 协议通信时的参数配置功能块。 机器人侧Ethernet/IP设定 机器人开

    2024年02月03日
    浏览(83)
  • 使用IOT-Tree Server连接西门子PLC S7-300/1200/1500

    IOT-Tree Server是个开源物联网软件,可以作为组态软件成为自动化系统的上位软件。她提供了接入、数据组织管理、控制逻辑和人机交互多个方面的功能。从版本0.99开始,IOT-Tree Server新增了西门子以太网驱动,能够通过以太网的方式直接访问S7-300/1200/1500. S7-200 smart好像也支持

    2024年02月03日
    浏览(35)
  • 西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一)

    第一部分:组态配置 具体步骤可参考以下内容 : 如下图所示,新建一个项目后,添加一个安全型PLC,这里以1516F-3 PN/DP为例进行说明, 如下图所示,添加CPU完成后,可以看到左侧的项目树中比普通的PLC多了几个选项和模块, 如下图所示,我们选中该CPU后进入属性画面,在“

    2024年02月06日
    浏览(54)
  • 库卡机器人profinet连接说明(西门子PLC部分)

    开始前准备:          硬件: 带有Profinet通讯协议PLC(本文选用西门子PLC)、普通交换机(用于测试数据)、电脑及机器人;          软件: 博图、workvisual 开始配置: 1、查看机器人Profinet选项的版本及PLC的CPU型号  机器人profinet选项版本  PLC的CPU型号         观察

    2024年02月05日
    浏览(119)
  • C++上位软件通过LibModbus开源库和西门子S7-1200/S7-1500/S7-200 PLC进行ModbusTcp 和ModbusRTU 通信

            一直以来上位软件比如C++等和西门子等其他品牌PLC之间的数据交换都是大家比较头疼的问题,尤其是C++上位软件程序员。传统的方法一般有OPC、Socket 等,直到LibModbus 开源库出现后这种途径对程序袁来说又有了新的选择。           1 )使用简单, 利用MUDBUS库文件

    2024年02月03日
    浏览(37)
  • 西门子S7-1500作为智能设备共享功能

    本章节介绍了共享设备的功能,优势,使用要求,使用规则,如何将智能设备作为共享设备,实现一个智能设备同时与2个IO控制器进行通信的示例,以及常见问题。 一、共享设备功能概述 信号模块可以被不同的IO控制器访问的IO设备被称为\\\"共享设备\\\",智能设备也可以作为共

    2024年02月22日
    浏览(32)
  • 西门子PLC1200自由口通信

    文章目录 前言 自由口通信 二、使用步骤 组态 编程 总结 项目里需要使用PLC和某公司液体泵通信,液体泵采用RS485,支持OEM协议和DT协议,因此PLC采用自由口通信 提示:以下是本篇文章正文内容,下面案例可供参考 扩展了CB1241通信板,RS485连线如下图所示 TRB为+,TRA为-,M为接

    2024年02月07日
    浏览(30)
  • 西门子S7-1200组态PROFINET

    1、首先参照官方给的帮助文档,里面有各种情况下的处理方式和组态教程 S7-1200PROFINET通信 2、如果要组态第三方的 PROFINET gateway,比如PROFINET转RS485网关,就需要按照如下的方法进行操作 以sibotech的TS-181为例 通用串口(两个) / PROFINET网关TS-181 上海泗博自动化 网关厂家会提供

    2024年02月11日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包