i have a small script which is checking connection to PLC... i put 1 on PLC tag, and PLC is wating for change and put to 1 and so on... Script is runing on 1 sec, becouse i run transaction group to put in base every 3 seconds (very fast pieces on line). In average this script takes beetwen 200ms to 700ms. But sometimes it happens that this script runs over 20sec. And if i dont get in 10sec in PLC i need to put alarm.
i run script every 1000ms with Fixed Delay and Shared Tread...
Other question is also i have a bit to execute writing to base (Transaction Group) and after succesful writing i put a bit executed back to PLC. But i need everytime to execute this in 2 second max. Is anyway to dedicate this group to do that in 2sec... line here is very fast and if ignition is not fast enough i get error. Or maybe if there is any possibility with buffer...??? Thanks for answer...
I recommend you switch to using a script instead of a transaction group in relatively fast applications, for a few reasons:
You can use a small integer trigger for recording with an echo handshake instead of booleans written from two directions.
You can omit the check connection operation--the PLC can simply check for trigger echo equality within the time limit.
Perhaps something like this (untested):
# This all goes in a project library script, perhaps named
# "customTransactions".
nqPathForA = 'some/Insert/NamedQuery'
triggerNQParamForA = 'nqParam0'
memoryTagsForA = [
["[default]Some/Path/to/Memory/Tag1", "nqParam1"],
["[default]Another/Path/to/Memory/Tag2", "nqParam2"]
]
opcServerForA = "Ignition OPC UA Server"
opcItemsForA = [
['[someDevice]item/path/A', 'nqParam2'],
['[someDevice]item/path/B', 'nqParam3'],
['[someDevice]item/path/C', 'nqParam4'],
['[someDevice]item/path/D', 'nqParam5']
]
echoTagForA = '[default]SomeFolder/Echo'
# Call this from a Gateway Tag Change event (in the project)
# that monitors just the trigger tag. With this one-liner:
#
# customTransactions.transactionA(newValue)
#
def transactionA(newValue):
if newValue.quality.good:
currentEcho = system.tag.readBlocking([echoTagForA])[0].value
if newValue.value != currentEcho:
# This is a truly new trigger, even if with initialChange.
# Start building the parameters dictionary for the named
# query that will perform the database insert.
nqParams = {triggerNQParamForA: newValue.value}
# Add memory tags to the dictionary
qvlist = system.tag.readBlocking([pair[0] for pair in memoryTagsForA])
values = [qv.value for qv in qvlist]
paramNames = [pair[1] for pair in memoryTagsForA]
nqParams.update([p, v] for (p, v) in zip(paramNames, values)]
# Add freshly-retrieved data from the PLC
qvlist = system.opc.readValues(opcServerForA, [pair[0] for pair in opcItemsForA])
values = [qv.value for qv in qvlist]
paramNames = [pair[1] for pair in opcItemsForA]
nqParams.update([p, v] for (p, v) in zip(paramNames, values)]
# Run the named query
rc = system.db.runNamedQuery("projectName", nqPathForA, nqParams)
# Check for actual insert/update effect before echo
if rc:
system.tag.writeBlocking([echoTagForA], [newValue.value])
# Any failure above will result in no echo sent, for the PLC to alarm.
# More sophisticated error handling is possible, of course, perhaps
# logging the values that failed.
The trigger would be some integer tag that the PLC increments to signal new data, rolling over. Perhaps skipping zero. This tag should be in a relatively fast-polling tag group, perhaps 250ms in you case.
The echo tag would receive the trigger value when the database insert succeeds. It should be in the same tag group as the trigger. The PLC should alarm if the trigger and echo do not match for several seconds.
You do not need Ignition tags for the values recorded from the OPC items, unless you also need live display. But continue using the OPC items in the script, to ensure fresh data after the trigger.