西门子TIA Portal与Factory IO的自动化立体仓库PLC仿真

发布时间:2026/9/1 2:32:25
西门子TIA Portal与Factory IO的自动化立体仓库PLC仿真 简介本资源是基于西门子TIA Portal V16开发的自动化立体仓库完整控制项目面向工业自动化初学者、PLC工程师及智能制造方向实践者聚焦Factory IO虚拟仿真与S7-1500/1200系列PLC协同控制的核心能力训练。项目覆盖巷道堆垛机、输送线、货位检测等典型仓储设备的I/O定义、逻辑编程、OPC UA通信配置及HMI交互设计解决从虚拟验证到真实部署的关键衔接问题。压缩包共39个文件含9张系统状态与信息提示PNG图如错误、警告、成功反馈、7个XML配置文件含版本转换日志、2个DEL删除标记文件及多个TIA工程核心文件如.ap15_1工程头、.plf项目数据、.db数据库、.tvd变量表等整体仅1.76MB轻量易导入。已有2541人学习下载提供可直接加载运行的Factory IO场景联动工程附带完整诊断标签、结构化DB块及标准化IO映射便于快速理解仓储控制流程、复用模块逻辑并开展二次开发。 做电气自动化这几年我最大的感受是改程序比接线快仿真跑通比现场试错便宜。今天这个项目就是用西门子TIA Portal V16把一套自动化立体仓库的控制逻辑跑通对象是Factory IO里的3D仿真场景。整套代码不依赖真实硬件用S7-1200/S7-1500的仿真环境就能把入库、出库、堆垛机运动、货位管理这些核心流程完整实现。无论你是刚学PLC的学生还是想快速验证物流自动化逻辑的工程师这套思路都值得参考。我会把项目从架构设计、软件版本匹配、通信连接、程序实现到调试排错整个过程拆开讲清楚尤其是那些不跑一遍根本发现不了的坑。1. 项目需求与整体方案设计1.1 立体仓库控制需求拆解自动化立体仓库听着高大上抽掉外壳之后核心就是几件事货物怎么进来、怎么存进去、怎么取出来、货位怎么记录。Factory IO里的“Automated Warehouse”场景把物理机构都搭好了我们作为PLC程序员要管的就是传感器输入、执行器输出、流程调度和异常保护。先说工艺动作。货物由入料传送带送到上料位检测传感器亮起堆垛机从待机位置移动到上料点抓取货物然后按系统指定的空货位坐标移动到对应货位把货物放下最后回待机位。出库反向操作堆垛机去目标货位取货送到出料传送带货物被下游运走。看起来就是“取-放-走”三个动作但中间牵涉到多轴联动、位置判断、限位保护、货位状态维护一旦逻辑混乱堆垛机就会撞限位或放错货位。从控制需求来看可以拆成四个模块流程控制模块负责入库、出库任务调度核心是顺序动作适合用状态机实现。运动控制模块管理堆垛机X轴、Z轴的正反转和启停配合位置反馈完成定点运动。仓库数据模块用数据库方式记录货位占用情况支持查找空位、查找最早入库货位先进先出。安全保护模块处理原点信号、超限信号、急停逻辑确保任何状态都能安全停止。1.2 为什么选TIA Portal V16 Factory IO这套组合很多初学者习惯直接用真实PLC和实物设备调试但一套微型立库动辄十几万场地、线缆、器件维护都是问题。Factory IO的好处是它有物理引擎传送带会转、传感器会亮、气缸会推信号时序和真实设备非常接近。配合TIA Portal的仿真可以做到“程序怎么写仿真就怎么动”几乎零成本复现现场逻辑。控制器选型上我用的是S7-1214C DC/DC/DC。为什么不用1500因为这个场景的I/O点数量不大1214C的集成DI/DO已经够用逻辑量也不大没必要杀鸡用牛刀。但要注意如果你用PLCSIM Advanced做仿真且程序用了大量SCL块或复杂数组操作1200的仿真性能也能扛住如果是做更复杂的多工位仓储建议换1500网络通信能力和块容量都更充裕。TIA Portal V16这个版本在仿真生态上比较成熟它配套的PLCSIM Advanced V4.0支持虚拟以太网Factory IO可以直接通过以太网通信协议连上来比老式PLCSIM的接口稳定得多。博途V16也兼容S7-1200固件4.4以上的版本我实际测试下来下载和在线监控都非常顺畅。2. 仿真环境搭建与通信配置2.1 软件版本匹配问题这个项目卡住最多人的不是程序而是软件版本不匹配。TIA Portal V16不是所有PLCSIM都通用。如果你用的是V16建议装PLCSIM Advanced V4.0而不是V3.0否则Factory IO里点击连接时经常报错。Factory IO这边也要留意版本太老的版本对PLCSIM Advanced的支持不完整建议使用2021年之后发布的版本通信功能更稳。还有一个高频报错是“博途v16安装一直提示重启”这个基本是注册表残留问题。安装前手动打开注册表编辑器定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager删除PendingFileRenameOperations里的残留项或者干脆重启一次再装。装V16过程中如果杀毒软件还开着也可能导致文件被拦截安装中断后就会出现各种奇怪问题。装HSP 0205报错也是类似原因解压路径务必用纯英文目录关掉Windows Defender实时保护再安装。2.2 PLCSIM Advanced与Factory IO连接步骤整个通信链路是这样的TIA Portal把编译好的程序下载到PLCSIM Advanced创建的虚拟PLC里PLC分配一个虚拟网卡IPFactory IO作为一个以太网IO设备通过这个IP和虚拟PLC交换I/O信号。连接步骤我按顺序拆开讲第一步在TIA Portal中新建项目添加一个S7-1200 CPU设置CPU的IP地址比如192.168.0.1子网掩码255.255.255.0。如果不设置IPFactory IO是找不到PLC的。注意PLCSIM Advanced的虚拟网卡和CPU IP必须处于同一网段。第二步写好程序编译通过不要有错误块。尤其是变量表和全局DB必须先编译一次生成下载时才会带过去。第三步启动PLCSIM Advanced V4.0创建一个虚拟实例选择对应型号比如V4.0 S7-1200启动实例后会给虚拟PLC分配IP地址。这里最容易踩坑如果PLCSIM Advanced提示“Instance already exists”说明上一个实例没关干净到主界面把旧实例停止删除再重来。第四步回到TIA Portal点击下载按钮目标接口选PLCSIM Advanced下载后把PLC切到RUN模式。第五步打开Factory IO加载“Automated Warehouse”场景在File - Drivers里选“Siemens S7-PLCSIM Advanced”填上IP地址192.168.0.1点Connect。如果连接成功Factory IO界面下方的状态会变成绿色的“Connected”。这里有个小经验连接之前确认PLC处于RUN如果PLC还是STOPFactory IO能连上但I/O不会刷新场景里所有动作都动不了。2.3 通信接口与原理解读很多同学会问为什么不用TIA自带的S7-PLCSIM而是用PLCSIM Advanced原因在于老版S7-PLCSIM主要是仿真TIA内部的程序逻辑对外网络接口很弱Factory IO这种外部仿真软件需要和PLC建立以太网通信PLCSIM Advanced等价于一台虚拟真实PLC有完整的IP协议栈通信行为更接近实际设备。这对以后接入真实HMI、第三方设备也有参考价值。数据交互方式上Factory IO把场景里的传感器映射成虚拟PLC的输入点把执行器映射成输出点。实际运行的顺序是PLC程序扫描一遍根据输入传感器状态和内部逻辑刷新输出虚拟PLC把这些输出点位状态通过网络发回Factory IOFactory IO物理引擎根据输出执行动作再更新传感器状态如此循环。所以整个仿真系统的节拍与PLC的扫描周期强相关这也是后面调试时定位不准问题的根源之一。3. PLC程序结构与核心逻辑实现3.1 信号映射与I/O规划写程序之前先做I/O映射。我按Factory IO中立体仓库场景的典型信号做了个示例表。因为不同版本的Factory IO场景信号名称可能有差异这里以逻辑功能为准具体点位以你打开场景的I/O面板为准。信号名称方向数据类型功能说明StartDIBool启动自动流程StopDIBool停止自动流程ResetDIBool故障复位AutoModeDIBool手动/自动切换Sensor_InDIBool入料位货物检测Sensor_OutDIBool出料位货物检测Home_XDIBoolX轴原点信号Limit_XDIBoolX轴超限信号Home_ZDIBoolZ轴原点信号Limit_ZDIBoolZ轴超限信号Vacuum_OKDIBool吸盘真空检测Conveyor_InDOBool入料传送带正转Conveyor_OutDOBool出料传送带正转Pusher_OutDOBool推杆伸出Pusher_InDOBool推杆退回Motor_X_ForwardDOBoolX轴正向运动Motor_X_BackwardDOBoolX轴反向运动Motor_Z_UpDOBoolZ轴上升Motor_Z_DownDOBoolZ轴下降Vacuum_OnDOBool吸盘吸附控制这组信号已经覆盖了入库、出库、回原点和急停保护的全部需求。如果你要加手动操作可以再补一组按钮信号。3.2 数据块规划货位状态和坐标表程序里最关键的数据结构是货位状态表和坐标表。我建了一个全局DB名字叫“DB_Warehouse”里面包含两个核心数组// 货位状态ROW_COUNT4排COL_COUNT5列 SlotsStatus : ARRAY[1..4, 1..5] OF Bool; // 每个货位的X轴目标脉冲位置 SlotPosX : ARRAY[1..4, 1..5] OF DInt; // 每个货位的Z轴目标脉冲位置 SlotPosZ : ARRAY[1..4, 1..5] OF DInt;货位状态用Bool数组True表示已占用False表示空闲。坐标表是位置定位的核心每个货位对应堆垛机的X轴和Z轴目标位置。如果你用编码器计数这两个值就是脉冲数如果你用时间定位就是运动时间。数组的好处是访问货位时直接传行号和列号代码逻辑会很简洁。这里有个容易忽略的点S7-1200仿真器对多维数组的处理完全支持但如果你把数组做成FB的静态变量每次调用都要初始化比较烦。所以货位数据我建议放在全局DB而不是FB内部。这样既能掉电保持又能让多个FB共享访问。3.3 堆垛机运动控制坐标定位与加减速处理堆垛机的X轴和Z轴我采用的是“目标位置比较脉冲反馈”的闭环定位方式和实际项目中编码器定位的思路一致。核心逻辑是X轴当前位置大于目标位置时反转小于目标位置时正转到达目标位置后停止。Z轴同理。不过在实际编程时不能只做简单的“等于就停”。因为扫描周期和运动惯性的存在CPU可能永远读不到绝对相等的位置。更稳妥的做法是加一个死区判断比如当前位置和目标位置偏差小于10个脉冲就认为到位。IF #X_Position (#TargetX - 10) THEN #Motor_X_Forward : TRUE; #Motor_X_Backward : FALSE; ELSIF #X_Position (#TargetX 10) THEN #Motor_X_Forward : FALSE; #Motor_X_Backward : TRUE; ELSE #Motor_X_Forward : FALSE; #Motor_X_Backward : FALSE; #X_InPosition : TRUE; END_IF;这里的#X_Position是通过编码器反馈累计出来的。简单说正向运动时累加脉冲反向运动时减少脉冲。每次碰到Home信号就把X轴位置清零完成原点校准。如果没有编码器信号退而求其次用定时方式记录运动开始时间经过预设时间后停车但精度确实低只适合演示。3.4 状态机框架入库出库流程不再乱立体仓库的流程控制我强烈建议用状态机别用梯形图一路串下去。为什么因为入库和出库流程之间有大量分支、等待、异常跳转梯形图写着写着就会变成一坨互相缠绕的线圈。状态机把所有流程抽象成有限个状态每个状态里只处理“做什么”和“下个状态是什么”排障时直接看当前状态号就知道卡在哪一步。我定义的状态机大致包含这些状态IDLE待机等待任务。GOTO_PICK_POS移动到取料点。PICK_GOODS执行抓取动作吸盘吸附。GOTO_PLACE_POS移动到目标货位。PLACE_GOODS放置货物。GOTO_UNPICK_POS移动到出库取货货位。UNPICK_GOODS抓取货物出库。GOTO_DROP_POS移动到出料口。DROP_GOODS放下货物。RETURN_HOME回原点。用SCL写状态机非常清晰我放一段入库流程的核心代码片段CASE #StepNo OF 0: // IDLE状态判断任务 IF #PickRequest THEN #FindSlot : FC_FindFreeSlot(#WarehouseDB); IF #FindSlot 0 THEN #StepNo : 10; END_IF; END_IF; 10: // 移动到取料点X轴和Z轴同时定位 #TargetX : #PickPositionX; #TargetZ : #PickPositionZ; // 调用运动控制块检测到位 IF #X_InPosition AND #Z_InPosition THEN #StepNo : 20; END_IF; 20: // 执行吸取 #Vacuum_On : TRUE; IF #Vacuum_OK THEN #StepNo : 30; // 关闭取料传送带 #Conveyor_In : FALSE; END_IF; 30: // 移动到目标货位 #TargetX : #WarehouseDB.SlotPosX[#Row, #Column]; #TargetZ : #WarehouseDB.SlotPosZ[#Row, #Column]; IF #X_InPosition AND #Z_InPosition THEN #StepNo : 40; END_IF; 40: // 放置货物 #Vacuum_On : FALSE; // 放置完成后更新货位状态 #WarehouseDB.SlotsStatus[#Row, #Column] : TRUE; #StepNo : 90; 90: // 回原点 #TargetX : 0; #TargetZ : 0; IF #X_InPosition AND #Z_InPosition THEN #StepNo : 0; END_IF; END_CASE;这段代码看起来简洁但有几个细节必须留意。第一状态跳转前要确保所有输出已经复位尤其是吸盘、传送带这类执行器避免货物还没放稳就被传送带带走。第二状态号不要用0到90这种大跨度跳转排障时会很难受建议用更紧凑的10、20、30……这样打印监控时一眼能看出流程进度。第三状态机每次扫描只执行一个状态不能靠“下一个循环自动进入下个状态”这种潜意识一定要在状态内部条件满足后再改#StepNo。3.5 货位管理先进先出和空位查找空位查找逻辑很简单遍历SlotsStatus数组找到第一个False的行、列计算仓位编号返回。但有些场景要求先进先出出库就是先入库的货物先出库。这时候不能只找空位还要记录每个货位的入库顺序号。我在DB里加一个二维整数数组SlotOrder每次入库时把当前入库计数器写入该货位出库时扫描所有SlotOrder找到值最小最早入库且非零的货位。// 查找最早入库货位 #OldestOrder : 9999; #FoundRow : 0; #FoundCol : 0; FOR #R : 1 TO 4 DO FOR #C : 1 TO 5 DO IF #WarehouseDB.SlotsStatus[#R, #C] AND #WarehouseDB.SlotOrder[#R, #C] #OldestOrder THEN #OldestOrder : #WarehouseDB.SlotOrder[#R, #C]; #FoundRow : #R; #FoundCol : #C; END_IF; END_FOR; END_FOR;用数组遍历做货位管理好处是直观、易改。如果货位扩展到几十上百个建议改用SCL的指针或批量操作指令效率更高。在这个项目中只有20个货位4排5列PLC扫描周期完全无压力。3.6 安全保护与手动模式自动状态机跑起来之后一定要把安全保护放进去。我在程序里加了以下几层保护限位保护X轴或Z轴碰到Limit信号时无论状态机在哪个状态立即切断对应轴的运动输出。Home缺失保护正常情况下开机先回原点如果找不到Home信号禁止任何自动任务。吸盘真空丢失保护入库流程中如果吸盘吸住货物后真空信号消失必须停下来报警不能带着半空货物继续移动。手动/自动切换手动模式只允许点动单个轴或执行器自动模式下才允许状态机运行。切换模式时必须先让状态机回到IDLE状态。这些保护逻辑我习惯单独写在一个FC块里在每个扫描周期无条件调用。这样即使状态机出bug保护块还是会执行安全底线保住了。4. 调试过程与常见问题排查实录4.1 通信连不上先查这三个地方我调试时遇到最多的问题是Factory IO点击Connect后提示连接失败。排查顺序就是三步第一步查地址。PLCSIM Advanced实例启动后分配的IP和TIA Portal里组态的CPU IP是否一致Factory IO驱动面板里填的IP是否一致。三个地方有一个不同都连不上。这个最简单但也最容易因为粗心出错。第二步查状态。PLCSIM Advanced的实例一定要在RUN状态如果停在STOPFactory IO虽然能握手成功但I/O不刷新现象就是所有执行器不动传感器也读不到变化。第三步查防火墙。Windows防火墙默认会拦截PLCSIM Advanced的虚拟网络通信。我是在控制面板里把“PLCSIM Virtual Ethernet Adapter”相关的入站规则设为允许或者在调试期间暂时关闭防火墙。如果公司电脑有安全策略没法关防火墙也可以尝试以管理员身份运行TIA和Factory IO有时候权限不够也会导致虚拟网卡识别异常。4.2 堆垛机定位不准不是程序问题是运动学和时序问题定位不准是立体仓库项目里最让人崩溃的问题。我刚开始用“固定时间固定速度”的方式定位给X轴正转3秒就停结果十次有八次位置都对不上。原因很简单Factory IO物理引擎的仿真步长、PLC扫描周期、输出刷新时间三者叠加导致实际运动时间永远不是理想值。解决办法是改成“回原点编码器计数”的闭环定位就是前面代码里的方式。如果你实在没有编码器信号只能用时间定位我的经验是先让堆垛机走到Home从Home开始计时每个货位的运动时间通过实测标定不要自己拍脑袋估算。标定方法手动让X轴从Home走10秒量出实际距离反推出每秒钟位移再换算到每个货位所需的运动时间。虽然精度不如编码器但至少能跑通演示。其实即便有编码器扫描周期抖动也会让位置停得不够准。我的处理是给每个轴增加“到位允许偏差”比如50个脉冲。只要位置落在偏差范围内就算到位然后立即切断运动输出。这个偏差值不能设太大否则货位之间会混淆也不能太小否则永远停不下来。50这个值是我在仿真里反复试出来的。4.3 货位状态错乱DB初始化和掉电保持的坑有一次运行过程中发现货架明明空着程序却认为货位上还有货物。排查到最后问题出在DB的掉电保持属性上。S7-1200的全局DB默认是掉电保持的我在调试时多次用“停止仿真”代替“断电重启”结果上一次运行留下的货位占用数据一直残留在DB里下次启动时旧状态还在。解决办法有两个。一是把“SlotsStatus”数组的保持属性改为非保持每次上电自动恢复初始值也就是全False。二是保持属性保留但增加一个“复位仓库”按钮或“首扫描初始化”逻辑在OB100启动组织块里把所有货位占用标志清零同时把堆垛机位置清0。我实际项目里两种方式都有用掉电保持的DB适合真实场景断电后再上电能恢复现场仿真环境则建议用OB100初始化让每次仿真都从干净状态开始。4.4 常见问题速查表现象可能原因处理方法Factory IO连接不上PLCIP不一致、实例未启动、防火墙拦截逐项核对IP实例切RUN检查防火墙规则程序不执行PLC处于STOP或未下载最新程序下载后点运行在线监控确认块状态传送带不转输出点没有接通或信号映射错误在线强制输出测试核对I/O映射表堆垛机只往一个方向走限位信号未生效位置反馈错误检查Home/Limit信号状态轴方向逻辑位置计数方向货物放到半空没到位位置偏差过大或吸盘提前释放增加到位偏差阈值检查到位判断条件状态机卡在某一步状态跳转条件未满足传感器信号没到监控状态号逐个条件排查重点看限位和真空信号货位状态与实物不符DB保持数据残留或初始化逻辑缺失增加OB100初始化或改成非保持DB4.5 我具体调试时的一段经历说个实际调试中的事情。那天程序下载进去启动运行入料传送带动了货物一到上料位堆垛机就冲过去。结果吸盘刚吸住货物X轴就疯狂向货架方向跑然后在第一个货位附近自动停了。我以为是定位问题反复调坐标表折腾了半天最后在线监控才发现状态机在PICK状态里判断“真空OK”用的是Vacuum_OK信号但Factory IO里这个信号在吸盘接触货物前后有一个短暂的假信号导致程序认为“已经吸好”并提前切到下一状态。后来我在真空检测的判断里加了一个2秒的稳定延时问题就解决了。这类问题在真实设备里也特别常见传感器信号毛刺、开关抖动、气缸到位信号提前都会让状态机走乱。所以我现在的习惯是所有关键翻转信号都加一个去抖延时不急着在下一次扫描就触发动作。在S7-1200里可以用TON定时器实现几行SCL就搞定。5. 进阶延伸与项目体会5.1 扩展HMI监控程序能跑通之后我顺手加了个HMI画面。用TIA Portal V16内置的WinCC连到PLCSIM Advanced直接在虚拟运行系统里跑。画面里显示货位占用矩阵、堆垛机当前位置、当前状态机步号、入库出库计数还能点按钮切换手动/自动模式。这里要提醒一句WinCC和PLCSIM Advanced的通信需要在HMI连接设置里选择“PLCSIM Advanced”作为接口不能用普通的S7-1200/1500连接。如果发现HMI里所有变量都显示“###”基本都是连接接口没选对。接入HMI之后调试效率提升很大。因为状态机步号、当前坐标这些变量直接可视化能立刻看到是在定位、等待还是卡住了。没有HMI的话只能用监控表盯变量效率低很多。5.2 让立体仓库和外部设备联动这个项目再往后延伸可以把立体仓库当成一个大型自动化产线的一环。比如用Modbus TCP让堆垛机把“当前货位状态”发给上位机或者用PROFINET和一台ABB机器人联动实现机器人把工件放到入料传送带上立库完成仓储出库时再取走。这些通信方式在TIA Portal V16里都有现成库函数只是要注意地址映射和通信数据块大小。如果手里有真实变频器比如G120XA也可以尝试把入料传送带的电机模型换成变频器驱动用485或者PROFINET报文控制速度。这个扩展的核心思路是把“传送带正转”这个布尔量替换成“变频器启动目标频率”整个立库逻辑的外层不变底层驱动方式变了。这样学到的就不只是仿真还顺手把工控通信协议练了一遍。5.3 我做完这个项目的真实体会做完这个立体仓库项目我最大的体会是PLC编程最大的难点不是指令而是流程抽象和边界条件处理。梯形图写顺序控制虽然直观但当流程有几十个状态、多个分支时状态机的优势就非常明显了。SCL写状态机不复杂但要想清楚每个状态的前置条件和后置动作不然就是在状态跳转里来回奔波。另一个体会是仿真毕竟不是现场Factory IO的物理模型已经比普通仿真软件真实很多但它不含PLC扫描周期的随机波动也不会有真实传感器的温漂和触点抖动。这意味着仿真跑通的项目到现场依然要充分考虑信号抖动、机械误差、通信中断这些“现实毒打”。不过也正因为如此在这个项目里把逻辑吃透了到了现场反而能更快定位问题。这个项目后续还可以扩展的方向包括多辆堆垛机协同同一轨道避让、仓库容量动态规划、订单队列管理等。如果你们公司正好有真实的立体仓库项目这套状态机加货位管理的思路可以直接迁移无非是把仿真I/O换成真实I/O把编码器脉冲累加换成伺服驱动的绝对位置反馈整体架构不用改。本文还有配套的精品资源点击获取