How to get ControlLogix PLC Mode from Ignition's OPC-UA?

Allen Bradley’s PlantPAX redundancy monitor faceplate uses the “@Mode” to pull the PLC mode (program or run) from the RSLinks OPC server. Is there a way to pull the same information with the Ignition OPC-UA server?

This is critical because if the PLC is in program mode, none of the code is executing and I need to know I can not trust any of the data to be up to date, even if the tags are not stale. I guess I could setup some hand shaking, but it would be nice to be able to do it the same way they do it in PlantPAX. I am using their AOIs in the PLC and want to use Ignition as the HMI instead of FactoryTalk View.

Thanks

You’re going to want to check out the GSV instruction, Class ControllerDevice, Atribute Name Status. Bits 12 and 13 tell if the PLC is in Remote or run and can be used to infer program.

The only thing I can see with this (because I thought of GSV too) is that I’m not sure the bits will change while in program mode, because no tasks are running to execute the GSV.

That being said, it does work in Emulate 5000. I just don’t have a spare unit handy to use.

I’ve used this code in several different ControlLogix PLCs. If I remember correctly, it does update even when the program is set to program mode instead of run.

I put it in a nice little AOI so I can easily copy the code to all my different projects along with error status/messages, PLC serial number, firmware revision, etc.

[quote=“abishur”]
I put it in a nice little AOI so I can easily copy the code to all my different projects along with error status/messages, PLC serial number, firmware revision, etc.[/quote]Nice! Anything you’d be willing to share?

correct me if I am wrong, but does not all the tags quality change to BAD when the Contrologix/Compactlogix is placed in program mode?
I recall seeing this in the past.

[quote=“JordanCClark”][quote=“abishur”]
I put it in a nice little AOI so I can easily copy the code to all my different projects along with error status/messages, PLC serial number, firmware revision, etc.[/quote]Nice! Anything you’d be willing to share?[/quote]

Sure (EDIT: See this post a little further down in this thread for an updated version of this AOI)

2 Basic principles we work with are the idea that

A) Blocks should be top end agnostic. As a result any tag I want to read in the HMI is brought out of the AOI and requires a controller tag to be created (since not all HMIs are proficient at reading tags inside of AOIs, especially if you start nesting AOIs within AOIs)

B) All Alarming is synchronized with the PLC as much as possible. So on my block you’ll see Acknowledged bits (ACKD), Acknowledge commands (which I got lazy on and did not expose breaking principal A, :laughing: ), and alarm active bits (ALRM). Since the alarming is only used for notification purposes it won’t affect the process if you completely ignore these bits.

The block should have some basic comments on the code itself and the tags used in it. It was created using ladder logic because I was working on a project that had limited space and it turns out structured text code is almost twice the size as its ladder logic equivalent. Who knew?

[quote=“Curlyandshemp”]correct me if I am wrong, but does not all the tags quality change to BAD when the Contrologix/Compactlogix is placed in program mode?
I recall seeing this in the past.[/quote]

Honestly, I’m not sure. I haven’t been able to test my AB blocks on an Ignition HMI yet.

Okay I did a little more research and here’s what I found:

  1. My AOI will correctly report the correct position of the key switch except when it goes from remote program to key switch program, or back to Key switch remote position until the processor is set back to Run mode (makes sense)

  2. I need to add some tags to watch Controller_Status_Word.6 (Run Mode) and Controller_Status_Word.7 (Program Mode) (Controller_Status_Word is the variable I created to store the results of the GSV that get’s the Status Attribute from the ControllerDevice Class)

  3. When monitoring those two bits, bit 7 Does not update in the controller when placed in program mode, so it’s kind of useless…

  4. I might use Controller_Status_Word.14 in place of bit 7 because .14 is the “Controller Mode Changing Bit” it is set to true whenever the controller is in program mode. It’s probably also true in other use cases, but in theory those transitions should be quick and the only time it should be true for long periods of time is when it’s in program mode either by the software or the key switch based on initial testing

Pretty much everything you try on this subject will have to deal with the fact that code in the PLC simply isn’t going to run while in program mode. Writing PLC code to turn a bit on in program mode will always be stuck in this catch-22. The answer is to have a simple piece of code that changes a variable every scan (adds one, whatever). Then, from the outside, the code running vs. not-running can be determined by whether that variable is changing or not.
Or talk Kevin Herron into having the driver poll the processor’s identity object, status and state attributes. That’s not going to be easy to optimize, though. I’d just use the changing variable indicator and call it a day.

ptumel is absolutely correct. Fortunately, in real life usage how often are you going to run into a situation where you put it into program mode remotely then someone moves the key switch? Without access to the @Mode tag we find work arounds the best we can :slight_smile:

I do typically also use ptumel’s method in conjunction with my aoi, one of the tags on my aoi is PLC_SCAN_TIME which is the time it took for the PLC to execute one standard scan cycle in milliseconds. This number will always have some slight variation to it so what I’ll do is something to the tune of throw up a notification if the PLC is in program mode (which I’ll now be using the PLC_PROG_MOED tag which is triggered by controller_status_word.14 to notify off of) and a separate alarm in the HMI to detect a loss of communications with the PLC such that if PLC_SCAN_TIME is no longer updating AND if I’m not in program mode THEN I’ve most likely lost communications to my PLC.

Ignition might have a more direct means of detecting this, but I work with a lot of different platforms and try to remain as consistent as possible between them.

Here’s the updated version of my AOI incorporating the changes I mentioned a few posts back. The Run Mode and Program mode status bits are now brought out of the controller status.

Here are the quick and dirty details about the AOI

[ul]
[li] Written in Ladder Logic[/li]
[li] 448 bytes large[/li]
[li] Get’s system Clock[/li]
[li] Extrapolates Day of Week from Clock[/li]
[li] Gets PLC Serial Number[/li]
[li] Gets PLC Name[/li]
[li] Gets PLC Type[/li]
[li] Gets PLC Revision[/li]
[li] Alarms on IO Fault, Serial Port Error, Fault Handler Error, Execution errors, Watchdog timer expirations, Minor and Major Faults, and PLC Battery Status[/li]
[li] Detects position of Key Switch and Run/Program Mode (with limitations previously mentioned)[/li][/ul]

Importing this AOI will create the following additional AOIs, User-Defined Data Types, and String Data Types

[ul]
[li] HexToString AOI (140 bytes) - Used to Convert Serial Number from Hexadecimal to Human Readable String[/li]
[li] Clock User-Defined Data Type (16 bytes) - Presents PLC Clock as object with human readable extensions (i.e. Clock.Year, Clock.Month) instead of having to constantly lookup what Clock[0] and Clock[1] referenced[/li]
[li] String_8 (12 bytes) - a String with 8 characters max (saves a lot of space compared to default string)[/li]
[li] String_50 (56 bytes) a String with 50 characters max (saves a lot of space compared to default string)[/li][/ul]

Let me know if you need any assistance with the block. :slight_smile: