ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

西门子S7-1200 PLC机器人码垛与AGV调度系统实战解析

西门子S7-1200 PLC机器人码垛与AGV调度系统实战解析

先交代一下背景。这套项目是某食品企业码垛工段的自动化改造,原来的方案是人工作业加一台老旧机械臂,产能跟不上、垛形不稳定,客户一口气提了三个需求:自动码垛、空满垛转运、AGV自动接驳。设备清单下来的时候列的是两台西门子S7-1215C PLC、一台六轴机器人、四台伺服轴、一套2D视觉定位系统和两台潜伏式AGV。我负责整体PLC程序、伺服调试、视觉对接和整线联调。前后干了三周,从IO表写到视觉补偿,从空跑试到满载运行,中间踩了不少坑。这套程序本身不算特别复杂,但它是很典型的“机器人码垛+伺服输送+视觉引导+AGV调度”四合一小系统,市面上很多项目都在这个框架里打转。今天把架构、选型、通信、码垛算法、视觉补偿、AGV握手和调试过程逐层拆开讲,给正在做类似集成项目的朋友一份能直接参考的完整思路。

1. 这套程序到底在解决什么问题

1.1 码垛工作站的整体流程

先把这个项目的工艺流程说清楚,后面所有程序逻辑都是围着它转的。整个工作站分两个区域:码垛区和成品转运区。码垛区的流程是:输送线把满箱产品送到定位工位,产品到位后由PLC发出拍照请求,固定安装在工位正上方的2D相机对箱体取像,视觉软件计算出箱体中心相对基准位置的偏差,把偏差值交给PLC;PLC把偏差补偿到机器人的抓取坐标里,机器人按补偿后的坐标去抓箱,再按照预设的料型一层一层码到托盘上;每当码完一层,机器人自动切换旋转方向形成交错堆叠;整垛码满后,PLC通知AGV过来把满垛拉走、放上空托盘,然后继续下一个循环。

这里面有两台S7-1215C的明确分工:PLC1负责码垛区,也就是机器人、视觉、伺服输送线和码垛逻辑;PLC2负责成品转运区,也就是AGV任务调度、空满托盘交换、以及与仓储或上层系统的接口。PLC1和PLC2之间通过以太网通信,只交换几个状态字,比如“满垛请求”“空托盘到位”“AGV已接单”这些布尔量。这样拆分的直接好处是,任何一台PLC停机检修时另一台还能保持基础安全状态,不会全线瘫痪。

1.2 为什么拆分两台1215而不是一台1500

这是方案阶段被客户问得最多的一个问题。客户一开始的想法是“干脆上一台1500,把所有东西装进去”,觉得一台大PLC总比两台小的省事。我给出反对意见的理由有三条。

第一是物理距离。码垛区和成品转运区在车间里隔了将近三十米,如果全部I/O都拉回一台PLC,电缆敷设和中间继电器柜会非常臃肿,抗干扰也差;拆成两台PLC放在各自区域电柜里,现场走线和接线都大幅简化。第二是故障隔离。AGV调度逻辑跟码垛逻辑是两类东西,混在一个程序里最怕“牵一发动全身”,比如AGV通信偶尔抖动,很容易把码垛的时序搅乱;分开后AGV那边再怎么乱,PLC1的码垛循环都能安全停下来等待,不会产生逻辑交叉污染。第三是成本。两台1215C加通信模块的总价,比一台1500加远程IO方案便宜一头,而且1215C的板载IO和双PN口在这个场景下刚好够用,不浪费。

当然,如果你将来要上多机器人协同、多轴插补或者几十轴运动控制,那还是要考虑1500系列或者更高级的运动控制器。像我手里这套“单机器人+四伺服+一套视觉+两台AGV”的规模,1215C反而是性价比最合适的组合。

2. 硬件选型与网络组态要点

2.1 S7-1215C到底干得了多少活

S7-1215C DC/DC/DC这个型号,板载资源是14路数字量输入、10路数字量输出、2路模拟量输入和2路模拟量输出,还带了两个PROFINET端口,六个100kHz高速计数通道和四个脉冲输出口。在TIA Portal里组态时,板载I/O和扩展模块是分开分配的,默认从字节0起,比如板载DI占I0.0到I1.7的前16个点(实际只用了14个),板载DO占Q0.0到Q1.1(实际只用了10个)。接扩展模块SM1223时,地址会自动往后排,很多时候就是从这里开始乱的,项目里一定要先打开“PLC变量”表确认实际地址,别凭印象去接线。

这套系统里板载IO其实不够用,因为光安全门、急停、光电、到位传感器、按钮指示灯加起来就快四十个点了,所以我在两台PLC上各加了一块SM1223数字量混合模块,把每台PLC的IO能力扩到四十多入三十多出。这里有个经验:凡是涉及安全回路的点,比如急停、安全门开关、光栅输出,全部走硬接线继电器链,只把最终的“安全链OK”信号给PLC;千万不要把人机安全依赖在PLC程序上,万一程序卡死或者某个输入点坏掉,后果不是闹着玩的。

2.2 PROFINET通信地址怎么对应

这个标题本身就是很多人在后台问的问题,尤其是西门子PLC跟安川机器人、ABB机器人走PROFINET时,最常翻车的就是“地址对不上”。核心规则其实一句话:PLC的Q区输出到机器人,就是机器人看到的输入;PLC的I区,接收机器人传来的状态。组态时先把机器人厂商提供的GSDML文件导入TIA,然后把机器人作为IO设备拖到网络视图里,分配设备名和IP;再在硬件目录里给机器人挂IO模块,系统会自动分配I起始地址和Q起始地址。

我举个例子。某次接一台安川机器人的时候,PLC侧组了16字节输入、16字节输出,TIA自动分配了I68和Q68作为起始地址。那么PLC里写一个QW68,等于往机器人PROFINET从站的第一个输出字发数据;机器人那边要在它的I/O映射表里,把PROFINET从站接收区的第一个字映射到它内部的输入寄存器,这样才能读到PLC的命令。返回路径相反:机器人内部的输出状态映射到PROFINET发送区,PLC侧就读IW68。如果两侧有一边映射错位一个字节,整条命令就会“串门”,比如置了夹爪信号,结果把允许运行信号点亮了,这种隐性错位在调试时非常恶心。

我的建议是开工前做一张通信地址对照表,A栏列PLC的I/Q地址,B栏列机器人/伺服/视觉模块对应的从站槽位,C栏列对方设备里的内部寄存器或IO号,贴在电柜门上。调试时第一件事不是写逻辑,而是先把这张表用“I/O强制”逐个点位验证清楚。

2.3 视觉系统和变频器的接入方式

视觉系统我用的是海康的VisionMaster,配合一台500万像素的GigE黑白相机。VisionMaster主流的对接方式是TCP/IP自定义报文:PLC作为客户端,视觉工控机作为服务器,每次拍照前PLC主动建立连接并发送“拍照请求”,视觉软件完成定位后回传一个ASCII字符串,比如“OK,121.35,-20.18,0.53”,三个数分别是X偏差、Y偏差和角度偏差。PLC收到后用字符串解析指令拆出来,再存入对应的REAL型变量。注意一定要做数据格式协议验证,我自己写了个简单校验:帧头、帧尾必须匹配,数据段用逗号分隔,解析失败就丢弃并报警,不能让乱码把坐标带飞。

另外输送线上如果有变频器,比如ABB或者别的品牌,接入方式就两种:支持PROFINET的直接挂到同一个总线里,不支持的用Modbus TCP桥接。ABB变频器配西门子PLC的经典做法是在TIA里组标准的PROFINET IO,然后通过通信字控制启停和速度给定,本质上跟控制伺服驱动器一样,只是报文里没有位置环,只有控制字、状态字、速度设定和实际频率。

3. 伺服控制与码垛核心算法

3.1 伺服轴怎么控

这个项目的四台伺服分别是:输送线入口的移载轴、码垛位的托盘升降轴、成品出口的定位挡停轴,以及一个用于空中调度摆渡的横移轴。四台都选了西门子V90 PN伺服,用PROFINET直连,报文用的111号报文。111号报文的好处是能直接做绝对位置控制,PLC把目标位置写到通信报文里,伺服自己处理位置环,PLC只需要管理“使能、急停、回原点”这些控制字,省去了大量编制轨迹的功夫。

程序里每个轴我建了一个统一的UDT,里面放控制字、状态字、目标位置、当前位置、回零命令、点动命令、使能、报警代码和轴忙标志。控制方式有三种:自动模式下由码垛逻辑写目标位置;手动模式下由HMI上的点动按钮或手轮控制;回零模式在每次上电初始化时执行。对于一个1500多行的运动控制程序来说,这种统一管理的方式比每个轴各写一堆FC清爽太多,排查时直接从DB里看每个轴的状态字就能定位问题。

这里顺便提一句:如果你用汇川H5U或者Easy系列走EtherCAT,带几十个660伺服轴的思路也是类似的,只是总线不同、控制方式换成轴控指令而已。新手看那种多轴EtherCAT案例会觉得复杂,先抓住“每个轴有独立状态字+统一位置给定”这两个核心就行。

3.2 码垛料型与坐标计算

码垛的核心是料型管理,也就是怎么把一排排、一列列、一层层的箱子摆得整齐、压得住。我在PLC里建了一个配方DB,用UDT定义产品料型,包含箱子长宽高、托盘长宽、垛型行数、列数、层数、箱间距、层间旋转标志。这样客户换产品时,HMI上改参数就行,不用动程序。

坐标计算的逻辑不复杂但容易错。假设托盘基准点在左下角,机器人放箱基准也定在这个点,那么第M行第N列的位置就是基准X加N乘以(箱宽加间距),基准Y加M乘以(箱长加间距)。如果开启层间旋转,奇数层行列互换,变成基准X加M乘以(箱长加间距)、基准Y加N乘以(箱宽加间距)。用一段ST语言写出来大概是:

// 行、列计数从1开始 ColPos := PalletBaseX + (ColNum - 1) * (BoxLen + GapX); RowPos := PalletBaseY + (RowNum - 1) * (BoxWid + GapY); PlacePosX := ColPos; PlacePosY := RowPos;

层数循环我放在一个异步状态机里,每一步只执行一次位置计算,然后把“目标位置已更新”的信号发给机器人,等机器人回报“已取走”或“已放完”再进入下一步。这里最容易犯的错是循环变量被重复累加,导致隔一层多摆一件、箱子摞斜。我在程序里加了占位计数保护,每一层的放置数量达到行数乘列数后,才允许层数加一,层数超过设定值才触发“满垛完成”。

3.3 机器人的拾放时序与安全互锁

机器人跟PLC配合靠的是握手信号,不是单纯地“给个坐标就完事”。我设计了三个标准信号:取料请求、取料完成、放料完成。PLC先把补偿后的坐标通过PROFINET发给机器人控制器,然后置位取料请求;机器人抓完箱之后回取料完成;PLC收到后把取料请求复位,进入放料阶段;放料完成后再复位取料完成。三套信号里任何一步超时,比如5秒没收到取料完成,PLC立刻暂停整个流程并报警,不允许自动继续,只能人工确认或清除故障后再启动。

安全互锁方面,除了安全门、急停、光栅这些硬件链,程序里我还加了两层软互锁:一是机器人必须在“自动模式”且“无报警”状态下才允许发给它坐标;二是伺服轴必须在“已回零”且“轴静止”状态下才允许托盘升降动作。双层互锁看起来很啰嗦,但正是这些“啰嗦”保住了设备,因为一旦机器人还夹着箱子时托盘突然升降,或者伺服轴还在移动时机器人就下来抓箱,轻则撞毁治具,重则伤到人。

4. 视觉定位与AGV接驳逻辑

4.1 视觉偏移补偿与飞拍拖影计算

视觉定位这步,很多人第一反应是“相机拍到了目标中心,直接把坐标发给机器人就行”,实际没那么简单。相机的像素坐标和机器人的世界坐标是两个坐标系,中间必须做标定。我用的方法是九点标定:在机器人工作范围内摆一块标定板,让机器人分别走到九个位置记录世界坐标,同时视觉软件识别出九个对应的像素坐标,VisionMaster里做一次仿射变换,算出像素到毫米的比例和旋转量。标定做完后,视觉返回的就不再是像素值,而是以毫米为单位的“相对基准点的偏差”,这才可以直接补偿。

补偿公式也不只是简单加减。当箱体在托盘上有角度偏转时,X和Y的偏差是耦合的,必须做旋转变换。我程序里的计算是:

// 角度转为弧度 A := Angle / 180 * 3.14159; // 旋转补偿 CompX := OffsetX * COS(A) - OffsetY * SIN(A); CompY := OffsetX * SIN(A) + OffsetY * COS(A); // 最终抓取点 PickX := TeachX + CompX; PickY := TeachY + CompY;

另外说到“视觉飞拍拖影计算”,这是不停线拍照方案的常见坑。如果产品在输送线上边运动边拍照,相机曝光时间内产品移动的距离就是拖影量:拖影量=传送速度×曝光时间。比如输送线速度0.5米每秒,曝光时间2毫秒,拖影就是1毫米,这个量在定位精度要求在±0.5毫米的项目里是致命的。解决办法一是缩短曝光时间,二是用频闪光源把有效曝光压到亚毫秒级,三是用编码器触发拍照让相机跟着产品位置触发。我这个项目采用了定位挡停后静态拍照,拖影问题不存在,但公式我在方案阶段算给客户看过,因为很多客户都问过“能不能不停、跑着拍”。

4.2 AGV对接与两台PLC的分工

成品码满后,PLC1会向PLC2发一个“满垛请求”标志。PLC2收到后先判断AGV当前状态,如果有空闲AGV就下发搬运任务,任务内容包括起点、终点、托盘类型和优先级;如果两台AGV都在忙,就把任务挂到队列里,等有AGV腾出来再发。AGV接到任务后自动行驶到码垛位,通过激光导航停在目标点,到位后给PLC2发送“已就位”信号。PLC2确认AGV到位后,再给PLC1发送“允许放行”,PLC1才把满垛输送线启动,把成品垛交到AGV上。

AGV跟PLC2之间的通信我用的是Modbus TCP,AGV控制器作为从站,PLC2作为主站,主要读写几个寄存器:任务号、起点站、终点站、AGV状态、到位标志、取货完成标志。这里最关键的是心跳信号,AGV每500毫秒会刷新一个递增计数值,PLC侧每1秒检查一次,如果心跳连续三次不更新,PLC2立刻置AGV故障并暂停下发任务,防止AGV中途死机后PLC还在傻等。

那台负责转运的PLC程序,如果扩展成多巷道、多库位的立体仓库调度,就是大家常说的“立库程序”的雏形。无非是把AGV换成堆垛机,把托盘位换成货位地址,逻辑都是“任务排队、状态监控、到位互锁”。

4.3 通信异常后的恢复逻辑

再稳定的通信也会有抽风的时候,所以恢复逻辑比通信本身更重要。我在两处做了超时保护:一是PLC1和PLC2之间的S7通信,每500毫秒由PLC1发送一个心跳字,PLC2在三个扫描周期内没收到新值就认为通信中断,立刻把“联动使能”复位,两台PLC各自进入本地安全暂停;二是视觉TCP通信,拍照请求发出后6秒内没收到结果就报“视觉超时”,同时把旧坐标值作废,防止机器人抓错位置。

恢复逻辑统一走“人工确认”路线,不搞自动重连跳回去。原因是自动恢复容易造成“看似已经正常,实际状态错位”的隐性故障,比如视觉已经拍过一次,重连后PLC还在等下一次结果,但机器人已经跑去抓箱子了。所有通信故障复位必须由操作员在HMI确认,确认后再从流程起点重新跑到故障前的断点继续执行。

5. 程序编写实战与调试心得

5.1 程序结构规划

这套程序我全部用TIA Portal写的,程序结构分成六层。第一层是系统块,OB1主循环、OB100初始化、OB82硬件故障诊断、OB86机架故障诊断;第二层是IO映射,单独一个FC把所有物理输入输出映射到符号变量,后续逻辑一律引用映射变量,绝对不直接读IO地址;第三层是设备控制,机器人、伺服、输送线各一个FC块;第四层是工艺逻辑,码垛料型计算、视觉补偿、AGV握手各一个FC;第五层是报警管理,集中收集所有报警条件并通过HMI显示;第六层是数据块,配方、计数器、轴状态、通信收发缓存全部用独立的DB保存。

这样分层的好处是每个块的功能边界清晰,出问题的时候不用翻几百行程序找原因。我见过很多同行喜欢把逻辑全堆在一个OB1里,程序短的时候没问题,一旦超过几百行,查一个闪烁的报警都能把人逼疯。

有一点必须强调:所有变量起名要么用完整语义,要么用标准缩写,比如PalletFull、RobotBusy、VisionResultOK,不要用A1、B2这种只有自己能看懂的命名。这个项目我拆的时候顺手救过人家一个老项目,全程序变量名都是X1、Y2,根本没法维护,最后只能推倒重写。

5.2 关键代码片段与参数选择

码垛层判断这块我贴一段简化后的ST代码,大家可以感受一下书写习惯:

IF PlaceCount >= LayersCols * LayersRows THEN PlaceCount := 0; LayerNum := LayerNum + 1; // 奇数层和偶数层旋转交错 IF "Recipe".LayerRotate AND (LayerNum MOD 2 = 0) THEN RowPer := "Recipe".Cols; ColPer := "Recipe".Rows; ELSE RowPer := "Recipe".Rows; ColPer := "Recipe".Cols; END_IF; END_IF;

这里的MOD取余要注意,TIA Portal里整数取余是可以直接用MOD运算符的。LayerNum到设定最大值后就置“满垛完成”。放箱坐标计算上一个小节已经给过了,整套码垛算法的核心就这三个量:当前层、当前行、当前列,其他都是围绕它们的边界检查和坐标推算。

伺服轴的控制我直接调用西门子标准库里的MC_MoveAbsolute功能块,设置好轴工艺对象、目标位置、速度、加减速时间。加减速时间是关键参数,我这次四台轴设置的加减速都在0.3秒左右,太快了机械冲击大,太慢了影响节拍。如果伺服走起来有异响或抖动,优先查加减速和增益匹配,不要上来就换硬件。

5.3 从空转到满载的调试顺序

调试顺序是我每次做设备必走的流程,不能跳步。第一步是IO对点,拿万用表和短接线逐一确认每个输入输出点,包括机器人和AGV的IO,确认那个通信地址对照表没问题。第二步是伺服回原点和点动,确认四台轴方向正确、限位有效、回零停位一致。第三步是机器人坐标统一,把机器人工作坐标系原点和PLC视觉标定基准对齐,这一步不对后面全白搭。第四步是视觉标定和单次拍照验证,用实物反复拍照检测坐标偏差的重复性。第五步是单循环手动测试,操作员在HMI上一步步执行“拍一张、抓一个、放一个”。第六步是全自动连续跑,先跑一层不码满,再跑满垛。第七步才是AGV联动,让AGV反复拉垛送空托盘,验证几十次不掉链子。

这七步里最容易出猫腻的是第四步和第七步。视觉重复性看着没问题,但一到不同时间段、不同光线条件就飘;AGV单独跑没问题,但AGV和码垛同时动作时,哪个信号先到哪个信号后到经常打架。所以我在调试最后专门做了一个“极限对抗测试”,让码垛连续三垛不停机,AGV同时过来接,人为制造高负载和信号拥挤的场景,把时序漏洞全逼出来。

6. 常见故障排查与避坑清单

6.1 PROFINET通信故障速查

现象常见原因处理方法
IO设备在TIA里显示不可达设备名错误或IP冲突重新分配设备名,保证IP唯一
通信偶尔中断、被诊断为IO故障网线/水晶头质量差、端接松动换工业级网线,重新压接头
地址错位、数据串号子模块顺序与GSD不一致删除模块重新按厂家说明挂载
更换新设备后无法通信没同步设备名/固件版本不符重新分配设备名,升级固件到兼容版本

这些坑都是实实在在碰到过的,尤其IP冲突,仪表、上位机、AGV、机器人全在一个网段,稍不小心就把某个设备和PLC的IP撞了。建议项目开工就画一张完整IP分配表,每台设备、每个上位机软件都占一行,哪个都不许乱改。

6.2 伺服抖动、原点丢失和过流

伺服轴最常见的三个问题:一是抖动,多半是速度环增益偏高或者机械共振,调低增益或者加滤波能解决;二是原点丢失,如果是增量编码器且电池没电,断电后原点位置就会跑丢,解决方法是定期检查编码器电池电压,或者改成绝对值编码器每次上电虚回零;三是过流报警,常见于机械卡滞或者抱闸没有及时释放,检查抱闸时序和机械结构就行。

这里我要提醒一句:伺服参数不要随便复制。就算同型号同功率,安装在不同的机械结构上,刚性、惯量都不一样。这个项目里四台轴参数我是一台台单独调的,直接复制参数导致第二台轴共振的教训我还记得。

6.3 视觉误判、定位不稳和飞拍拖影

视觉系统在车间环境里最大的敌人是环境光。日光、焊机弧光、旁边行车的大灯都会让图像亮度漂移,导致模板匹配分数忽高忽低。解决方案很粗暴也有效:相机固定位置加遮光罩,光源用常亮频闪两用环形光源,拍照结果低于设定置信度就直接判定NG,不参与坐标计算。别迷信算法有多强,先把环境控制住,视觉问题能少一半。

定位不稳还有可能出在标定上。机器人换了工具末端、相机动了哪怕一毫米,都要重新标定。如果发现补偿方向反了,先检查九个标定点的顺序和坐标方向,这是基准问题不是算法问题。飞拍方案的拖影计算前面说过了,记住一个公式:拖影量=速度×曝光时间,算出来超过精度要求就得换短曝光或者上频闪。

6.4 关于程序保护、备份和那些“拆不开”的块

调试过程中还碰到一个很现实的问题:甲方拿来的旧设备程序里有些块是加密的,也就是带“KNOW_HOW保护”的块。这类块在TIA里只能调用,看不到内部逻辑,而且没有原密码是没法解除的。网上流传的各种“强制解除保护”的办法我劝大家别轻易试,一是大概率失败,二是这类工具来源不明,容易把TIA环境搞坏或者引入别的东西,三是万一弄坏了现场程序,停产损失全算你头上。正规做法是找原程序开发者要密码,或者让你的供应商提供源程序。这个经验也告诉我们,交付项目时一定要把源程序和密码明确写进合同里,别把“程序交付”漏了。

备份方面我坚持一个原则:每天下班前用TIA的Archive功能归档一次项目,存到两个不同的U盘加一个网盘位置,版本号按日期命名。现场改参数前先存档,改完确认没问题再存档一次。很多做调试的朋友吃了亏才养成这个习惯,我不希望靠吃亏才长记性。

最后说一点我个人在这次项目里体会最深的东西:这套系统真正难的不是某一个单点控制,而是把机器人、伺服、视觉、AGV这些“各自都很聪明”的设备,按照一个严谨的时序逻辑串起来。信号握手、超时保护、故障停机、人工恢复,这四个东西做好了,整条线就稳了一大半。调试的时候我守在现场最大的感触是,设备卡在中间状态比设备报警更可怕,机器人抓着箱子悬在半空、AGV在门口排队、操作员不知道按哪个按钮,所以我把每个交接点都做了状态显示和复位按钮,让任何卡住的情况都能一眼看懂、一键恢复。这套程序的架构后续想扩展也很容易,比如加MES上传、加多配方自动切换、加产量统计,都是在现有DB和FC基础上再挂一层的事,核心的码垛和握手逻辑不用动。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进