Timing of GDS writes, program destruction, and firmware shutdown
Hello,
I am building a C++ component + associated program used by the PLM.
When the firmware shuts down in an expected manner (e.g. not by sudden power failure), I would like all hardware components (e.g. fans, motors, etc.) controlled by the PLC to be stopped. Some of these hardware components are controlled via Modbus/Profinet, and my PLC program communicates with them via GDS ports in the program.
My question is: upon firmware shutdown, what is the relative timing of GDS writes, program destruction, and component destruction? I would like the program to be alerted when shutdown occurs, write 'OFF' values to the corresponding hardware component GDS ports, and for these to be written out on the Modbus/Profinet fieldbuses, but I seem to be unable to get this to work.
I have attempted to send signals to the program when the component's ResetConfig() or Stop() methods are called to write out 'OFF' values, and in the program's destructor itself, but to no avail.
Could you provide any assistance?
Thanks,
Joe
Comments
Joe,
Unfortunately there is currently no mechanism for a program being executed on the ESM to know when it is being executed for the last time before a controlled shutdown.
This question also comes up for programs written in IEC 61131 languages in PLCne.
One possible solution - and probably the easiest - is to create a program instance in an "Event Task" of type "Stop". This can be done in PLCnext Engineer's "Tasks and Events" window. A new program type will need to be created specifically for this task, and this program can be written in C++ if desired.
It might be possible to do cleanup work in that program instance.
If you need any further assistance, feel free to continue to post here or contact your local Phoenix Contact office.
Regards
Andrew Ellis
Hi Andrew,
Thanks for your reply. I have implemented a new C++ program under the component that is triggered by the Arp.Plc.Esm.OnStop event. Through logging, I've confirmed that this program's Execute() function does get called when the firmware shuts down, but writing to the component's ports seems to have no effect upon the GDS (in this case, a Modbus server does not receive a request to set a value to 0, even though the port variable is set to 0).
Do you have any more advice on how to proceed?
Thanks,
Joe
Joe,
Can you confirm how the Modbus component has been implemented? Is it written in IEC61131 or as a further C++ component? Also if it is implemented as part of the PLCnext Runtime, what task do you currently use to run that component?
Regards
Andrew Ellis
Hi Andrew,
The Modbus component is the built-in Modbus TCP client from firmware version 2024.6 https://www.plcnext-community.net/infocenter/modbus_tcp_client/.
My program communicates with this client by reading/writing from GDS ports.
Thanks,
Joe
I have reproduced this behaviour using the Modbus TCP client (master) in PLCnext Engineer - I linked a Global variable to a Modbus OUTPUT variable and then set the value of that variable in a program instance in a Stop event task. The value of the Global variable was set in the program instance, but that value was not written to the Modbus slave. The same behaviour occurs when an OUT port variable is used instead of a Global variable.
It turns out that this isn't just an issue for Modbus I/O, and this was identified as a requirement for PLCnext Control devices a good few years ago. Unfortunately there is currently no timeline for the implementation of this feature.
The only workaround that I'm aware of is to check if the slave device has a default output setting, which it uses in case communications with the master is lost. This is possible with Axioline I/O modules, where a "substitute value" can be set for each Output channel.
If you'd like to discuss this in more detail, I'd like to suggest that you contact Andrew Ellis and his colleagues in your local Phoenix Contact office.