2

I have VARs declared

trigger_pos_sensor_left                 : BOOL;

trigger_ticks                           :   INT := 0;
trigger_sensor_rtrig                    :   R_TRIG;
trigger_sensor_ftrig                    :   F_TRIG;
delay_timer                             :   TOF;

Program is :

IF (re = FALSE )THEN
    trigger_sensor_rtrig(CLK := trigger_pos_sensor_left);
    trigger_sensor_ftrig(CLK := trigger_pos_sensor_left);
    delay_timer(IN := trigger_sensor_ftrig.Q, PT := T#10s);
    trigger_ticks := 5;

    re := TRUE;
END_IF

IF (trigger_sensor_rtrig.Q = TRUE) AND (delay_timer.Q = OFF) THEN
    trigger_ticks := trigger_ticks - 1;
END_IF

If I understand it correctly r_trig, f_trig and tof are set and "activated" in the first IF and then everytime trigger_pos_sensor_left is activated it should activate set trigger_sensor_rtrig.Q to true and then decrement trigger_ticks by one. It actually does nothing. Why?

user3742046
  • 171
  • 12

2 Answers2

3

The blocks must be processed at every cycle of the program, remove them from the IF. The way it is, the blocks are not executed by the program.

trigger_sensor_rtrig(CLK := trigger_pos_sensor_left);
trigger_sensor_ftrig(CLK := trigger_pos_sensor_left);
delay_timer(IN := trigger_sensor_ftrig.Q, PT := T#10s);

IF (re = FALSE )THEN
    trigger_ticks := 5;
    re := TRUE;
END_IF

IF (trigger_sensor_rtrig.Q = TRUE) AND (delay_timer.Q = FALSE) THEN
    trigger_ticks := trigger_ticks - 1;
END_IF
dwpessoa
  • 440
  • 4
  • 15
3

If by "activated" you mean that they will execute the preset logic without you touching, then NO, you must execute the Function Block on every cycle for it to update the state.

Let's check the example in the documentation for R_TRIG:

(* Example declaration *)
RTRIGInst : R_TRIG ;

(* Example in ST *)
RTRIGInst(CLK := VarBOOL1);
VarBOOL2 := RTRIGInst.Q;

Notice that the RTRIGInst(CLK := VarBOOL1); line is NOT enclosed in an if statement, it is executed on every cycle.

Perhaps it would help you understand if we created our own R_TRIG block to show how it probably works under the hood:

FUNCTION_BLOCK R_TRIG
  VAR_IN
    CLK: BOOL;
  VAR_END
  VAR_OUT
    Q: BOOL;
  VAT_END
  VAR
    _first_run: BOOL := TRUE;
    _last_clk: BOOL;
  VAR_END

// implementation:
  IF _first_run THEN
    _first_run := FALSE;
    _last_clk := CLK; // this is so Q isn't set if the initial CLK value was TRUE
  END_IF
  
  Q := FALSE;
  
  IF _last_clk <> CLK THEN
    _last_clk := CLK;
    Q := CLK;
  END_IF

FUNCTION_BLOCK_END

As you can see in my reference implementation, the edge detection happens inside the Function Block, which is only executed when the Function Block is run. Hope this clarifies things.

Guiorgy
  • 1,405
  • 9
  • 26