Trouble with Timer Script combined with Alarm Timer

Hello all,

I'm hoping someone can help me with this. I have a Gateway Timer script that runs at a fixed rate (every 500 ms). The idea is that it is a heartbeat monitor so every 500 ms, it should read a new value from the PLC (Heartbeat_from_PLC), compare it to a previously saved value (Prev_Heartbeat) and if the value is unchanged, it indicates some sort of communication error and it will set a tag (Heartbeat_Alarm_Flag) that will alarm after 10 s and the alarm then triggers another tag (PLC_Comm_Err) to turn on. After that, it saves Heartbeat_from_PLC to Prev_Heartbeat and then sets a different heartbeat value, which is sent to the PLC and used only by the PLC (Heartbeat_to_PLC).

The code works fine except for one thing - after the 10 s alarm, it takes around 25 s for the PLC_Comm_Err tag to turn on and I cannot figure out why! The Gateway Timer script is below:

def handleTimerEvent():
	#===-HEARTBEAT ALARM====#

	# Read current values
	Heartbeat = system.tag.readBlocking(['[MTCE]Heartbeat_from_PLC'])[0].value
	Prev_Heartbeat = system.tag.readBlocking(['[MTCE]Prev_Heartbeat'])[0].value
	
	# Compare current Heartbeat value to previous value
	if Heartbeat <> Prev_Heartbeat:
		# Reset the alarm flag
		system.tag.writeBlocking(['[MTCE]Heartbeat_Alarm_Flag'], 0)
	else:
		# Set the alarm flag (alarm flag has 15 s alarm delay)
		system.tag.writeBlocking(['[MTCE]Heartbeat_Alarm_Flag'], 1)
		
		# Set the PLC_Comm_Err if heartbeat alarm flag has been on for 10 s
		if system.tag.readBlocking(['[MTCE]Heartbeat_Alarm_Flag/Alarms/Timer.IsActive'])[0].value == 1:
			system.tag.writeBlocking(['[MTCE]PLC_Comm_Err'], 1)
		else:
			system.tag.writeBlocking(['[MTCE]PLC_Comm_Err'], 0)

	# Save the heartbeat value to the Prev_Heartbeat variable
	system.tag.writeBlocking(['[MTCE]Prev_Heartbeat'], Heartbeat)

	# Check if heartbeat value sent to PLC should be reset
	if Heartbeat > 99:
		# Reset heartbeat counter
		system.tag.writeBlocking(['[MTCE]Heartbeat_to_PLC'], 0)
	else:
		# Set new value
		system.tag.writeBlocking(['[MTCE]Heartbeat_to_PLC'], Heartbeat + 1)

Some things to note:

  1. The PLC increases the value of Heartbeat_from_PLC as long as it gets a new value of Heartbeat_to_PLC from Ignition.

  2. Heartbeat_Alarm_Flag alarm settings are shown below:

If anyone could shed light on why turning on PLC_Comm_Err takes so much more than 10 s after Heartbeat_Alarm_Flag turns on, I'd be very grateful!

Thanks!

I would blame the system.tag.writeBlocking() operations, if to OPC tags. That, combined with comms overload to the PLC, will stall those operations. Meaning your timer is probably not actually running as often as you think it should be. Consider adding a logging statement to the start of the event script.

Thank you! I will try that the next time I am able and see if that's what's going on!