Micrologix 1400 data sync problem

I’m having problems logging data correctly from a micrologix 1400 into a database via an historical transaction group.

I set up a simple test to try and find out what’s going on. On the PLC, I increment an integer, copy the integer into a string, and set a trigger bit. I’ve attached a picture of the code below.

In Ignition I have a historical transaction group set to execute on the PLC trigger bit (only execute once, reset trigger after execution), with the PLC integer tag mapped to an integer field in the database table, and the PLC string tag mapped to a string field in the table. The transaction group has an update rate of 100 ms.

This is what I would expect to be stored in the table:


and so on. The PLC sees the trigger bit is off, it increments the integer, copies the new value into the string, and sets the trigger. Ignition sees the trigger bit is on, copies the integer and string into the database, and resets the trigger. And the cycle repeats.

This is what I actually get:


Ignition is storing sometimes current values, sometimes old values from the previous cycle. Also, it’s not consistent between the integer and string tags. Sometimes it’ll store the current integer value and an old string value, sometimes the other way around, sometimes an old value from both, sometimes the current value from both.

A further problem is that sooner or later the process will get stuck. The PLC will set the trigger bit and Ignition won’t recognize the trigger. My guess is that Ignition sees the trigger as being set on the previous cycle and set on the current cycle, so there’s no off-on transtition to trigger the group. However, Ignition has cleared the trigger bit in between the two cycles.

To achieve correct behaviour, I have to introduce a delay of 150 ms at the PLC between updating the fields and setting the trigger bit, and I have to allow an idle period between cycles so that Ignition can realize the trigger has gone off.

I had hoped to transfer ten packets per second (at the 100 ms rate), but with the enforced delays the process is down to about two packets per second just to ensure reliability. The device diagnostic page tells me the maximum request duration is 25ms and the average is 14ms, so it seems like Ignition can get data from the PLC in a timely manner.

What’s gone wrong? What should I do differently? It’s worrying to have to jump through all sorts of hoops just to make sure the data gets recorded correctly, and I’d like to speed up the rate I can transfer data into the database.


With subscription based polling, these types of setups can be difficult to get right. The first thing to do would be to try using “Read” mode instead of “Subscribed” mode on the group - this can be set under the “Options” tab. When set like this, the trigger value is subscribed, but when the trigger goes active, the other values are read explicitly. This makes sure you get the current values for that cycle, instead of whatever has happened to arrive from the subscription.

As for the trigger, this issue does come up fairly often, but there isn’t a concrete fix. In “one shot” mode, the trigger must see the reset value come in from the PLC. This is a problem if the PLC see the reset, and then immediate sets the value back high. We could change the group to reset the trigger after a successful write, but it is then very likely that on the next execution, it might erroneously see the 1 as a new trigger.

Instead, I think it is more reliable to work on a different trigger mechanism. There are a variety of things you could do, but one of the easiest would be to trigger “on change” of a counter, instead of an on/off, and use the handshake to tell the plc to increment the counter. Or, you could unselect “only execute once”, and add in the “only evaluate when items have changed” option above, and select the value tag. That way, it will log when the trigger is high, and when the value has changed (these options are still compatible with “read” mode, anything that plays into the trigger will be subscribed, but the other tags will be read).

If something more complex is needed, you could use a run-always expression item. I’m not sure it’s necessarily, but just to give you an idea of what’s possible, you could set up something like “if the trigger is active, or if I haven’t logged for x time, or if the current value isn’t in the db”.

Hope this helps,

OK, that makes sense. I’ll try changing to Read mode and use a counter trigger mechanism. I’ll post my conclusions tomorrow. Thanks for the help.

Yes, that worked well. I took the Micrologix PLC code back to the simple bare minimum, using a counter as trigger instead of toggling a bit. And the Read mode solved the data synchronization problem.

With Read mode it slowed right down to about 1.9 transactions per second, as opposed to the theoretical 10 transactions per second in Subscribe mode. Goes to show how much more efficient Subscribe mode is.

It’s funny that I don’t see these problems with CompactLogix. The same setup works perfectly in Subscribe mode, at 10 transactions per second.