'Create alternating signal in PLC programming

I'm struggling with an assignment I was given about PLC programming. The set up is the following:

When the alarm signal (= input) is set, a lamp (=output) begins to flash at a frequency of 1Hz and the klaxon (=output) is activated. From the moment a person pushes the acknowledge button (=input), the klaxon stops functioning. Depending on the state of the alarm while acknowledging, the lamp changes from flashing to fully on until the alarm is reset. An overview of the behavior of both outputs, based on the inputs is given in the following figureoutput behavior

Is there anyone that is familiar with this kind of task? I would really appreciate the help. Thanks in advance!

This is what I have so far:

// if alarm goes of, the klaxon and an alternating light start
IF gvl.IN_alarm := TRUE THEN
    gvl.OUT_klaxon := TRUE;
    
    //alternating signal 
    FB_ton(IN:= NOT qton1 , PT:= T#1S, Q=> qton1 );
    FB_pulse(IN:= qton1 , PT:= T#1S , Q=> gvl.OUT_flashingLight);
END_IF

// if button is pressed, the klaxon goes off and the light becomes fully on

IF gvl.IN_acknowledge := TRUE THEN 
    gvl.OUT_klaxon := FALSE;
    gvl.OUT_flashingLight := TRUE;
END_IF

// if the alarm is reset, the light goes out 
IF gvl.IN_alarm := FALSE THEN
    gvl.OUT_flashingLight := FALSE;
END_IF


Solution 1:[1]

I'll assume you're using Codesys v3.5.

If it's another IEC 61131-3 based PLC system, I can include the code of a "Blink" block if needed. Also note that a rising edge detection block (R_TRIG) may have a different name or need a different Library.

Some tips:

  1. The ideal is that the function blocks (eg. Timers) be executed outside of conditionals (IF), that way they will always be processed.

  2. The symbol ":=" is for assigning value to a variable. Should not be used as a condition of an IF. For that use "=", or, if it's a BOOL, you can just use the symbol itself, as in the example below.

//Declaration
VAR
    fbBlink : Blink;
    fbAlarmTrig : R_TRIG;
    fbAckTrig : R_TRIG;
END_VAR

//------------------
//The program

//This will generate a "blink signal" in OUT while ENABLE is set to TRUE.
//Blink is a block of 'Util' library in Codesys
//if you get error, please check if is added to the project
fbBlink(ENABLE := TRUE, TIMELOW := T#0.5S, TIMEHIGH  := T#0.5S);

//Get the rising edge of Alarm and Ack (In this case, is a good practice). 
//R_Trig is a block of 'Standart' library of Codesys
//if you get error, please check if is added to the project
fbAlarmTrig(CLK := gvl.IN_alarm);
fbAckTrig(CLK := gvl.IN_acknowledge);

//When the alarm occurs 
IF fbAlarmTrig.Q THEN
    gvl.OUT_klaxon := TRUE;
END_IF

//When pressing the ACK button 
IF fbAckTrig.Q THEN
    gvl.OUT_klaxon := FALSE;
END_IF

//Set the output
IF gvl.OUT_klaxon THEN
    //blink 
    gvl.OUT_flashingLight := fbBlink.OUT;
ELSE
    //Turns on or off, passing state directly to output
    gvl.OUT_flashingLight := gvl.IN_alarm;  
END_IF

Edit - Blink Function Block

FUNCTION_BLOCK BLINK
VAR_INPUT
    ENABLE      : BOOL;
    TIMELOW     : TIME;
    TIMEHIGH    : TIME;
END_VAR
VAR_OUTPUT
    OUT : BOOL;
END_VAR
VAR
    fbTimerOn   : TON;
    fbTimerOff  : TOF;
    bMem        : BOOL := TRUE;
END_VAR

//------------------

fbTimerOff(IN := bMem, PT:= TIMEHIGH);
fbTimerOn(IN := NOT fbTimerOff.Q, PT:= TIMELOW);
bMem := FALSE;

IF fbTimerOn.Q THEN
     bMem := TRUE;
END_IF

IF ENABLE THEN
    OUT := fbTimerOff.Q;
ELSE
    OUT := FALSE;
    bMem := TRUE;
END_IF

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1