Timer ON and timer OFF

Hi,

Is there a way to recreate timer ON and timer OFF like the ones in the PLC via scripting?

Let’s say we have a program:

timer1(tag1, 3000ms) ← Timer ON turns on, when tag1 is true for 3000ms
IF timer1.Q THEN: ← timer 1 is true
#code
END;

See if Reset Tag Value after a Number of Seconds - #6 by hamlinjr helps. Pay attention to the warnings and cautions.

Ok. So, now I want to create a function, that will work like a Timer ON from PLC, but I encounter a problem:

def TimerON(tagPath, time):
	
	if system.tag.read(tagPath).value == 0:
		date_ms = system.date.toMillis(system.date.now())
		return 0
	else:
		time_diff = system.date.toMillis(system.date.now()) - date_ms
		if time_diff > time:
			return 1
		
TimerON("[default]Testowe/test1",5000)

The scripting console shows an error, when tag value is 1:
UnboundLocalError: local variable ‘date_ms’ referenced before assignment

You’ve assigned date_ms in the if block (for no apparent reason, not using it) but are trying to use it in the else block.

date_ms in if block is to remember the timestamp, when the variable was ‘0’ last time.

Doesn’t work like that. Your script has no “memory”.

So is it possible to create this kind of function via scripting?

It’s possible, you just need to find a place to store the start time that is scoped outside of your function.

For instance, perhaps create a UDT with the needed tags. Note that creating a “Timer” in this manner will be pretty inaccurate as there will be built in latencies with tag scan times, and read and right times. Can it be done? Yes. Should it? I’m not sure.

What exactly are you trying to accomplish, other than to replicate a construct from a PLC? There may be a better approach then this.

I want to trigger a IF condition in my script by a boolean value, that becomes TRUE, when tag is TRUE for 5 seconds.

Use a tag change event of some kind on your boolean to record the current timestamp into another tag (memory tag) whenever the boolean becomes true. In the script where you need this, read both the boolean tag and the timestamp tag. Then you have enough information to evaluate your condition.

Hello!
sorry for the delay :sweat_smile:, I had a similar need, check if my solution could fit yours:
udt_TON.xml (2.1 KB)

use: create an instance of TON, say myTON
set myTON.PT = 3.5 → it’s a float, PresetTime in seconds
set myTON.EN = True to enable the timer
Q is set to False at this moment and will be set to True after 3500ms

caveat: PT can’t be 0

see Adding a Delay to a Script - Ignition User Manual 7.9 - Ignition Documentation for details on the use of Timer

:slightly_smiling_face:

That’s not what you want to do, that’s how you’re trying to do it.

Try to be as closed to the problem you want to solve, without including anything you think might be part of the solution. You might not even need a script to achieve your ‘true’ goal.

Unless of course your ultimate goal is to trigger an if in a script, in which case… why ?

UDT attached.

  • Monitor has two Diagnostic level alarms for TON and TOF operation.
  • Expression tags bound to each alarm isActive flag.
  • Integer tags for TON and TOF time values.
  • limited to even seconds

timer_udt.json (1.2 KB)