首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带边缘检测的CODESYS问题(反弹)

带边缘检测的CODESYS问题(反弹)
EN

Stack Overflow用户
提问于 2020-01-07 15:27:12
回答 3查看 736关注 0票数 0

我的CODESYS程序有问题。我有三个按钮,它们被定义为输入。每个按钮都存储一个数字。例如,数字1。我现在创建了一个程序,它识别按钮上的一个边缘,并将按钮的数值(2)存储在数组中。如果现在按下值(3)的另一个按钮,该值也会再次存储在变量中。这两个变量应该加在一起。2+3= 23在我的程序中,我遇到的问题是,如果按下值为2的按钮测试器,就会得到22。这是错误的。我认为这个问题是由于按钮的瘀伤造成的。检测到几个边缘。所以我想在技术上延迟解决这个软件。你知道我怎么编程序吗?

代码:

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-08 06:42:09

你需要实现边缘检测。下面是可以使用的代码模板:

代码语言:javascript
复制
//  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;
票数 0
EN

Stack Overflow用户

发布于 2020-01-07 21:03:18

我将以更面向对象的方式实现整个逻辑。

首先,我们定义了一个按钮。

声明部分:

代码语言:javascript
复制
FUNCTION_BLOCK FB_Button
VAR
    bSignal   AT%I* : BOOL;
    IButtonHandler : I_ButtonHandler;

    fbPushTimer : TON;
    fbTrig : R_TRIG;

    sValue : STRING;
END_VAR

执行部分:

代码语言:javascript
复制
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

该按钮有四个属性:

第一项财产:

声明部分:

代码语言:javascript
复制
 PROPERTY getValue : String

执行部分:

代码语言:javascript
复制
getValue := sValue;

第二项财产:

声明部分:

代码语言:javascript
复制
PROPERTY isPushed : BOOL

执行部分:

代码语言:javascript
复制
isPushed := bSignal;

第三项财产:

声明部分:

代码语言:javascript
复制
PROPERTY setPushHandler : I_ButtonHandler

执行部分:

代码语言:javascript
复制
IButtonHandler := setPushHandler;

第四项财产:

声明部分:

代码语言:javascript
复制
PROPERTY setValue : String

执行部分:

代码语言:javascript
复制
sValue := setValue;

然后我们定义接口。

代码语言:javascript
复制
INTERFACE I_ButtonHandler

并添加接口方法:

代码语言:javascript
复制
METHOD onPush 
VAR_INPUT
    sValue : STRING;
END_VAR

最后定义了处理程序。

声明部分:

代码语言:javascript
复制
FUNCTION_BLOCK FB_ButtonHandler IMPLEMENTS I_ButtonHandler
VAR_OUTPUT
    floorstorage : STRING;
END_VAR

处理程序有两个方法:

第一种方法:

声明部分:

代码语言:javascript
复制
METHOD onPush 
VAR_INPUT
    sValue : STRING;
END_VAR

执行部分:

代码语言:javascript
复制
floorstorage := concat(floorstorage,sValue);

第二种方法:

声明部分:

代码语言:javascript
复制
METHOD reset 

执行部分:

代码语言:javascript
复制
floorstorage := '';

现在我们需要插入按钮,并调用它们的主。

主要声明部分:

代码语言:javascript
复制
PROGRAM MAIN
VAR 
    aButtons : ARRAY[1..10] OF FB_Button;
    fbButtonHandler : FB_ButtonHandler;
    i : UINT;
    bInit : BOOL;
END_VAR

执行部分:

代码语言:javascript
复制
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。

通过这样做,您可以对变量进行更强的封装和数据保护,而不是将其声明为全局变量。

票数 0
EN

Stack Overflow用户

发布于 2020-01-08 06:22:00

我在这里看不到任何边缘检测

代码语言:javascript
复制
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周期,它将改变。这是你如何发现上升的边缘。

代码语言:javascript
复制
VAR
    xSignal, xSignalM: BOOL;
END_VAR

IF xSignal AND NOT xSignalM THEN
    // Raising edge is here
END_IF
xSignalM := xSignal;

这样的情况下只能运行一个PLC周期,一切都会好起来的。所以你的代码会像这样。

代码语言:javascript
复制
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

代码语言:javascript
复制
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_IF
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59631369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档