1

I want to use a global method to debounce digital inputs by passing the IO and the desired debounce time to the method and using the returnvalue to set the Bool-Variable. The Method itself is working but I need to instantiate the function block for every input. I would like to further optimize by eliminating the need of instantiation.

Is there a possibility to configure the functionblock/method in order that the runtime allocates the memory and instantiates the method whenever it is being called?

METHOD NO : BOOL
VAR_INPUT
    IN  : BOOL;
    T       : TIME;
END_VAR
VAR_INST
    _timer  : TON;
END_VAR

_timer (IN := IN, PT := T);
IF _timer.Q
THEN
    NO := TRUE;
ELSIF _timer.ET < T
THEN
    RETURN;
ELSE
    NO := FALSE;
END_IF

Call:

debouncedInput := debounce.NO(digitalInput, T#500MS);

where "Debounce" is the local instance of the funtion block.

Thanks in advance for constructive answers.

momo0815
  • 11
  • 2

1 Answers1

0

If I understand your question correctly than this is not possible.

Getting rid of initialization is only possible if you do not need to save the state of your method variables between cycles. In that case you could use a FUNCTION. Since you are using a TON inside your function block, the _timer instance needs to be available for the next cycle. This "state saving" is only possible when you use it in a FUNCTION BLOCK. That is also why you declared the _timer as a VAR_INST. Declaring it as a VAR would not work, since the timer would be re-initialized with every call to the NO method.

Unrelated to the question. Your NO method is doing the same as a call to the normal TON would be. Not sure why you implemented it this way, but I think you could also implement it with just a timer as follows:

PROGRAM Test
VAR
    timer : TON;
    digitalInput : BOOL;
    debouncedInput : BOOL;
END_VAR

timer(IN:=digitalInput, PT:=T#500MS, Q=>debouncedInput);

Or keeping the method

METHOD NO : BOOL
VAR_INPUT
    IN  : BOOL;
    T       : TIME;
END_VAR
VAR_INST
    _timer  : TON;
END_VAR

_timer (IN := IN, PT := T);
NO := _timer.Q
Roald
  • 2,459
  • 16
  • 43
  • Thanks for the feedback. I was thinking that it is not possible. As I said: I was searching for a more convenient way for debouncing inputs. If you know of any other elegant solution let me know! I think I will continue using the method with an instance for every input. – momo0815 Mar 18 '21 at 11:45
  • I suggested a better way by using only the timer. I do not think there is a way without creating some sort of function block for each input, since you need a separate timer for each input. – Roald Mar 18 '21 at 12:57