您的程序逻辑是在自动模式切换到手动模式时记录轴的位置,然后从手动模式切换回自动模式时计算位置差值,如果差值超过设定的阈值,则触发报警。这个逻辑是合理的,但是您提到的问题是在急停情况下会出现报警,因为急停会导致轴立即停止,这可能会导致位置差值计算出现异常。
为了解决这个问题,您可以考虑以下几个步骤:
1. **增加急停状态检测**:在您的程序中增加一个变量来检测急停状态,当急停按钮被按下时,这个变量会被设置为真。
2. **在急停状态下跳过位置差值计算**:在您的程序中,当检测到急停状态时,跳过位置差值的计算和报警触发。
3. **急停恢复后重置位置**:当急停状态被解除后,重置轴的位置记录,以便下一次从手动切换到自动时能够正确计算位置差值。
以下是修改后的程序示例:
```pascal
VAR
急停状态: BOOL; (* 急停状态标志 *)
X自动前位置old: REAL;
Y自动前位置old: REAL;
Z自动前位置old: REAL;
L自动前位置old: REAL;
X自动前位置new: REAL;
Y自动前位置new: REAL;
Z自动前位置new: REAL;
L自动前位置new: REAL;
X自动前位置差值: REAL;
Y自动前位置差值: REAL;
Z自动前位置差值: REAL;
L自动前位置差值: REAL;
X自动前位置点位差值: REAL;
Y自动前位置点位差值: REAL;
Z自动前位置点位差值: REAL;
X自动前位置差值绝对值: REAL;
Y自动前位置差值绝对值: REAL;
Z自动前位置差值绝对值: REAL;
L自动前位置差值绝对值: REAL;
X自动前位置点位差值绝对值: REAL;
Y自动前位置点位差值绝对值: REAL;
Z自动前位置点位差值绝对值: REAL;
END_VAR
自动模式下降沿(CLK := M3, Q => );
IF 自动模式下降沿.Q THEN
IF NOT 急停状态 THEN
X自动前位置old := X_Axis.fActPosition;
Y自动前位置old := Y_Axis.fActPosition;
Z自动前位置old := Z_Axis.fActPosition;
L自动前位置old := Lift_Axis.fActPosition;
END_IF;
END_IF;
自动模式上升沿(CLK := M4, Q => );
IF 自动模式上升沿.Q THEN
IF NOT 急停状态 THEN
X自动前位置new := X_Axis.fActPosition;
Y自动前位置new := Y_Axis.fActPosition;
Z自动前位置new := Z_Axis.fActPosition;
L自动前位置new := Lift_Axis.fActPosition;
X自动前位置差值 := X自动前位置new - X自动前位置old;
X自动前位置点位差值 := X自动前位置new - POSTION_X[X_Axis_AutoAbNum];
X自动前位置差值绝对值 := ABS(X自动前位置差值);
X自动前位置点位差值绝对值 := ABS(X自动前位置点位差值);
Y自动前位置差值 := Y自动前位置new - Y自动前位置old;
Y自动前位置点位差值 := Y自动前位置new - POSTION_Y[Y_Axis_AutoAbNum];
Y自动前位置差值绝对值 := ABS(Y自动前位置差值);
Y自动前位置点位差值绝对值 := ABS(Y自动前位置点位差值);
Z自动前位置差值 := Z自动前位置new - Z自动前位置old;
Z自动前位置点位差值 := Z自动前位置new - POSTION_Z[Z_Axis_AutoAbNum];
Z自动前位置差值绝对值 := ABS(Z自动前位置差值);
Z自动前位置点位差值绝对值 := ABS(Z自动前位置点位差值);
L自动前位置差值 := L自动前位置new - L自动前位置old;
L自动前位置差值绝对值 := ABS(L自动前位置差值);
IF M4 = TRUE AND X自动前位置差值绝对值 > E0.5 AND X自动前位置点位差值绝对值 > E0.5 THEN
Alarm[86] := TRUE;
END_IF;
IF M4 = TRUE AND Y自动前位置差值绝对值 > E0.5 AND Y自动前位置点位差值绝对值 > E0.5 THEN
Alarm[87] := TRUE;
END_IF;
IF M4 = TRUE AND Z自动前位置差值绝对值 > E0.5 AND Z自动前位置点位差值绝对值 > E0.5 THEN
Alarm[88] := TRUE;
END_IF;
IF M4 = TRUE AND L自动前位置差值绝对值 > E0.5 THEN
Alarm[89] := TRUE;
END_IF;
END_IF;
END_IF;
(* 急停按钮被按下时设置急停状态 *)
急停按钮按下(CLK := E-Stop, Q => );
IF 急停按钮按下.Q THEN
急停状态 := TRUE;
END_IF;
(* 急停按钮释放后重置急停状态和轴位置 *)
急停按钮释放(CLK := E-Stop, Q => );
IF 急停按钮释放.Q THEN
急停状态 := FALSE;
X自动前位置old := X_Axis.fActPosition;
Y自动前位置old := Y_Axis.fActPosition;
Z自动前位置old := Z_Axis.fActPosition;
L自动前位置old := Lift_Axis.fActPosition;
END_IF;
```
请注意,您需要根据您的实际硬件和软件环境调整上述代码。希望这些修改能够帮助您解决问题。