PLC 梯形图逻辑 - 使用两个电位器的序列有问题
PLC Ladder logic - problematic sequence using two potentiometer
我花了很多时间和大量的纸上草图,但我没有偶然发现任何东西来解决这个问题。
我们有两个装满水的水箱和两个水泵。如果 h>hmax(Tank 1)和 H,我们需要使用这些泵自动将水推到第二个水箱
有一件事我想不通。第一个序列假定如果 H>Hmax,则泵 1 或 2 将工作(它们不能同时工作)。当水被泵到第二个水箱时,第一个水箱中的水将下降,在第一个水箱中补充水后重复该顺序。我无法弄清楚如何在每个序列后仅使用电位器自动更换泵。我需要做的更多是包括其中一个泵的故障。我处理这个问题将近一个星期了。
希望这就是你的意思。我把它写成 "working" 伪代码。
在现实生活中,这段代码并不是最好的,因为从现在开始你有超过 2 个泵,它应该很复杂,但是这个非常详细。
还缺少一个紧急开关(如果有人必须手动停止泵,他可以按下按钮)。
更好的方法是使用一些 function_blocks 和方法...
声明:
VAR
//INPUT
levelTank1 AT %I* : INT; //potentiometer 1
levelTank2 AT %I* : INT; //potentiometer 2
pump1Malfunction AT %I* : BOOL; //TRUE=pump has no malfunction || FALSE=malfunction
pump2Malfunction AT %I* : BOOL;
//OUTPUT
pump1Operation AT %Q* : BOOL; //TRUE=pump should run
pump2Operation AT %Q* : BOOL;
lastPumpInOperation : BYTE := 1;
nState : UINT := 0;
END_VAR
你应该在某个地方定义最小和最大电平,我把它定义为一个常量值:
VAR CONSTANT
tank1Hmax : INT := 32000;
tank1Hmin : INT := 5000;
tank2Hmax : INT := 25000;
tank2Hmin : INT := 2000;
END_VAR
作为备注:模拟输入通常是 INT 值,所以最大。等级等于 32767
现在的程序:
CASE nState OF
0: //wait till tank 1 is filled and make sure tank2 is not overcharged
IF (levelTank1 >= tank1Hmax) AND NOT (levelTank2 >= tank2Hmax) THEN
nState := 1;
END_IF
1: //start one pump
//first check worst case - both pumps are broken
IF NOT pump1Malfunction AND NOT pump2Malfunction THEN
nState := 100; //emergency
//last time pump1 was used, and now pump 2 should start when it has no malfunction
ELSIF lastPumpInOperation = 1 AND pump2Malfunction THEN
pump2Operation := TRUE;
lastPumpInOperation := 2;
nState := 2;
//last time pump2 was used, and now pump 1 should start when it has no malfunction
ELSIF lastPumpInOperation = 2 AND pump1Malfunction THEN
pump1Operation := TRUE;
pump2Operation := FALSE;
lastPumpInOperation := 1;
nState := 2;
//now we have to define what happens when one pump is in malfunction
ELSIF NOT pump1Malfunction THEN
pump2Operation := TRUE;
pump1Operation := FALSE;
lastPumpInOperation := 2;
nState := 2;
ELSIF NOT pump2Malfunction THEN
pump1Operation := TRUE;
lastPumpInOperation := 1;
nState := 2;
END_IF
2: //pump operation till tank1 is "empty", tank2 is "full" or pump failure occurs
IF (levelTank1 <= tank1Hmin) OR (levelTank2 >= tank2Hmax) THEN
nState := 3; //stop pumps
ELSIF (pump1Operation AND NOT pump1Malfunction) THEN //pump has gone in malfunction during operation
nState := 1; //go back to step2 to start another pump
ELSIF (pump2Operation AND NOT pump2Malfunction) THEN
nState := 1;
END_IF
3: //stop pumps
pump1Operation := FALSE;
pump2Operation := FALSE;
nState := 0;
100: //emergency
//do what you can do - close the valve to tank1 or run as fast as you can
pump1Operation := FALSE;
pump2Operation := FALSE;
IF (pump1Malfunction OR pump2Malfunction) THEN
nState := 0;
END_IF
END_CASE
我花了很多时间和大量的纸上草图,但我没有偶然发现任何东西来解决这个问题。
我们有两个装满水的水箱和两个水泵。如果 h>hmax(Tank 1)和 H,我们需要使用这些泵自动将水推到第二个水箱
有一件事我想不通。第一个序列假定如果 H>Hmax,则泵 1 或 2 将工作(它们不能同时工作)。当水被泵到第二个水箱时,第一个水箱中的水将下降,在第一个水箱中补充水后重复该顺序。我无法弄清楚如何在每个序列后仅使用电位器自动更换泵。我需要做的更多是包括其中一个泵的故障。我处理这个问题将近一个星期了。
希望这就是你的意思。我把它写成 "working" 伪代码。 在现实生活中,这段代码并不是最好的,因为从现在开始你有超过 2 个泵,它应该很复杂,但是这个非常详细。 还缺少一个紧急开关(如果有人必须手动停止泵,他可以按下按钮)。 更好的方法是使用一些 function_blocks 和方法...
声明:
VAR
//INPUT
levelTank1 AT %I* : INT; //potentiometer 1
levelTank2 AT %I* : INT; //potentiometer 2
pump1Malfunction AT %I* : BOOL; //TRUE=pump has no malfunction || FALSE=malfunction
pump2Malfunction AT %I* : BOOL;
//OUTPUT
pump1Operation AT %Q* : BOOL; //TRUE=pump should run
pump2Operation AT %Q* : BOOL;
lastPumpInOperation : BYTE := 1;
nState : UINT := 0;
END_VAR
你应该在某个地方定义最小和最大电平,我把它定义为一个常量值:
VAR CONSTANT
tank1Hmax : INT := 32000;
tank1Hmin : INT := 5000;
tank2Hmax : INT := 25000;
tank2Hmin : INT := 2000;
END_VAR
作为备注:模拟输入通常是 INT 值,所以最大。等级等于 32767
现在的程序:
CASE nState OF
0: //wait till tank 1 is filled and make sure tank2 is not overcharged
IF (levelTank1 >= tank1Hmax) AND NOT (levelTank2 >= tank2Hmax) THEN
nState := 1;
END_IF
1: //start one pump
//first check worst case - both pumps are broken
IF NOT pump1Malfunction AND NOT pump2Malfunction THEN
nState := 100; //emergency
//last time pump1 was used, and now pump 2 should start when it has no malfunction
ELSIF lastPumpInOperation = 1 AND pump2Malfunction THEN
pump2Operation := TRUE;
lastPumpInOperation := 2;
nState := 2;
//last time pump2 was used, and now pump 1 should start when it has no malfunction
ELSIF lastPumpInOperation = 2 AND pump1Malfunction THEN
pump1Operation := TRUE;
pump2Operation := FALSE;
lastPumpInOperation := 1;
nState := 2;
//now we have to define what happens when one pump is in malfunction
ELSIF NOT pump1Malfunction THEN
pump2Operation := TRUE;
pump1Operation := FALSE;
lastPumpInOperation := 2;
nState := 2;
ELSIF NOT pump2Malfunction THEN
pump1Operation := TRUE;
lastPumpInOperation := 1;
nState := 2;
END_IF
2: //pump operation till tank1 is "empty", tank2 is "full" or pump failure occurs
IF (levelTank1 <= tank1Hmin) OR (levelTank2 >= tank2Hmax) THEN
nState := 3; //stop pumps
ELSIF (pump1Operation AND NOT pump1Malfunction) THEN //pump has gone in malfunction during operation
nState := 1; //go back to step2 to start another pump
ELSIF (pump2Operation AND NOT pump2Malfunction) THEN
nState := 1;
END_IF
3: //stop pumps
pump1Operation := FALSE;
pump2Operation := FALSE;
nState := 0;
100: //emergency
//do what you can do - close the valve to tank1 or run as fast as you can
pump1Operation := FALSE;
pump2Operation := FALSE;
IF (pump1Malfunction OR pump2Malfunction) THEN
nState := 0;
END_IF
END_CASE