#程序员,使用梯形图踩坑记#
最近在做一个AGV铲车的工控和上位机程序,简单的说就是上位机下发指令,AGV按指定任务去搬运东西。
做的过程中,需要使用LD,就是梯形图实现在两个输出点,分别输出两个方波信号,两个信号互斥,不同时输出。
经过分析,感觉挺简单的一件事,用编程(ST)的思路:
IF 输出信号1 = true then
如果是 高电平
启用定时器1
定时器1到时间,电平设置为低电平。
如果是 低电平
启用定时器2
定时器2时间到 ,电平设置为高电平
end_if
具体ST代码如下,实际上是没有问题的。(CSDN没有ST代码格式,所有显示不太正常)
IF s1 = TRUE THEN //s1方波信号输出
t1(in:=flag=FALSE,pt:=T#1S,Q=>);//高电平定时
t2(in:=flag,pt:=T#1S,q=>);//低电平定时
IF flag = FALSE THEN // 输出高电平
s1out:=TRUE;//输出1s高电平
IF t1.Q THEN
flag := TRUE;//临时变量设置为tuue
END_IF
ELSE //输出底电平
s1out:=FALSE;//输出1s底电平
IF t2.Q THEN
flag:=FALSE;
END_IF
END_IF
END_IF
IF s2 = TRUE THEN //s2方波信号输出
t1(in:=flag=FALSE,pt:=T#1S,Q=>);//高电平定时
t2(in:=flag,pt:=T#1S,q=>);//低电平定时
IF flag = FALSE THEN // 输出高电平
s2out:=TRUE;//输出1s高电平
IF t1.Q THEN
flag := TRUE;//临时变量设置为tuue
END_IF
ELSE //输出底电平
s2out:=FALSE;//输出1s底电平
IF t2.Q THEN
flag:=FALSE;
END_IF
END_IF
END_IF
但是由于项目需要用LD,就是梯形图去实现。所以按照这个思路,用LD给功能重新画一次。感觉应该问题不大。
所以第一版LD图:
运行以后,发现一s1out一直是高电平。t1定时器可以触发,到时间后,flag瞬间变成高电平,然后马上就复位成低电平,这样t1,就一直反复被激活,s1out,就一直高电平。看到这个结果一脸懵逼。经过简单的排除,以及调整(实际上整了一天),终于发现问题原因了。
原因就是:梯形图和编程的思路不太一样。
比如,实现信号1触发,信号二也触发。在程序逻辑就是:如果 信号1 = true then 信号2=true。如果信号1=false,那么 IF 条件不成立,也就是信号2=true,这条就不执行,但是如果信号2已经为true,就保持true不变。
但是用梯形图,逻辑就完全不一样了,如下图。s2out状态永远和s2同步。这点和上面红色字体不一样。
再回到刚才方波梯形图,问题出在t1定时器。当flag为false的情况下,定时器他被激活,1s以后,t1到时间,给flag设置为true。
flag变成true以后,t1定时器失效,但并不是ST代码里面,不执行这个语句。这个时候会给flag设置为false。也就是说瞬间又恢复成false。问题的根源在于flag设置为true以后,没法保持。
发现问题以后,就好解决,本质上是flag变成true以后,没法保持。所以下面t2定时器就没法触发。只要想办法保持flag=true就行。经过短暂思考(大约1小时),发现TOF可以解决这个问题。TON是定时开,使能以后,输出 点Q是由低到高。TOF是定时关。使能以后,输出点Q是先高后低。根据这个特性,重新写梯形图如下两个:
其实就是,当t1给flag设置为true的时候。t2定时器瞬间启用,然后给flag设置为true,相当于使用tof给flag保持1s时间,到1s以后,再给flag设置为flase。这个时候,又回到t1启用。
到这里,看似问题解决了。接着给另外一个方波梯形图如法炮制一下就行了。想想还挺简单的。于是,见下图。问题来了,为啥一个信号没有问题,两个就不行了。顿时十万个为什么就来了。
省略掉几秒钟的思考,发现了问题:上下两个图行,用的同一组定时器,t1和t2。上面s1给t1启用了,但是下面s2=false,又给t1禁用了。本质上还是,s2虽然没有导通,并不代表后面的不执行。这是梯形图跟ST的区别。
知道问题的原因,那么解决问题就不难了,于是改进一下,见下图。改完以后,还是不行。经过思考,原来还有flag变量,上下也会影响。
于是,最终版的图:见下图。方波功能终于实现了。不过这每次都这样弄,似乎是有点傻,本着代码复用的原则,必须给这个功能封装一下,封装成一个函数块FB,简称装逼一下。
封装就很简单了,新建一个pou,类型是FB。给方波的梯形图画好。输入是使能,以及两个时间,输出是一个信号。封装见下图:
封装好,调用见下图。是不是感觉简单很多。
对于一个资深程序员来说,程序运行逻辑已经深入骨髓。LD梯形图的逻辑,确实需要时间去适应。经过这一天的折腾,对梯形图编程也理解差不多了。AGV小车也调试差不多了,在电工这条路上越走越远了。
最后发的时候,发现csdn居然没有自动化相关标签。希望管理员能增加上。先随便选一个机器人吧,因为这AGV,也能算一个机器人。