我的CODESYS程序有问题。我有三个按钮,它们被定义为输入。每个按钮都存储一个数字。例如,数字1。我现在创建了一个程序,它识别按钮上的一个边缘,并将按钮的数值(2)存储在数组中。如果现在按下值(3)的另一个按钮,该值也会再次存储在变量中。这两个变量应该加在一起。2+3= 23在我的程序中,我遇到的问题是,如果按下值为2的按钮测试器,就会得到22。这是错误的。我认为这个问题是由于按钮的瘀伤造成的。检测到几个边缘。所以我想在技术上延迟解决这个软件。你知道我怎么编程序吗?
代码:
IF (PLC_PRG.calls[5].gpio = TRUE) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[5].message.floorstore[5]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[5].message.floorstore[5]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF
IF (PLC_PRG.calls[6].gpio = TRUE) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[6].message.floorstore[6]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[6].message.floorstore[6]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF
IF (PLC_PRG.calls[7].gpio = TRUE) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[7].message.floorstore[7]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[7].message.floorstore[7]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF
GlobalVar.floorstorage := concat(floorstorage2[0],floorstorage2[1]); // Total of value 1 and value 2 (1 + 2 = 12)发布于 2020-01-08 06:42:09
你需要实现边缘检测。下面是可以使用的代码模板:
// Generate Oneshot Signal
VAR_INPUT
SIGNAL : BOOL; // Input
END_VAR
VAR
LATCH_SIGNAL : BOOL; // Latch
END_VAR
VAR_TEMP
OS_P_SIGNAL : BOOL; // Oneshot - Rising edge detection
OS_N_SIGNAL : BOOL; // Oneshot - Falling edge detection
END_VAR
//Code - Rising edge detection
OS_P_SIGNAL := SIGNAL AND NOT LATCH_SIGNAL;
LATCH_SIGNAL := SIGNAL;
//Code - Falling edge detection
OS_N_SIGNAL := NOT SIGNAL AND NOT LATCH_SIGNAL;
LATCH_SIGNAL := NOT SIGNAL;发布于 2020-01-07 21:03:18
我将以更面向对象的方式实现整个逻辑。
首先,我们定义了一个按钮。
声明部分:
FUNCTION_BLOCK FB_Button
VAR
bSignal AT%I* : BOOL;
IButtonHandler : I_ButtonHandler;
fbPushTimer : TON;
fbTrig : R_TRIG;
sValue : STRING;
END_VAR执行部分:
IF IButtonHandler = 0
THEN
RETURN;
END_IF
fbPushTimer(IN:= bSignal, PT:=T#50MS);
fbTrig(CLK:=fbPushTimer.Q);
IF fbTrig.Q
THEN
IButtonHandler.onPush(sValue);
END_IF该按钮有四个属性:
第一项财产:
声明部分:
PROPERTY getValue : String执行部分:
getValue := sValue;第二项财产:
声明部分:
PROPERTY isPushed : BOOL执行部分:
isPushed := bSignal;第三项财产:
声明部分:
PROPERTY setPushHandler : I_ButtonHandler执行部分:
IButtonHandler := setPushHandler;第四项财产:
声明部分:
PROPERTY setValue : String执行部分:
sValue := setValue;然后我们定义接口。
INTERFACE I_ButtonHandler并添加接口方法:
METHOD onPush
VAR_INPUT
sValue : STRING;
END_VAR最后定义了处理程序。
声明部分:
FUNCTION_BLOCK FB_ButtonHandler IMPLEMENTS I_ButtonHandler
VAR_OUTPUT
floorstorage : STRING;
END_VAR处理程序有两个方法:
第一种方法:
声明部分:
METHOD onPush
VAR_INPUT
sValue : STRING;
END_VAR执行部分:
floorstorage := concat(floorstorage,sValue);第二种方法:
声明部分:
METHOD reset 执行部分:
floorstorage := '';现在我们需要插入按钮,并调用它们的主。
主要声明部分:
PROGRAM MAIN
VAR
aButtons : ARRAY[1..10] OF FB_Button;
fbButtonHandler : FB_ButtonHandler;
i : UINT;
bInit : BOOL;
END_VAR执行部分:
IF NOT bInit
THEN
FOR i := 1 TO 10 DO
aButtons[i].setPushHandler := fbButtonHandler;
aButtons[i].setValue := UINT_TO_STRING(i);
END_FOR
bInit := TRUE;
END_IF
FOR i := 1 TO 10 DO
aButtons[i]();
END_FOR您可以根据按钮选择自己的按钮值。
为了简单起见,我将循环索引指定为按钮的值。
每次按下按钮,onPush方法在50 is后只会被调用一次。
当您想要访问another存储的值时,只需调用fbButtonHandler.floorstorage将其分配给另一个var。
通过这样做,您可以对变量进行更强的封装和数据保护,而不是将其声明为全局变量。
发布于 2020-01-08 06:22:00
我在这里看不到任何边缘检测
IF (PLC_PRG.calls[5].gpio = TRUE) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[5].message.floorstore[5]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[5].message.floorstore[5]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF你检查一下是否按下了按钮。这意味着当您按住此按钮时,此条件为真。这意味着当您按住按钮时,counter会在每一个可编程控制器周期中改变它的状态。这意味着,如果你释放按钮,PLC做偶数的周期,什么都不会改变,如果奇数f周期,它将改变。这是你如何发现上升的边缘。
VAR
xSignal, xSignalM: BOOL;
END_VAR
IF xSignal AND NOT xSignalM THEN
// Raising edge is here
END_IF
xSignalM := xSignal;这样的情况下只能运行一个PLC周期,一切都会好起来的。所以你的代码会像这样。
VAR
M1, M1, M3: BOOL;
END_VAR
IF (PLC_PRG.calls[5].gpio AND NOT M1) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[5].message.floorstore[5]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[5].message.floorstore[5]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF
M1 = PLC_PRG.calls[5].gpio;
IF (PLC_PRG.calls[6].gpio AND NOT M2) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[6].message.floorstore[6]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[6].message.floorstore[6]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF
M2 = PLC_PRG.calls[6].gpio;
IF (PLC_PRG.calls[7].gpio AND NOT M3) THEN // edge detection on gpio
IF (counter = 0) THEN // counter for the first value
floorstorage2[0] := PLC_PRG.calls[7].message.floorstore[7]; // save button value in the array to calculate the total
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[7].message.floorstore[7]; // save button value in the array to calculate the total
counter := 0;
END_IF
END_IF
M3 = PLC_PRG.calls[7].gpio;或者您可以使用R_TRIG
VAR
RT1:R_TRIG;
END_VAR
R1(CLK := PLC_PRG.calls[5].gpio);
IF (R1.Q) THEN
IF (counter = 0) THEN
floorstorage2[0] := PLC_PRG.calls[5].message.floorstore[5];
counter := 1;
ELSE
floorstorage2[1] := PLC_PRG.calls[5].message.floorstore[5];
counter := 0;
END_IF
END_IFhttps://stackoverflow.com/questions/59631369
复制相似问题