1. 为什么变量定义和IO关联是TwinCAT3项目真正的“启动开关”
很多人装完TwinCAT3,新建一个PLC项目,写完几行ST代码,编译通过、下载成功、运行灯亮——就以为“程序跑起来了”。结果一接真实设备,电机不转、传感器没响应、HMI显示乱码。我第一次在客户现场遇到这种情况时,调试了整整两天,最后发现:变量名写对了,地址也配对了,但变量类型和硬件端子的电气特性完全不匹配。一个被定义为INT的变量,硬生生绑到了一个24V PNP型接近开关上,而这个开关实际输出的是开关量信号,根本不是数值。这种“逻辑通”但“物理断”的状态,在TwinCAT3里极其隐蔽,因为编译器不会报错,运行时也不会崩溃,它只是安静地把错误的数值传给你的算法。
这就是为什么我把变量定义和IO关联称为TwinCAT3项目的“启动开关”——它不是编程的起点,而是系统能否真正与物理世界对话的唯一入口。你写的再漂亮的PID控制算法,如果输入变量没连到真实的温度探头,输出变量没驱动到真实的变频器启停端子,那整套逻辑就是空中楼阁。TwinCAT3的强项在于其“配置即编程”的理念,但这也意味着:变量不是孤立的数据容器,而是物理IO通道在软件世界里的精确映射。它要求你同时具备PLC逻辑思维和电气工程常识。比如,看到一个BOOL变量,你得立刻反应出它背后对应的是一个干接点还是一个晶体管输出;看到一个REAL变量,你得知道它是否经过了模拟量模块的16位ADC采样、是否需要做线性化补偿、量程是否和传感器标称值一致。
从网络热词来看,“twincat3本地模拟”和“结构体变量的定义”高频并存,恰恰暴露了一个普遍误区:新手习惯先在纯软件环境里把逻辑跑通,再回头去配硬件。这在TwinCAT3里是本末倒置的。TwinCAT3的IO扫描周期、任务调度、甚至变量的内存布局,都深度耦合于硬件组态。你在本地模拟时用%IX0.0模拟一个按钮,和你在真实EtherCAT总线上用AX5203模块的第1个DI通道绑定%IX0.0,它们的底层行为、响应延迟、抗干扰能力,完全是两回事。所以,这篇教程不教你如何写一个闪烁灯程序,而是带你亲手拧紧这颗最关键的螺丝:让每一个变量,都成为物理世界的一个可信赖的“触角”。
2. 变量定义的三层结构:从数据类型到符号命名,每一步都在为IO关联铺路
在TwinCAT3里,变量定义远不止是写一行MyVar : INT;这么简单。它是一个自顶向下的三层结构,每一层都直接决定了后续IO关联的可行性与健壮性。我见过太多项目,因为第一层就选错了,导致后期改起来牵一发而动全身。
2.1 第一层:基础数据类型选择——不是“能用就行”,而是“必须精准匹配”
TwinCAT3提供了丰富的标准数据类型,但新手常犯的错误是“贪多求全”。比如,看到一个压力传感器输出4-20mA信号,就想当然地用REAL来接收。这看似合理,但埋下了巨大隐患。原因在于:REAL是32位浮点数,而绝大多数模拟量输入模块(如EL31xx系列)的原始数据是16位有符号整数(INT),范围通常是-32768到+32767。如果你直接用REAL去映射硬件地址,TwinCAT会尝试进行类型转换,但这个过程丢失了精度,且无法反映模块的真实采样分辨率。
正确的做法是:始终以硬件模块的原始数据格式为第一参考。查阅倍福官方手册(如EL3102的Datasheet),明确其数据格式是INT,那么你的变量就应该定义为:
Pressure_Raw : INT; // 直接映射硬件寄存器,保持原始精度然后,再通过一个独立的转换函数,将INT转换为工程单位的REAL:
Pressure_PSI : REAL; Pressure_PSI := (REAL)Pressure_Raw * 0.001 + 0.0; // 示例:假设1LSB = 0.001 PSI,零点偏移0这样做的好处是:Pressure_Raw永远忠实于硬件,便于诊断(比如你能直接看到原始码值是否在正常范围内),而Pressure_PSI则用于逻辑运算,两者职责分明。我在一个水厂项目中就靠Pressure_Raw的异常跳变,快速定位出是某个EL3102模块的供电电压不稳,而不是传感器本身故障。
提示:对于数字量(DI/DO),务必区分
BOOL和BYTE。BOOL对应单个位(bit),适合单个按钮或指示灯;BYTE对应8个连续位,适合一组8个LED的状态打包读取。混用会导致地址错位,一个BOOL变量可能意外覆盖了相邻变量的高位。
2.2 第二层:变量声明位置——全局、局部与实例化,决定IO绑定的灵活性
变量声明的位置,直接决定了它能否被正确地绑定到硬件IO上。
- 全局变量(在POU的VAR_GLOBAL块中):这是最常用也最安全的选择。全局变量拥有固定的、可预测的内存地址,TwinCAT的IO映射引擎能稳定地将其与硬件地址关联。所有POU都可以访问它,非常适合IO信号的“中枢神经”。
- 局部变量(在POU的VAR块中):它只在当前POU内有效,生命周期随POU执行结束而释放。局部变量不能直接绑定到硬件IO地址。试图这样做,编译器会报错
Error 4029: Variable cannot be mapped to an I/O address。很多新手误以为只要写上AT %IX0.0就能绑定,却忽略了作用域限制。 - 实例化变量(在FB或FC的VAR_IN_OUT块中):这是实现“多重实例”的关键。例如,你有一个控制电机的FB
MotorCtrl,它内部需要一个启动信号Start。当你在主程序中创建两个MotorCtrl实例Motor1和Motor2时,Motor1.Start和Motor2.Start会自动映射到不同的硬件地址(如%IX0.0和%IX0.1),前提是你的FB定义时,Start参数被声明为VAR_IN_OUT,并且在调用时显式地指定了地址。
我曾在一个包装线项目中,用一个FB控制12台伺服电机。如果为每台电机都定义12套全局变量,代码会臃肿不堪。而采用实例化方式,只需定义一套FB逻辑,再通过12次调用,每次绑定不同的IO地址,代码复用率高达90%,维护成本直线下降。
2.3 第三层:符号命名与注释——不是为了好看,而是为了十年后还能看懂
一个没有注释的变量名,就像一张没有图例的地图。Var1,Data,Flag这类名字,在项目初期可能你觉得很顺手,但三个月后,你自己都得花半小时去翻代码猜它的用途。TwinCAT3支持长变量名(最长255字符),这给了我们充分的空间去写有意义的名字。
我的命名规范是“功能_物理位置_单位”三段式:
Conveyor_Belt_Speed_SP_RPM(输送带速度设定值,单位RPM)Valve_Main_Water_DO_Status(主供水阀,数字量输出,状态)Temp_Sensor_Tank_A_PT100_RAW(A号水箱温度传感器,PT100类型,原始码值)
这种命名法的好处是:当你在IO映射表里看到Conveyor_Belt_Speed_SP_RPM,你立刻就知道它应该绑定到哪个变频器的模拟量输出通道;当你在HMI画面里看到Valve_Main_Water_DO_Status,你知道它控制的是哪个物理阀门。更重要的是,它让变量定义本身就成了最权威的文档。我在接手一个前任工程师留下的老项目时,仅凭变量名就还原出了80%的工艺流程,省去了大量沟通成本。
注意:避免使用特殊字符(如空格、中文、
-)和保留字(如AND,OR,NOT)。TwinCAT3虽然支持部分Unicode,但为确保兼容性和未来迁移(比如导出到其他平台),强烈建议只使用英文字母、数字和下划线_。
3. 硬件IO关联的核心机制:从EtherCAT拓扑到地址映射的完整链路
在TwinCAT3里,硬件IO关联不是一个简单的“拖拽”操作,而是一条贯穿整个自动化系统的精密链路。理解这条链路,是避免“明明配了地址,却没反应”的唯一途径。它由四个关键环节组成:EtherCAT拓扑识别、设备描述文件加载、IO映射配置、以及最终的地址解析。
3.1 EtherCAT拓扑识别——让TwinCAT“看见”你的硬件
一切始于TwinCAT System Manager中的“Scan Devices”(扫描设备)操作。这一步不是魔法,而是TwinCAT通过网卡向整个EtherCAT网络发送广播帧,等待所有从站设备(倍福的EL系列端子、AX系列驱动器等)回应自己的身份信息。这个过程会生成一个完整的拓扑树,清晰地展示出:
- 主站(你的PC或CX控制器)的网卡型号和固件版本
- 每一个从站的设备类型(如
EL1008数字量输入端子)、序列号、固件版本 - 从站之间的物理连接顺序(即拓扑结构)
关键经验:扫描失败是IO关联的第一道拦路虎。最常见的原因是网卡驱动问题。TwinCAT3必须使用倍福官方认证的实时以太网驱动(通常名为Beckhoff Realtime Ethernet Driver),而不是Windows自带的通用驱动。我曾在一个项目中,客户自己安装了第三方网卡驱动,导致扫描时只能看到主站,看不到任何从站。卸载第三方驱动,重装倍福驱动后,问题瞬间解决。另一个常见原因是物理连接:检查网线是否为工业级屏蔽双绞线,两端水晶头是否压接良好,拓扑末端的终端电阻是否已启用(通常为ON)。
3.2 设备描述文件(ESI)加载——让TwinCAT“读懂”你的硬件
扫描到设备后,TwinCAT需要一份“说明书”来理解这个设备的功能。这份说明书就是ESI(EtherCAT Slave Information)文件。它是一个XML格式的文本文件,由设备制造商提供,详细描述了该设备的所有IO通道、数据类型、寄存器地址、诊断信息等。
TwinCAT3会自动从其内置的ESI库中查找匹配的文件。但如果遇到新型号设备或第三方设备,库中可能没有。这时,你需要手动导入ESI文件。路径通常在C:\TwinCAT\3.1\Io\EtherCAT\ESI。导入后,右键点击设备,在“Properties”(属性)中,确保“ESI File”字段指向了正确的文件。
踩坑实录:我在一个项目中使用了一款国产的EtherCAT IO模块,厂商提供了ESI文件。但导入后,TwinCAT在配置IO映射时,总是提示“Invalid channel index”。排查了整整一天,最后发现是ESI文件里一个通道的索引号(ChannelIndex)被错误地设置为了0,而标准规定应从1开始。修改ESI文件后,问题迎刃而解。这说明,ESI文件的质量直接决定了IO配置的成败,绝不能掉以轻心。
3.3 IO映射配置——在System Manager中完成“物理”到“逻辑”的翻译
这是最核心、也最容易出错的一步。在System Manager的“Configuration”(配置)视图中,展开你的EtherCAT设备,你会看到一个名为“I/O”或“Process Data”的节点。双击它,进入IO映射编辑器。
这里,你需要为每一个物理通道(如EL1008的第1个DI通道)分配一个逻辑变量。操作方式有两种:
- 手动映射:在“Variable Name”列,输入你已在PLC项目中定义好的全局变量名(如
Conveyor_Start_Button)。TwinCAT会自动检查该变量是否存在、类型是否匹配。 - 自动生成:右键点击通道,选择“Create Variable...”,TwinCAT会根据通道类型(DI/DO/AI/AO)和名称,自动生成一个符合命名规范的变量,并添加到PLC项目中。
为什么推荐手动映射?因为自动生成的变量名往往过于机械(如EL1008_1),缺乏业务含义,不利于后期维护。更重要的是,手动映射让你对整个IO结构有完全的掌控权。你可以将多个物理通道映射到同一个结构体变量的不同成员上,实现更高级的数据组织。
3.4 地址解析——TwinCAT如何把%IX0.0变成真实的电信号
当你在PLC代码中写下IF Conveyor_Start_Button THEN ... END_IF,TwinCAT编译器做的第一件事,就是查找Conveyor_Start_Button这个符号对应的硬件地址。这个地址不是你凭空想象的,而是由前面三步共同决定的:
- 拓扑顺序:第一个扫描到的EL1008,其基地址是
%IX0.0。 - ESI定义:ESI文件规定,EL1008的8个DI通道,依次占用
%IX0.0到%IX0.7。 - 映射配置:你在IO映射中,将
%IX0.0分配给了Conveyor_Start_Button。
因此,Conveyor_Start_Button这个符号,最终被解析为物理网卡上的第0个字节的第0位。当这个位为TRUE时,TwinCAT的实时内核会通过DMA(直接内存访问)技术,将这个状态同步到CPU的缓存中,供你的PLC程序读取。整个过程在微秒级完成,这就是TwinCAT实时性的基石。
提示:在System Manager中,你可以右键点击任意一个IO通道,选择“Show Address Assignment”,它会弹出一个窗口,清晰地展示该通道在整个EtherCAT网络中的绝对地址(如
0x00000000),以及它在PLC内存中的偏移量(如%IX0.0)。这是验证映射是否正确的最直接方法。
4. 结构体变量:让IO关联从“散装”走向“精装”的工程实践
当项目规模扩大,IO点数达到上百甚至上千时,用一个个独立的BOOL、INT变量去管理,会迅速陷入混乱。此时,结构体(STRUCT)变量就不再是“高级技巧”,而是维持项目可维护性的“生存必需品”。它能把相关的IO信号,像一个“数据包”一样,打包在一起,实现逻辑分组和批量操作。
4.1 定义一个典型的电机控制结构体
让我们以一个三相异步电机的控制为例。它通常需要以下IO信号:
- 输入(Input):启动按钮(DI)、停止按钮(DI)、运行反馈(DI)、故障反馈(DI)、电流模拟量(AI)
- 输出(Output):接触器线圈(DO)、故障复位(DO)、频率设定(AO)
我们可以定义一个名为Motor_IO的结构体:
TYPE Motor_IO : STRUCT // 输入信号 Start_Button : BOOL; // %IX0.0 Stop_Button : BOOL; // %IX0.1 Run_FB : BOOL; // %IX0.2 Fault_FB : BOOL; // %IX0.3 Current_Raw : INT; // %IW0.0 (注意:模拟量通常占2个字节) // 输出信号 Contactor : BOOL; // %QX0.0 Fault_Reset : BOOL; // %QX0.1 Freq_Set_Raw : INT; // %QW0.0 END_STRUCT END_TYPE4.2 在PLC项目中声明结构体实例
在主程序(MAIN)的全局变量声明区,我们创建一个Motor_IO类型的实例:
VAR_GLOBAL Motor_A : Motor_IO; // 创建一个名为Motor_A的实例 END_VAR4.3 在System Manager中完成结构体的IO映射
这才是结构体的精髓所在。在System Manager的IO映射编辑器中,你不再需要为每个成员单独配置。你只需:
- 展开
Motor_A这个结构体变量。 - 将
Motor_A.Start_Button拖拽到EL1008的第1个DI通道上。 - 将
Motor_A.Stop_Button拖拽到第2个DI通道上。 - 依此类推...
TwinCAT会自动计算每个成员在结构体内的偏移量,并将其与硬件地址一一对应。这意味着,Motor_A.Current_Raw会被映射到%IW0.0,而Motor_A.Freq_Set_Raw会被映射到%QW0.0。整个结构体就像一个“数据集装箱”,你只需要把它“挂载”到硬件上,里面的所有货物(成员变量)就自动各就各位。
工程价值:这种做法带来了三个质的飞跃:
- 可读性:在PLC代码中,
IF Motor_A.Run_FB THEN ... END_IF比IF Run_FB_Motor_A THEN ... END_IF更能体现上下文。 - 可复用性:要控制第二台电机?只需再声明一个
Motor_B : Motor_IO;,然后在System Manager中,将Motor_B的成员映射到另一组硬件地址上。逻辑代码完全不用改。 - 可测试性:在单元测试中,你可以轻松地为
Motor_A这个结构体赋值,模拟各种工况,而无需改动任何硬件配置。
4.4 高级技巧:嵌套结构体与数组——构建模块化IO架构
结构体可以嵌套,也可以作为数组元素,这为构建大型系统提供了无限可能。
- 嵌套结构体:你可以定义一个
Drive_IO结构体,专门处理伺服驱动器的复杂信号(如状态字、控制字、位置反馈、速度反馈),然后将它作为一个成员,放入Motor_IO中。这样,Motor_A.Drive.StatusWord就清晰地表达了“电机A的驱动器状态字”。 - 结构体数组:对于12台相同的电机,你可以声明
Motors : ARRAY[1..12] OF Motor_IO;。然后,在System Manager中,你可以用一个循环,将Motors[1].Start_Button映射到%IX0.0,Motors[2].Start_Button映射到%IX1.0,以此类推。这极大地简化了重复性配置工作。
我在一个汽车焊装车间的项目中,就采用了ARRAY[1..48] OF Welding_Gun_IO的方案。48把焊枪的IO信号,通过一个统一的结构体数组进行管理。当需要增加一台焊枪时,只需在数组中增加一个元素,并在System Manager中为其分配新的硬件地址,整个系统的逻辑框架岿然不动。
5. 常见故障排查链路:从“没反应”到“精准定位”的完整思路
即使你严格按照上述步骤操作,IO关联问题依然会不期而至。这时候,一套系统化的排查思路,比任何捷径都管用。我总结了一套“四步定位法”,它不是按部就班地试错,而是沿着数据流的方向,层层剥茧。
5.1 第一步:确认物理层——用万用表和指示灯说话
在怀疑软件之前,先用最原始的工具验证物理世界。
- 检查电源:用万用表测量IO模块的供电电压(通常是24V DC),确认其在额定范围内(如24V ±10%)。电压过低会导致输入信号无法被可靠识别。
- 检查信号源:将一个已知良好的24V开关(如一个按钮)直接接到目标DI通道上,观察模块上的对应LED指示灯是否亮起。如果灯不亮,问题一定在外部线路或开关本身,与TwinCAT无关。
- 检查输出负载:用万用表的通断档,测量DO通道的输出端子与公共端(COM)之间,在程序发出
TRUE指令时,是否有通路。如果无通路,检查模块的保险丝是否熔断,或负载是否短路。
经验:很多“没反应”的问题,根源都是一个松动的接线端子。我养成了一个习惯:在首次上电前,用一把小螺丝刀,逐个拧紧所有IO模块的接线端子。这一步耗时不到五分钟,却能避免80%的现场调试时间。
5.2 第二步:验证TwinCAT系统层——用System Manager的“透视眼”
如果物理层没问题,就进入TwinCAT的“系统层”验证。
- 检查设备状态:在System Manager的“Online”(在线)模式下,查看EtherCAT设备列表。所有设备的状态应为
Operational(运行中)。如果某个设备是Pre-op(预操作)或Safe-op(安全操作),说明其配置或ESI文件有问题。 - 强制IO值:在System Manager中,右键点击一个DI通道,选择“Force Value...”,手动将其设为
TRUE。然后,立即切换到PLC的在线监控视图,查看你定义的变量(如Conveyor_Start_Button)的值是否同步变为TRUE。如果变了,说明IO映射和通信链路是通的;如果没变,问题出在映射配置或变量定义上。 - 检查地址冲突:在System Manager的“Address Assignment”(地址分配)视图中,检查所有IO通道的地址是否连续、无重叠。地址冲突会导致数据错乱,表现为某些变量值随机跳变。
5.3 第三步:剖析PLC逻辑层——用在线监控和断点调试
如果系统层验证通过,问题就锁定在PLC程序内部。
- 在线监控:在TwinCAT PLC Control中,打开你的主程序(MAIN),将光标悬停在目标变量(如
Conveyor_Start_Button)上,右键选择“Online Monitor”。这会打开一个实时监控窗口,显示该变量的当前值、历史趋势和更新时间戳。如果值一直为FALSE,而你已确认物理按钮按下,那问题就在IO映射;如果值能正确变化,但后续逻辑不执行,问题就在你的ST代码里。 - 设置断点:在
IF Conveyor_Start_Button THEN这一行左侧的灰色区域点击,设置一个断点。然后,按下物理按钮。如果程序执行停在了断点处,说明逻辑是触发的;如果没停,说明要么条件不满足(比如Conveyor_Start_Button是FALSE),要么程序根本没有执行到这一行(比如被更高优先级的任务抢占,或被IF语句的前置条件过滤掉了)。
5.4 第四步:回溯配置层——用“反向工程”校验映射关系
这是最烧脑但也最有效的一步。当你百思不得其解时,就回到源头,用“反向工程”的方式,重新梳理整个链路。
- 在PLC代码中,找到那个“不工作”的变量名(如
Valve_Open_DO)。 - 在System Manager中,搜索这个变量名,找到它被映射到的IO通道。
- 查看该IO通道所属的设备,记下其在拓扑中的位置(如“EtherCAT Master -> EL2008 #3”)。
- 打开该设备的ESI文件(用记事本),查找其
ProcessData(过程数据)部分,确认该通道的DataType(数据类型)是否与PLC变量定义一致。 - 最后,回到System Manager的“Address Assignment”视图,确认该通道的绝对地址,与你在PLC中预期的地址是否一致。
我曾在一个项目中,发现一个BOOL变量始终无法驱动DO。按照上述步骤,最终发现:该DO通道在ESI文件中被定义为UINT(无符号整数),而TwinCAT在映射时,将BOOL变量的TRUE值(1)写入了UINT的最低位,但DO模块的驱动逻辑要求整个字节为非零值才动作。解决方案是:将PLC变量改为UINT,并在代码中赋值为16#0001。这个案例深刻地提醒我:硬件的“语言”和PLC的“语言”,有时需要一个精准的“翻译官”,而这个翻译官,就是你对ESI文件的理解。
6. 实战演练:从零开始,完成一个完整的“输送带启停”IO关联
理论终需落地。现在,让我们用一个最经典的“输送带启停”控制案例,走一遍从变量定义到硬件IO关联的全流程。这个案例涵盖了数字量输入、数字量输出、以及一个简单的互锁逻辑,足以检验你对前述所有知识的掌握程度。
6.1 步骤一:规划与准备
- 硬件清单:
- 主站:一台安装了TwinCAT3的PC(网卡为Intel I210)。
- 从站:一个倍福EL1008(8通道DI)端子,一个倍福EL2008(8通道DO)端子。
- 外部设备:一个带常开触点的启动按钮(SB1),一个带常闭触点的停止按钮(SB2),一个24V DC接触器线圈(KM1)。
- 电气连接:
- SB1的一端接24V+,另一端接EL1008的
Ch1(通道1)。 - SB2的一端接24V+,另一端接EL1008的
Ch2(通道2)。 - EL2008的
Ch1(通道1)接KM1的线圈一端,KM1线圈另一端接24V-。 - EL1008和EL2008的
COM端子均接24V-。
- SB1的一端接24V+,另一端接EL1008的
6.2 步骤二:在PLC项目中定义变量
在TwinCAT PLC Control中,新建一个项目,然后在MAIN程序的全局变量区,定义如下变量:
VAR_GLOBAL // 输送带控制信号 Conveyor_Start_Button : BOOL; // 启动按钮,对应EL1008 Ch1 Conveyor_Stop_Button : BOOL; // 停止按钮,对应EL1008 Ch2 Conveyor_Run_FB : BOOL; // 运行反馈(此处用虚拟反馈,实际项目中应接接触器辅助触点) Conveyor_Output : BOOL; // 控制接触器,对应EL2008 Ch1 // 内部逻辑变量 Conveyor_Running : BOOL; // 输送带运行状态 END_VAR6.3 步骤三:编写核心控制逻辑
在MAIN程序的主体中,编写一个经典的启保停(Latch)逻辑:
// 启保停逻辑 Conveyor_Running := (Conveyor_Running AND NOT Conveyor_Stop_Button) OR (Conveyor_Start_Button AND NOT Conveyor_Stop_Button); // 输出驱动 Conveyor_Output := Conveyor_Running; // 运行反馈(模拟) Conveyor_Run_FB := Conveyor_Running;6.4 步骤四:在System Manager中完成IO映射
- 启动TwinCAT System Manager,进入“Configuration”视图。
- 点击“Scan Devices”,确认EL1008和EL2008被正确识别。
- 展开EL1008,找到
Ch1,双击“Variable Name”列,输入Conveyor_Start_Button。 - 找到
Ch2,输入Conveyor_Stop_Button。 - 展开EL2008,找到
Ch1,输入Conveyor_Output。 - 关键检查:右键点击
Conveyor_Start_Button,选择“Show Address Assignment”,确认其地址为%IX0.0;同理,确认Conveyor_Stop_Button为%IX0.1,Conveyor_Output为%QX0.0。
6.5 步骤五:编译、下载与测试
- 在PLC Control中,点击“Build Solution”编译整个项目。
- 确保System Manager处于“Config Mode”,点击“Activate Configuration”激活配置。
- 切换到“Online”模式,点击“Download”将PLC程序下载到TwinCAT运行时。
- 点击“Run”按钮,启动PLC任务。
- 测试:
- 按下SB1,观察EL2008的
Ch1指示灯是否亮起,KM1是否吸合。 - 按下SB2,KM1应立即释放。
- 在PLC Control的在线监控窗口中,观察
Conveyor_Running、Conveyor_Output等变量的值,是否与物理动作完全同步。
- 按下SB1,观察EL2008的
实测心得:在这个看似简单的案例中,我故意将SB2接成了常闭触点,这在PLC逻辑中意味着:Conveyor_Stop_Button在按钮未按下时为TRUE,按下时为FALSE。这正是启保停逻辑中NOT Conveyor_Stop_Button的由来。很多新手会忽略触点类型,直接按常开逻辑写,导致“按下停止按钮,输送带反而启动”的诡异现象。所以,在定义变量之前,务必先画一张清晰的电气原理图,标注清楚每个按钮、传感器的触点类型和常态。这张图,是你所有软件工作的唯一依据。
注意:在真实项目中,停止按钮必须使用常闭触点,并接入硬件安全回路。本文仅为教学演示,不构成安全设计指导。