Wrong I/O image on POWERLINK due to automatic task class setting

Good afternoon everyone,

I would like to share an interesting, and very annoying, problem that we have been dealing with over the last few months.

This is a rather long story, but I am sharing it in detail in the hope that it may help someone in the future.

Background

We build different machines and systems, all based on the same basic software framework. One type of these machines includes Denso robots, which are controlled via DeviceNet using an X20 DeviceNet master on a POWERLINK bus coupler.

In the past, these robots had repeatedly caused problems — or at least that was our assumption — because they would stop without giving us any useful feedback.

Troubleshooting, part 1

During troubleshooting together with the robot manufacturer, we found that one of two bits in the robot interface occasionally dropped to 0 for a very short time, although both bits should always remain TRUE.

Since we do not actively write these two bits anywhere in the application program, but simply keep them permanently set to TRUE, we initially assumed that our PLC application code was not the cause.

Later, we tried all kinds of methods to capture the error case, including traces, log entries, breakpoints, and other checks, hoping to find an incorrect address access or something similar. However, we had no success.

Long story short:
We assumed that something was wrong with the robot I/O card, while the robot manufacturer assumed that something was wrong in our PLC program.

Troubleshooting, part 2

After we had already delivered several machines (all similar but not exactly identical) the problem continued to occur very sporadically on almost all of them.

During commissioning of the latest machine, however, the same problem suddenly occurred much more regularly. On average, one of the bits dropped to 0 for one robot cycle every 3 to 6 hours.
We even tried replacing DeviceNet with PROFINET, but the same problem still occurred.

Later, we used a CAN analyzer to check when these “wrong” bits were being sent.
This time we were successful:
the incorrect I/O image was actually coming out of the DeviceNet coupler.

However, since we still could not capture the error case inside the PLC application, we eventually used Wireshark to record the POWERLINK traffic as well.

This was quite time-consuming, but with some persistence, the POWERLINK documentation, and some help from AI, we were able to isolate the exact telegram and the corresponding bytes.

And again, we found that the wrong bits were actually being sent on POWERLINK. They were always wrong for exactly one PLC cycle. In our case, this corresponded to three telegrams, because TC#1 runs with three times the POWERLINK cycle time.

Further tests revealed:
Not only one of the two bits, but bits and bytes over the whole I/O image was “wrong” from time to time. But only these two bits showed an effect consistently.

The solution(?)

For the robot communication, we use one channel with a width of OCTET[32] to send 32 bytes to the robot and receive 32 bytes from it. All commands, jobs, and status information are encoded within these bytes.

In the I/O mapping, we therefore only have to map two arrays with 32 bytes each. These arrays are declared globally and are part of a larger “IO” structure, which also contains other I/O data.

The two arrays containing the robot input and output bytes are written by a task in TC#4. However, other I/Os in the same “IO” structure are also used by tasks in other task classes.

Why is this important?

The issue seems to have been related to the task class setting of the mapped IO structure. This setting was set to “Automatic”.

image

The compiler also gave us warning 6779, but unfortunately we ignored it.

The warning in the help article says:

“The fastest of these task classes is used, which can produce inconsistent transfer behavior for complex variables (structures, arrays).”

We still do not fully understand why this can result in an incorrect I/O image being sent.

However, after we explicitly set the task class for this mapping to TC#4, the problem no longer occurred.

Conclusion

A few lessons learned from this issue:

  • Always keep investigating! There’s a reason for every strange behaviour
  • Read compiler and logger warnings carefully
  • Do not be afraid of Wireshark. :wink:

Questions

Have you ever experienced something similar?

Do you have any idea what exactly happens internally in this case?

By coincidence, I stumbled accross this post today, which sounds suspiciously similar.
But I still do not fully understand how the PLC can actively send a “wrong” I/O image.

2 Likes

When using the automatic task class setting on a variable IO Mapping the compiler detects the fastest task class and uses then that task class to update the variables value. This can then lead to a situation where the mapped variables are updated at different times, and as the compiler warning suggest this can lead to inconsistent transfer for complex variables.

Using your IO mapping as an example, in a case where the “Input” is detected for Task Class #1 and “ModuleOK” for Task Class #4 they could be updated at different times. Assuming that TC #1 is for example at 1ms and TC #4 at 10ms it could happen that the Input variable is updated in the middle of the TC #4 task class, as the update happens at the beginning of TC #1.

So you could have for example the following sequence.
TC#1 → Input updated
TC#1 → Input updated
TC#4 → Module OK Updated
TC#4 → Half of the code in TC#4 runs
TC#1 interrupts execution of TC4 → Input updated
TC#4 → Rest of the code in TC4 runs, has different Input values than at the beginning
TC#1 → Input updated
etc…

Some links to Automation Help where this is explained:
IO transfer
Cyclic program execution

1 Like

For inputs you could solve this behavior by using two variable and Add a second mapping.
image
For outputs this is not possible and most of the output issues are also caused how it is programmed.

If during the slow task class (tc#4) the output is changed multiple times and this output is mapped in tc#1, the output could already be changed multiple times.
This could also be solved by first changing a software output variable and copy this at the end of slow task to the variable connected to the output mapping.

Thank you for your comments.
Maybe I didn’t do a great job of explaining the issue:

The issue is not the “ModuleOK” datapoint but single bits in the […].Output structure (ARRAY[0..31]OF BYTE).

For example:
::IO.DeviceNet.ROB[1].Output[0].2 switches from TRUE to FALSE every x hours.
Sometimes its Output[0].2, sometimes Output[2].5 or any other bit.

The strange part is that there are bits changing, which are never changed or written to in the programm. Also not the whole variable is e.g. 0 but only single bits (sometimes also more then one, scattered around the whole 32bytes).

So the theory about interrupting task classes doesn’t hold up in my opinion.

It does not matter if one variable is connected to an output mapping, or if an octet of 32 bytes is connnected to an output mapping.
What it important, what is set and reset during the tc#4 cycle in this octet of bytes.

And thats exactly the point:
There are bits changing on the bus, which are not beeing set/reset during runtime (except on the first cycle)!

Output[0].2 is always TRUE from the perspective of the PLC.
It is never set to FALSE, never overwritten by a pointer or something like that.
Neither in TC#1, TC#4 or any other taskclass.
Also tracing it from any task always returns TRUE (beginning and end).

On the bus / PLK however, this single bit changes from time to time to FALSE for a few PLK cycles.



I am pretty sure I understand how schedulers, task classes, and I/O-Images work.
And, of course, I also understand that inconsistent I/O images can occur when one task interrupts another.

However, “inconsistent” should still only mean that parts of the I/O image are out of sync in time.
It should not mean that states occur that never existed.