博图Tia Portal学习教程目录
设备介绍
我们以普通电动开关阀为例,一般至少会有开启、关闭、开启到位反馈、关闭到位反馈4个信号,如下图。
也有一些会更加丰富一点,例如这款西门子的电动风阀执行器,除了正常的正反转和开/关到位信号,还有开/关到位的取反信号以及电位计位置反馈。
因为在不同的工况下,对同一个阀门,要求的控制逻辑不尽相同,多以我们从简单到复杂,来编写几个典型的范例。
案例1
简单粗暴型(适用于开关到位后能自行内部断电的执行器)
按一下HMI上的开启按钮,开启阀门;按一下关闭按钮,关闭阀门。加个开/关输出互锁和开/关信号互锁。
IF "Open_value1" THEN
"DQ_Open_value1_RLY" := TRUE;
"DQ_Close_value1_RLY" := FALSE;
"Close_value1" := FALSE;
END_IF;
IF "Close_value1" THEN
"DQ_Close_value1_RLY" := TRUE;
"DQ_Open_value1_RLY" := FALSE;
"Open_value1" := FALSE;
END_IF;
案例2
到位断电型
阀门运行到位,PLC接收到信号,即断开动力电源。
IF "Open_value1" THEN
"DQ_Open_value1_RLY" := TRUE;
END_IF;
IF "DI_Value1_opened" OR "Close_value1" THEN
"DQ_Open_value1_RLY" := FALSE;
"Open_value1" := FALSE;
END_IF;
IF "Close_value1" THEN
"DQ_Close_value1_RLY" := TRUE;
END_IF;
IF "DI_Value1_closed" OR "Open_value1" THEN
"DQ_Close_value1_RLY" := FALSE;
"Close_value1" := FALSE;
END_IF;
案例3
上面的方案在实际使用中,如果执行器质量不是特别好的话,有可能会遇到一个比较尴尬的问题——执行器已经发出运动到位的信号了,然而实际上阀门离走到位还差那么点。例如开启旋转阀,旋转到85°了,旋转到位的信号就已经发出来了,那PLC立刻断电的话,阀门就停在85℃这儿了。要知道,阀门关不严或者开不完全会导致一系列的问题,我遇到过一次比较极端的情况,因为阀门处风速特别高,如果阀门板不能开到完全跟风向平行,运行过程中就会慢慢被风“强行扳回去”,导致风阀被关闭。
应对方法呢,可以在PLC接受到限位信号和断开执行器动力电源之间加一个小延时。
IF "Open_value1" THEN
"DQ_Open_value1_RLY" := TRUE;
END_IF;
"Stop_opening_value1".TON(IN:="DI_Value1_opened",
PT:=T#10s);
IF "Stop_opening_value1".Q OR "Close_value1" THEN
"DQ_Open_value1_RLY" := FALSE;
"Open_value1" := FALSE;
END_IF;
IF "Close_value1" THEN
"DQ_Close_value1_RLY" := TRUE;
END_IF;
"Stop_closing_value1".TON(IN := "DI_Value1_opened",
PT := T#10s);
IF "Stop_closing_value1".Q OR "Open_value1" THEN
"DQ_Close_value1_RLY" := FALSE;
"Close_value1" := FALSE;
END_IF;
案例4
HMI上想要实时显示阀门状态,完全开启时显示绿色,完全关闭红色,中间状态灰色,信号错误红绿双色。
实现方案,用一个Byte变量代表阀门状态,0表示未知状态,1表示完全开启,2表示完全关闭,3代表信号错误。程序如下:
REGION Value1_HMI
IF NOT #Value_opened AND NOT #Value_closed THEN
#Value_state_HMI := 0;
END_IF;
IF #Value_opened AND NOT #Value_closed THEN
#Value_state_HMI := 1;
END_IF;
IF NOT #Value_opened AND #Value_closed THEN
#Value_state_HMI := 2;
END_IF;
IF #Value_opened AND #Value_closed THEN
#Value_state_HMI := 3;
END_IF;
END_REGION
HMI上先创建该种类阀门使用的图形列表。我是用Adobe Illustrator画的,建议长期画屏幕的同志还是要能熟用一款绘图软件,这样设计的界面会比较符合需求且美观。然后创建I/O域,赋值。
案例5
通过上面一顿猛如虎的操作,大家应该发现了,单独一个阀门就这么多行程序,那我一个设备十几个阀门的话,岂不是满屏幕哗啦啦的都是阀门控制程序,那还得了?所以最后我们需要把它做成一个函数块。
因为要用到好多TON定时器,所以创建一个FB块,在Static里面声明,这样每次调用该FB块都会在其DB块里面自动生成IEC_Timer数据。
程序如下:
REGION Open_value
IF #Open_value_HMI THEN
#Open_value_RLY := TRUE;
END_IF;
#Stop_opening_value.TON(IN := #Value_opened,
PT := T#10s);
IF #Stop_opening_value.Q OR #Close_value_HMI THEN
#Open_value_RLY := FALSE;
#Open_value_HMI := FALSE;
END_IF;
END_REGION
REGION Close_value
IF #Close_value_HMI THEN
#Close_value_RLY := TRUE;
END_IF;
#Stop_closing_value.TON(IN := #Value_closed,
PT := T#10s);
IF #Stop_closing_value.Q OR #Open_value_HMI THEN
#Close_value_RLY := FALSE;
#Close_value_HMI := FALSE;
END_IF;
END_REGION
REGION Value_HMI
IF NOT #Value_opened AND NOT #Value_closed THEN
#Value_state_HMI := 0;
END_IF;
IF #Value_opened AND NOT #Value_closed THEN
#Value_state_HMI := 1;
END_IF;
IF NOT #Value_opened AND #Value_closed THEN
#Value_state_HMI := 2;
END_IF;
IF #Value_opened AND #Value_closed THEN
#Value_state_HMI := 3;
END_IF;
END_REGION
主函数里调用是这么个情况,然后添加变量就行了。
"Value_Control_SCL_DB"(Value_opened:="DI_Value1_opened",
Value_closed:="DI_Value1_closed",
Value_state_HMI=>"Value1_state_HMI",
Open_value_RLY=>"DQ_Open_value1_RLY",
Close_value_RLY=>"DQ_Close_value1_RLY",
Open_value_HMI:="Open_value1",
Close_value_HMI:="Close_value1");
"Value_Control_SCL_DB"(Value_opened := "DI_Value2_opened",
Value_closed := "DI_Value2_closed",
Value_state_HMI => "Value2_state_HMI",
Open_value_RLY => "DQ_Open_value2_RLY",
Close_value_RLY => "DQ_Close_value2_RLY",
Open_value_HMI := "Open_value2",
Close_value_HMI := "Close_value2");