# Are OPC writes atomic? Conclusion: No

**URL:** <https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [June 13, 2024, 2:51pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825 "2024-06-13T14:51:11Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![zacht](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@zacht](https://forum.inductiveautomation.com/u/zacht)\
**Post date:** [June 13, 2024, 2:51pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/1 "2024-06-13T14:51:11Z")

</div>

When using `system.opc.writeValues` to write to a PLC through the 'Allen-Bradley Logix Driver,' are multiple writes ~~synchronous~~ atomic within the PLC? The two values in this case are sequential elements (but not every element) of an array. An example is:

```python
# plc_array_tag has type DINT[5,2]
# This does not write to all elements, but they are sequential elements.
system.opc.writeValues(
    'OPC_SERVER_NAME'
    ['plc_array_tag[0,0]', 'plc_array_tag[0,1]'],
    [5,10]
)

```

I'm seeing behavior that makes me think the PLC (sometimes) evaluates the elements after one has been changed but not the other. Is this possible? Is it likely?

The script runs in the gateway scope from a gateway timer event.

Ignition Version: 8.1.17  
Allen Bradley CAT: 5069-L320ER  
Allen Bradley Firmware: 30.011

Edit 1: @Kevin.Herron pointed out I used the wrong function in my code snippet.  
Edit 2: Learned a new word that better describes my question. Question edited for future searchability.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [June 13, 2024, 3:06pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/2 "2024-06-13T15:06:17Z")

</div>

This is code does a read, so I'm not sure what you're trying to ask.

Both the `system.opc.readValues` and `system.opc.writeValues` calls are synchronous though. When the calls return you will have values or quality codes representing the result of the operation.

---

<div class="post-metadata">

**Author:** ![zacht](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@zacht](https://forum.inductiveautomation.com/u/zacht)\
**Post date:** [June 13, 2024, 3:07pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/3 "2024-06-13T15:07:28Z")

</div>

I corrected it. The question stands, I just typed it wrong with my brain in automatic mode this morning.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [June 13, 2024, 3:12pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/4 "2024-06-13T15:12:07Z")

</div>

I think what you may be trying to ask is if this write operation to 2 separate elements is _atomic_, and that's something that I can't answer, and will be entirely up to the PLC implementation of whatever PLC you're writing to.

In this case with it being a Logix PLC we do send a single "Multiple Service Packet" Service request, inside of which will be 2 Write Tag Service requests.

What the PLC does with these 2 requests, and whether it's possible for them to be evaluated in separate scans somehow, is not something I'm aware of being documented. @pturmel sometimes knows these kinds of implementation details.

---

<div class="post-metadata">

**Author:** ![zacht](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@zacht](https://forum.inductiveautomation.com/u/zacht)\
**Post date:** [June 13, 2024, 3:17pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/5 "2024-06-13T15:17:14Z")

</div>

_Atomic_ is what I'm curious about, but I didn't know the right word to describe it. I learned something new today.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [June 13, 2024, 3:18pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/6 "2024-06-13T15:18:26Z")

</div>

You'd probably be better off assuming it's not atomic.

Generally, if you want to load some set of values into a PLC for it to operate on as a whole, you need to write those values first, then in a separate operation write to a trigger tag that tells the PLC it can start operating on those values.

---

<div class="post-metadata">

**Author:** ![zacht](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@zacht](https://forum.inductiveautomation.com/u/zacht)\
**Post date:** [June 13, 2024, 3:22pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/7 "2024-06-13T15:22:37Z")

</div>

> [@Kevin.Herron](#):
>
> write those values first, then in a separate operation write to a trigger tag that tells the PLC it can start operating on those values.

That's what I'll do. Thanks for your help with this.

---

<div class="post-metadata">

**Author:** ![zacht](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@zacht](https://forum.inductiveautomation.com/u/zacht)\
**Post date:** [June 13, 2024, 3:48pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/8 "2024-06-13T15:48:08Z")

</div>

Just for fun, I did some testing. I used this script in the Ignition Script console:

```python
import time

for i in range(1000):
	print i
	_ = system.opc.writeValues(
		'Ignition OPC-UA Server',
		[
			'ns=1;s=[TestPLC]zTestDint[0]',
			'ns=1;s=[TestPLC]zTestDint[1]'
		],
		[i,i]
	)
	time.sleep(.1)

```

and this logic rung in the PLC:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/4/3447bff0c01a84277c8a782c5ce2dbc702a84bee.png)

Conclusion: @Kevin.Herron's assumption is correct; OPC writes are not atomic within this type of PLC.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 13, 2024, 4:30pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/9 "2024-06-13T16:30:08Z")

</div>

The CIP Specification requires that the requests within the Multiple Service Packet be executed serially, with no parallelism. But it says nothing about the PLC's own parallelism for target objects, which effectively makes the restriction useless. I have seen no evidence that **any** PLC brand follows that part of the CIP spec, because of the loophole, and the fact that it would crush messaging performance.

**Single** requests for an array tag or for the entire content of a UDT will be **cooperatively** atomic where the target is handled in the PLC only with `CPS` instructions.

---

<div class="post-metadata">

**Author:** ![zacht](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@zacht](https://forum.inductiveautomation.com/u/zacht)\
**Post date:** [June 13, 2024, 4:53pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/10 "2024-06-13T16:53:31Z")

</div>

> [@pturmel](#):
>
> **cooperatively** atomic

Can you clarify what this means? Google results were less than helpful, mostly pointing to research papers in the atomic physics realm.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 13, 2024, 5:05pm UTC](https://forum.inductiveautomation.com/t/are-opc-writes-atomic-conclusion-no/91825/11 "2024-06-13T17:05:04Z")

</div>

Dedicate a PLC structure type instance for data that travels one-way. For data that is going from Ignition to the PLC, write **every** element in the UDT (even if repeating) when writing anything (in a single `system.tag.writeBlocking()` or `system.opc.writeValues()` call) so that the driver can optimize into a single write request for the entire UDT. In the PLC, use a `CPS` instruction to copy from that tag to another instance. Use that copy for all other logic in the PLC--that copied structure will be reliably unfragmented.

Similarly, going from PLC to Ignition, use CPS to load a snapshot from one UDT into the UDT read by Ignition. Use `system.opc.readValues()` to get everything in that UDT atomically. Subscribe to a trigger tag that is always updated by the PLC **after** the snapshot, and fire the `readValues()` call in its tag change event.
