PLC实战避坑指南:从IO分配到程序框架的90条经验 1. 入行前三年我把PLC踩过的坑都翻了一遍刚入行那会儿我总觉得PLC编程就是“画梯形图、下载程序、按启动按钮”这三件事。真正进了车间才发现程序能跑通和产线能稳定量产之间隔着至少一百个细节。我做过食品包装线的改造也跟过汽车零部件厂的六轴机械臂调试还接过冷库监控这种温湿度PID常年波动的烂摊子。三年下来我攒了90条实战经验有些是师傅骂出来的有些是半夜三点在客户现场自己悟出来的。这篇文章不打算讲“PLC是什么”这种教科书内容而是把入行1到3年的工程师最常卡住的地方——IO分配怎么做才不返工、梯形图怎么写才不被后来人骂、西门子1200的程序框架怎么搭才不越写越乱、Modbus和OPC UA读上来的数据怎么用——一条条拆开讲。如果你刚入行或者正在从“能写程序”往“能扛项目”过渡这些内容应该能帮你少走不少弯路。2. 先想清楚再动手PLC项目整体设计与思路拆解2.1 为什么IO分配表比程序本身还重要很多人拿到项目第一反应是打开博途或者GX Works开始画梯形图这是典型的“先写代码再想架构”。我吃过最大的亏是在一个包装线上程序写了三天到现场发现IO点对不上光电开关的常开常闭和程序里完全反了结果整条线的逻辑全部要翻。后来我养成一个习惯任何项目先出IO分配表而且这张表要包含六个字段——序号、信号名称、信号类型DI/DO/AI/AO、PLC地址、电气符号、备注。备注里必须写清楚这个信号是常开还是常闭、是PNP还是NPN、有没有特殊要求。为什么这么强调因为IO分配表是电气工程师、PLC程序员、现场调试人员三方共用的“合同”。你表里写I0.0是启动按钮常开电气接线就必须按常开来接你写Q0.0控制接触器现场就得确认接触器线圈电压和PLC输出类型匹配。我见过太多项目因为IO表没对齐导致程序逻辑全部重写。一个中等规模的产线IO点通常在80到200个之间如果没有表你写到一半自己都不记得I3.7是干什么的。提示IO分配表建议用Excel做按DI、DO、AI、AO分Sheet每个Sheet里按设备工位排序不要按地址排序。地址是结果工位才是逻辑。2.2 程序框架的选型逻辑为什么我最终选了西门子1200入行前两年我用过三菱FX3U、台达、信捷后来主力转到西门子S7-1200。不是说其他品牌不好而是1200在中小型非标项目里有一个很舒服的平衡点本体IO够用、支持Profinet、博途的变量表和交叉引用做得足够好、Modbus和OPC UA都有现成库。三菱FX3U的梯形图很直观但一旦项目超过50个IO点没有结构化编程会写得非常痛苦。信捷XD3系列在伺服脉冲控制上性价比很高但程序框架的复用性偏弱。我现在的1200项目框架基本固定为几个FB块主控FB、报警FB、模拟量处理FB、通讯FB、HMI交互FB。主循环里只调用这几个FB每个FB内部再细分。这样做的好处是下一个项目来了我把FB复制过去改一下IO映射和参数就能跑。很多人写程序是“一个Main从头写到尾”写到后面自己都找不到变量在哪。FB框架的代价是前期要多花半天搭结构但后期调试和修改的时间能省掉至少两天。2.3 梯形图还是SCL别被“梯形图万能论”绑住刚入行时师傅跟我说“梯形图是PLC的根先把梯形图写熟”。这话对了一半。梯形图在逻辑互锁、电机正反转、顺启逆停这些场景下确实直观但遇到数据处理——比如把10进制转16进制、做PID运算、解析Modbus报文——梯形图会写得非常臃肿。我在一个温度PID项目里试过用梯形图写PID调节光是比较和运算就占了十几行后来改用SCL写了一个FB代码量少了三分之二可读性还更好。我的建议是逻辑控制用梯形图数据处理用SCL通讯用现成库。西门子1200支持LAD和SCL混编同一个FB里可以既有梯形图网络又有SCL代码块。不要强迫自己只用一种语言工具是拿来用的不是拿来供的。3. 核心细节解析与实操要点3.1 IO分配的具体操作与常见陷阱IO分配不是简单地把信号列出来有几个细节直接决定调试顺不顺利。第一DI点要预留至少10%的余量。我做过一个项目IO表上DI用了28个点选了1214C本体14DI/10DO结果现场临时加了两个传感器只能加扩展模块柜内空间不够最后把模块装到了柜门上。第二DO点要确认负载类型。PLC继电器输出可以带交流接触器但晶体管输出只能带直流负载而且要注意续流二极管。我见过一个项目用晶体管输出直接带电磁阀没有加续流二极管用了两个月输出点烧了三个。第三AI点的信号类型要提前确认。是4-20mA还是0-10V是两线制还是四线制这决定了PLC模拟量模块的接线方式和量程配置。西门子1200的AI模块默认是电压输入接4-20mA信号需要并一个250欧姆电阻或者选支持电流输入的模块。这个细节如果IO表里没写现场调试时发现信号读出来全是0或者满量程排查起来很浪费时间。信号类型常见规格接线注意程序处理DI24VDC PNP/NPN确认公共端接法常开常闭与程序逻辑一致DO继电器/晶体管晶体管需加续流二极管确认负载电流不超限AI4-20mA/0-10V电流输入需并电阻或选模块量程转换用NORM_X和SCALE_XAO4-20mA/0-10V确认执行器输入类型输出值限幅防止超程3.2 梯形图编程的五个实战要点梯形图看起来简单但写得好和写得能用的差距很大。第一个要点是网络注释。博途里每个网络都可以加注释我要求自己每个网络必须写清楚“这个网络在什么条件下执行、输出什么”。半年后回头看自己写的程序如果没有注释连自己都要重新捋一遍。第二个要点是避免双线圈。同一个输出Q点在多个网络里被赋值程序会以最后一个网络为准前面的逻辑全部失效。我见过一个项目Q0.0在三个地方被写现场设备动作完全乱套排查了一整天才发现是双线圈。第三个要点是定时器要统一编号管理。三菱FX3U的T0到T199是100ms定时器T200到T245是10ms定时器如果随便用后面想改时间基准就要全部重来。西门子1200的定时器是IEC定时器每个定时器是一个背景数据块建议在DB块里统一声明不要散落在各个FB里。第四个要点是上升沿和下降沿要慎用。上升沿检测需要存储前一个扫描周期的状态如果放在条件调用里可能会丢失沿信号。我通常把沿检测放在主循环里用M点或者DB变量存储状态。第五个要点是模拟量处理要用NORM_X和SCALE_X。很多人用梯形图做模拟量转换写一堆MUL和DIV容易出错。西门子1200有现成的NORM_X和SCALE_X指令NORM_X把原始值归一化到0.0到1.0SCALE_X再映射到工程值。比如一个4-20mA的压力传感器量程0到10bar原始值0到27648NORM_X输出0.0到1.0SCALE_X输出0.0到10.0。这个链条清晰且不容易出错。3.3 西门子1200程序框架的搭建步骤我现在的1200项目框架搭建分五步。第一步建变量表。在PLC变量表里按设备工位分组比如“上料工位”、“加工工位”、“下料工位”每个工位下的变量加前缀。第二步建DB块。建一个全局DB叫“G_Data”里面放所有跨FB共享的变量比如报警字、状态字、配方参数。第三步建FB块。主控FB、报警FB、模拟量FB、通讯FB各一个每个FB的接口区定义好Input、Output、InOut。第四步写主循环。OB1里只调用FB不写具体逻辑。第五步做HMI映射。HMI变量直接连DB块里的变量不要连M点M点掉电不保持而且不好管理。这个框架搭下来大概需要半天时间但后面写逻辑会非常顺。我试过在一个项目里偷懒不搭框架直接写OB1写到第三天就发现变量冲突、逻辑交叉最后花了一天时间重构。搭框架的时间不是浪费是投资。3.4 Modbus和OPC UA读取设备数据的实操细节现在很多项目要求PLC读取传感器、数控机床、变频器的运行状态数据。Modbus RTU和Modbus TCP是最常见的协议OPC UA在数控机床和MES对接场景里越来越普遍。西门子1200做Modbus RTU需要CM 1241 RS422/485通讯模块做Modbus TCP可以用本体网口。OPC UA需要授权而且1200做OPC UA服务器可以做客户端需要额外配置。我做过一个项目用1200通过Modbus RTU读ABB变频器的运行频率和电流。步骤是第一步确认变频器的Modbus地址和波特率ABB变频器默认地址是1波特率9600。第二步在博途里添加CM 1241模块配置端口参数。第三步调用Modbus_Comm_Load和Modbus_Master指令。Modbus_Comm_Load的REQ用上升沿触发PORT填模块的硬件标识符。Modbus_Master的MB_ADDR填变频器地址MODE填0读保持寄存器DATA_ADDR填变频器手册里的寄存器地址DATA_LEN填要读的寄存器数量。这里有个坑ABB变频器的寄存器地址和Modbus地址有偏移。手册里写的是40001但Modbus协议里实际地址是0所以DATA_ADDR要填0而不是40001。这个偏移量每个品牌不一样西门子自己的设备是40001对应地址0但有些品牌是40001对应地址1。调试时如果读不到数据先检查这个偏移。OPC UA读取数控机床数据更复杂一些。数控机床通常作为OPC UA服务器PLC作为客户端去订阅。1200做OPC UA客户端需要调用“OPC_UA_Connect”、“OPC_UA_Read”等指令而且需要购买OPC UA授权。我建议如果只是读几个状态字用Modbus TCP更简单如果要读大量结构化数据OPC UA更合适。4. 实操过程与核心环节实现4.1 一个完整项目的调试流程记录我拿最近做的一个小型非标项目举例设备是一台自动锁螺丝机控制要求是气缸上料、伺服定位、电批锁付、气缸下料。PLC用1214C伺服是汇川IS620PHMI是西门子KTP700。调试流程分五步。第一步静态检查。不上电用万用表检查24V电源对地是否短路检查DI公共端接法检查DO负载是否匹配。这一步花20分钟但能避免上电烧模块。第二步IO点动测试。上电后不跑程序在博途的监控表里强制Q点逐个确认气缸动作、伺服使能、电批启动。这一步要确认每个输出对应的物理动作和IO表一致。第三步手动模式调试。写一个手动FB每个动作单独触发确认气缸到位信号、伺服定位完成信号、电批扭力到达信号都能正确读入。第四步自动模式调试。把手动动作串成自动流程加互锁和超时报警。第五步连续运行测试。让设备连续跑50个循环观察有没有偶发故障。这个流程里第三步和第四步最容易出问题。手动模式正常但自动模式卡住通常是互锁条件写得太严或者某个到位信号的时序不对。我遇到过一次气缸到位信号在自动模式里读不到手动模式却正常后来发现是自动模式里气缸动作和信号读取在同一个扫描周期信号还没稳定就被读了。解决办法是加一个0.1秒的延时或者用上升沿触发。4.2 伺服电机控制的参数计算与梯形图实现汇川IS620P伺服驱动器用脉冲方向控制PLC发脉冲。1214C本体不支持高速脉冲输出需要加信号板SB 1223或者用工艺对象。我用的方案是PTO脉冲串输出在博途里配置工艺对象“定位轴”。参数计算伺服电机编码器是17位即131072脉冲每转丝杆导程是5mm所以每个脉冲对应5/131072≈0.000038mm。如果要求定位精度0.01mm这个分辨率完全够用。梯形图实现上我用MC_Power使能轴MC_MoveAbsolute做绝对定位MC_MoveRelative做相对定位MC_Reset复位故障。每个运动指令的Execute用上升沿触发Done和Error做状态判断。这里有个细节MC_Power的Enable要一直为TRUE否则轴会掉使能。我见过一个项目MC_Power的Enable用了一个按钮按钮松开轴就掉使能设备直接报警。注意伺服使能后如果长时间不动作有些驱动器会进入待机状态需要周期性发脉冲或者用MC_MoveJog保持。具体看驱动器手册。4.3 温度PID波动大的调节方法冷库监控项目里温度PID波动大是常见问题。我遇到的情况是设定-18℃实际在-22℃到-14℃之间来回摆温差8℃。排查思路分三层。第一层确认传感器响应。PT100的响应时间通常在10到30秒如果传感器安装位置靠近蒸发器会提前感受到温度变化导致PID误判。解决办法是把传感器移到冷库中间位置或者加一个热缓冲套管。第二层确认PID参数。西门子1200的PID_Compact指令比例增益P太大导致振荡积分时间I太小导致超调。我的经验值是冷库温度PIDP设2.0到5.0I设300到600秒D设30到60秒。具体值要用自整定功能先跑一遍再手动微调。第三层确认执行器动作。冷库的压缩机通常不是连续调节而是通过电磁阀开停来控制。如果PID输出直接控制电磁阀电磁阀频繁启停会导致温度波动。解决办法是加一个PWM周期比如PID输出0到100%映射到电磁阀的占空比周期设60秒。这样电磁阀不会频繁动作温度也更平稳。问题现象可能原因排查方法解决措施温度持续偏高制冷量不足检查压缩机电流、冷媒压力补充冷媒或检修压缩机温度振荡P太大或I太小查看PID输出曲线减小P增大I温度响应慢传感器位置不当对比传感器读数和实际温度调整传感器位置电磁阀频繁动作PID输出直接控制观察电磁阀动作频率加PWM周期转换4.4 十字路口红绿灯PLC程序的实现思路红绿灯程序是很多人的入门练手项目但写好也不容易。我用1214C做过一个带倒计时的红绿灯东西向和南北向各三灯红黄绿倒计时用HMI显示。核心逻辑用一个状态机状态0东西绿南北红状态1东西黄南北红状态2东西红南北绿状态3东西红南北黄。每个状态用一个定时器时间到切换到下一个状态。梯形图实现上我用一个整数变量“State”表示当前状态用比较指令判断状态用TON定时器做状态切换。倒计时用定时器的ET值换算成秒传给HMI。这里有个细节黄灯时间要单独设不能和绿灯共用定时器。我见过一个程序黄灯和绿灯用同一个定时器结果黄灯时间跟着绿灯走绿灯30秒黄灯也30秒实际黄灯只要3秒。5. 常见问题与排查技巧实录5.1 通讯类问题速查通讯问题占了我调试时间的一半以上。Modbus RTU通讯不上先查三样接线、波特率、站地址。RS485接线是A接A、B接B但有些设备标注是D和D-对应关系要查手册。波特率和站地址在PLC和从站两边都要一致。如果接线和参数都对用串口调试助手抓报文看PLC有没有发出去、从站有没有回。我遇到过一次PLC发出去的报文从站收到了但从站回的报文PLC收不到后来发现是RS485模块的终端电阻没接信号反射导致误码。Modbus TCP通讯不上先ping通IP再确认端口502是否开放。西门子1200做Modbus TCP客户端调用MB_CLIENT指令CONNECT参数填TCON_IP_v4结构体里面填从站IP和端口。如果连接建立但读不到数据检查MB_CLIENT的MB_ADDR和DATA_ADDR。有些设备的Modbus TCP和RTU的寄存器地址不一样要分别查手册。OPC UA通讯问题更复杂常见的是证书信任问题。1200做OPC UA服务器客户端连接时需要信任服务器证书。如果客户端不信任连接会被拒绝。解决办法是在客户端里导入服务器证书或者在服务器里关闭证书验证不推荐有安全风险。另外OPC UA的节点ID要确认不同设备的节点ID命名规则不一样。通讯类型常见问题排查步骤解决技巧Modbus RTU通讯超时查接线、波特率、站地址用串口助手抓报文Modbus TCP连接失败ping IP、查端口确认寄存器地址偏移OPC UA证书拒绝查证书信任列表导入证书或关闭验证Profinet设备掉站查网线、设备名称确认设备名称和IP5.2 程序类问题速查程序类问题最典型的是输出不动作。排查顺序先看PLC输出指示灯亮不亮灯亮但设备不动查外部接线和负载灯不亮查程序逻辑。程序逻辑里先看有没有双线圈再看有没有条件不满足。我遇到过一次Q0.0在三个网络里被写最后一个网络的条件是M0.0而M0.0一直为FALSE所以Q0.0永远不亮。用博途的交叉引用功能可以快速定位一个变量在哪些地方被读写。模拟量读数不对也是高频问题。先确认模块的测量类型配置对不对电压还是电流量程是0-10V还是4-20mA。再确认接线两线制还是四线制。最后确认程序里的量程转换NORM_X的MIN和MAX填的是原始值范围SCALE_X的MIN和MAX填的是工程值范围。如果读数一直是0或者满量程大概率是接线或模块配置问题。定时器不动作先看定时器的使能条件再看时间基准。西门子1200的TON定时器IN为TRUE时开始计时ET达到PT时Q输出TRUE。如果IN一直为FALSE定时器不会计时。三菱FX3U的定时器T0的设定值是K100时间基准是100ms所以是10秒。如果误用了T20010ms基准K100就是1秒。5.3 现场调试的独家避坑技巧第一条永远带一个笔记本和一支笔。现场调试时IO点的实际接线可能和图纸不一致程序里的临时修改可能忘了改回来。记下来晚上回酒店整理。我吃过亏现场改了一个定时器时间忘了改回去第二天设备动作不对排查了半天。第二条改程序前先备份。博途里可以“另存为”一个新版本或者用“归档”功能。现场调试时程序可能被改得面目全非如果客户说“还是昨天的版本好”你没有备份就麻烦了。我现在的习惯是每天下班前归档一次文件名带日期。第三条和电气工程师确认公共端。DI点的公共端是接24V还是0V决定了PNP还是NPN。如果PLC默认是PNP公共端接0V但现场传感器是NPN信号会反。解决办法是在PLC输入端加一个继电器转换或者在程序里取反。但取反不是长久之计最好在IO表阶段就确认清楚。第四条伺服和步进电机的脉冲信号要用示波器看。PLC发脉冲如果频率太高或者占空比不对驱动器可能收不到。我遇到过一次PLC发脉冲的频率是200kHz但驱动器最大只支持100kHz结果电机不转。用示波器看脉冲波形确认频率和幅值。第五条HMI变量不要直接连M点。M点是位存储区掉电不保持而且M点的地址是全局的容易冲突。HMI变量应该连DB块里的变量DB块可以设置保持属性而且变量名清晰。我见过一个项目HMI上显示的温度值一直不变后来发现连的是M点而程序里M点被其他地方覆盖了。5.4 非标项目调试的节奏控制非标项目的特点是“每个项目都不一样”所以调试节奏很重要。我的经验是先跑通手动再跑自动先跑单站再跑整线先跑空载再跑负载。手动模式是基础手动都不对自动肯定不对。单站调试时把每个工位的动作单独跑通再串起来。空载跑通后再带负载跑观察电流、气压、速度有没有异常。调试时要有“假设-验证”的思维。比如设备不动先假设是程序问题用监控表看输出如果输出正常再假设是电气问题用万用表查线路如果线路正常再假设是机械问题手动盘车看有没有卡死。不要一上来就改程序很多时候问题不在程序里。提示非标项目调试时建议用“分段调试法”。把整条线分成几个功能段每段单独调试调好一段再调下一段。这样出问题时排查范围小容易定位。6. 从能写程序到能扛项目还差什么入行前三年我最大的感受是PLC编程本身不难难的是把编程放到整个项目里去看。IO分配、程序框架、通讯配置、现场调试每一个环节都有坑而且这些坑在教科书里不会写。我总结的这90条经验有些是技术细节有些是工作习惯有些是思维方式。技术细节可以查手册工作习惯和思维方式只能靠项目喂出来。如果你现在还在写“一个Main从头到尾”的程序建议你下一个项目试着搭一个FB框架如果你还在用梯形图硬写数据处理建议你学一下SCL如果你还在现场改程序不备份建议你从明天开始每天归档。这些改变不会让你立刻变成高手但会让你在下一个项目里少熬两个夜。PLC这行经验是熬出来的但有些夜可以不熬。