与Beckhoff同时脉冲多个LED

时间:2018-02-02 23:58:09

标签: automation plc hardware-interface structured-text

对于不同的方法,这应该是一个很好的问题。我很新,所以请原谅我的简单问题。

说我有6个LED。

LED1 AT %Q* : BOOL;
LED2 AT %Q* : BOOL;
LED3 AT %Q* : BOOL;
LED4 AT %Q* : BOOL;
LED5 AT %Q* : BOOL;
LED6 AT %Q* : BOOL;

我的目标是能够切换3个LED(我想要的)。因此,如果您按下特定按钮并将其切换为ON,它将使用相应的LED执行此操作:

LED[i] := button[i]; 

这很容易。现在说我有3个目前正在开启。

我希望能够同时按下一个独特的“脉冲”按钮和脉冲所有3个当前点亮的LED,持续3个脉冲周期。每1秒长。 恩。 ON - >关闭 - > ON - >关闭 - > ON - >关闭

结构化文本中最好的方法是能够知道当前哪些,如果是,使用定时器将当前的ON LED脉冲3次

谢谢!

2 个答案:

答案 0 :(得分:0)

You need to utilize timers in TwinCAT, TON and/or TOF. You also need to detect when the buttons have been pressed, to reset the timers. Once the button has been pressed for a LED, you restart both timers and also start the on-timer.

A quick and dirty probably not 100% correct 2-min solution (not in any way elegant, and which can be significantly simplified) goes something along this: In here I only use one of the buttons. Put all of this inside a for-loop to get what you want.

Function-block header:

bLED : ARRAY [1..6] OF BOOL ;
bLEDButton : ARRAY [1..6] OF BOOL;
tTimersOn : ARRAY [1..6] OF TON := [(PT := T#1S)];
tTimersOff : ARRAY [1..6] OF TON := [(PT := T#1S)];
fbLEDButtonTimerReset : ARRAY [1..6] OF R_TRIG;
fbLEDOnReset : ARRAY [1..6] OF R_TRIG;
fbLEDOffReset : ARRAY [1..6] OF R_TRIG;

Function block body

fbLEDButtonTimerReset[1](CLK := bLEDButton[1]); 
IF fbLEDButtonTimerReset[1].Q THEN
    tTimersOn[1](IN := FALSE);
    tTimersOn[1].IN := TRUE;
    tTimersOff[1](IN := FALSE);
END_IF

IF bLEDButton[1] THEN
    tTimersOn[1]();
    tTimersOff[1]();
    fbLEDOffReset[1](CLK := tTimersOff[1].Q);
    IF fbLEDOffReset[1].Q THEN
        tTimersOn[1](IN := FALSE);
        tTimersOn[1].IN := TRUE;
    END_IF
    fbLEDOnReset[1](CLK := tTimersOn[1].Q);
    IF fbLEDOnReset[1].Q THEN
        tTimersOff[1](IN := FALSE);
        tTimersOff[1].IN := TRUE;
    END_IF

    bLED[1] := NOT tTimersOn[1].Q;
END_IF

答案 1 :(得分:0)

让我提供我的5c。我知道可能会迟到,但我想很多人会发现我的代码很有用。

PROGRAM PLC_PRG
VAR
    xLed1 : ARRAY [1..6] OF BOOL; (* Array of LEDs *)
    xLed1M : ARRAY [1..6] OF BOOL; (* Array of LEDs to remember what to blink*)
    xLedButtons: ARRAY [1..6] OF BOOL; (* Array of buttons to toggle LED state *)
    xLedButtonsM: ARRAY [1..6] OF BOOL; (* Array of button press memmories to use pulse on rised edge of button press *)
    i:INT;
    xButtonBlink: BOOL; (* Button to press to start blinking *)
    xButtonBlinkM: BOOL; (* Memory of the button state to detect raising edge *)
    xBlinkLock: BOOL; (* Lock programm during blinking *)
    xBlinkLockM: BOOL; (* Memory of the lock to detect raising and falling edge *)
    fbTP1:TP; (* timer to enable lock for 6 seconds *)
    fbBLINK1: BLINK;
END_VAR
    (* Start lock timer of raising edge of blink button *)
    fbTP1(IN := xButtonBlink AND NOT xButtonBlinkM, PT := T#6s);
    xButtonBlinkM := xButtonBlink;

    xBlinkLock := fbTP1.Q;

    (* If locked start blinking *)
    IF xBlinkLock THEN
        (* If raised edge, of first cycle of blinking save LED array *)
        IF NOT xBlinkLockM THEN
            xLed1M := xLed1;
        END_IF
        fbBLINK1(ENABLE := TRUE, TIMEHIGH  :=  T#1s,  TIMELOW  :=  T#1s);
        FOR i :=1 TO 6 DO
            IF xLed1M[i] THEN
                xLed1[i] := fbBLINK1.OUT;
            END_IF
        END_FOR
    ELSE
        (* If falling edge of lock, restore LED array and reset blink FB *)
        IF xBlinkLockM THEN
            xLed1 := xLed1M;
            fbBLINK1(ENABLE := FALSE);
        END_IF

        (* Track button clicks and toogle state of led *)
        FOR i := 1 TO 6 DO
            IF xLedButtons[i] AND NOT xLedButtonsM[i] THEN
                xLed1[i] := NOT xLed1[i];
            END_IF;
            xLedButtonsM[i] := xLedButtons[i];
        END_FOR
    END_IF
    xBlinkLockM := xBlinkLock;
END_PROGRAMM