Environment: VC6, Windows, PLC
Overview
Modern automation of industrial plants use networking. Specialized networks, called fieldbus, have been in use for many years and in many flavours. Modbus, the most successful, recently found its way to CodeGuru—see MODBUS Serial RTU Simulator by Conrad Braam.
Over the last years serial Modbus communication over RS-232 or RS-485 have been replaced by Ethernet using TCP/IP. Most (all?) PLCs (programmable logic controller)now support Modbus/TCP.
Using Ethernet with its large bandwidth makes other new tools possible. One of the most important is the simulation of Ethernet I/O, possibly including a complete simulation of the behaviour of the plant.
Networked Simulated Plants (NSP) is a frame program that connects a plant simulation in an ActiveX to a Modbus/TCP server. It establishes Ethernet-based I/O for a PLC.
Using such Ethernet I/O allows you to debug and test automations with a simulation instead of the real plant. And simulations in a Windows program can model the plant much better than the usual switchboards or others.
The sample here contains four simple models and a toolkit to create your own new simulations that model your specific plant.
The PLC needs to work as a Modbus/TCP client.
If a suitable PLC is not at hand (or delivered to a customer and no longer available) OATs, a PC-based IEC 61131 compatible PLC software, can be used free for self-education.
OATs contains a MS-Windows based programming support environment and MS-DOS based PLC run-time kernels that may include Modbus/TCP clients and servers.
A complete specification of the Modbus protocol can be found at the Modicon site.
How to Create NSP Simulations
Here comes a small “toolkit” to create new plant simulations. The sample uses VC6.
Assume the new ActiveX simulation should have the name WHATEVER. It will reside in a file WHATEVER.OCX. A template will be used as a starting point. The template should focus on the simulation of the plant behaviour, the visual representation, and possibly some manual handling if such is available at the automation site. The completed simulation can be loaded into the NSP frame that in turn manages the Modbus/TCP communication as well as steadily calling your WHATEVER simulation for updates.
Step 1
Copy the template in the PLANT folder.
Copy the entire PLANT folder to a suitable location. You will possibly change the folder name from PLANT to something more meaningful. But don’t change the names of files within the folder. It’s not required.
In this tutorial, the name WHATEVER stands for the name of your NSP simulation.
Step 2
Open your copy of the template copy with Visual C++. It is the PLANT.DSW file that you have to open.
Change the name of the output file in the project settings from PLANT.OCX to WHATEVER.OCX. Do this for both the debug and the release version. The entry to do so is in the linker/general chapter.
Also, change the name of the output file in Plant.def. The “LIBRARY” entry there needs to be edited.
Search for IMPLEMENT_OLECREATE_EX. You will find it, for the current time, in PLANTCtl.cpp, PLANTCtl.h, PLANTPpg.cpp, and PLANTPpg.h.
In PLANTCtl.cpp and in PLANTPpg.cpp, change the string “PLANT.NSP” to “WHATEVER.NSP”. This is not a must but it can ease the management of NSP simulations. It creates a better-looking name in the Registry and for other programs that use ActiveX control names from the Registry.
Compile the ActiveX.
Step 3
Exchange the GUIDs in the template.
This is an important step. It is required to not confuse the GUIDs (Globally Unique Identifiers) in your Registry.
With Microsoft Visual C++ comes a program called Guidgen.exe. This program creates new GUIDs for you.
Start Guidgen.exe.
Guidgen.exe creates GUIDs in 4 formats. Select the third format, which is what you need here. Other formats require some more labour. Guidgen.exe copies entries such as
// {649072C0-5F8B-11d7-A3C5-000795DA4C2F}
static const GUID <<name>> =
{ 0x649072c0, 0x5f8b, 0x11d7, { 0xa3, 0xc5, 0x0, 0x7, 0x95,
0xda, 0x4c, 0x2f } };
to the Clipboard. Please note that you find the GUID in two forms. The first line shows a comment with the Registry format that will be used for odl-files and the third line shows the format that the compiler expects in cpp-files. You need both.
For each new GUID, press the “New GUID” button and copy the result onto the Clipboard by pressing the “Copy” button.
You need four GUIDs four each NSP simulation. Each GUID has to be used twice, once in a cpp-file and once in the odl-file. This part of your work is a bit tricky.
The first GUID goes into Plant.cpp and Plant.odl. In Plant.cpp, locate
const GUID CDECL BASED_CODE _tlid =
{ 0x1b6a35c0, 0x5f65, 0x11d7, { 0xa3, 0xc5, 0, 0x7, 0x95,
0xda, 0x4c, 0x2f } };
and replace the funny numbers in the 2nd line with a new one from the Clipboard but do not touch the first line.
Then in Plant.odl locate
[ uuid(1B6A35C0-5F65-11D7-A3C5-000795DA4C2F), version(1.0),
helpfile(“PLANT.hlp”),
helpstring(“PLANT ActiveX control module”),
control ]
and replace the number there. Here the number is in the Registry format.
Don’t forget to press the “New GUID” button and the “Copy” button in Guidgen.exe for a new GUID.
The second GUID goes into PlantCtl.cpp and Plant.odl. In PlantCtl.cpp, locate
IMPLEMENT_OLECREATE_EX(CPLANTCtrl, “WHATEVER.NSP”,
0x1b6a35c3, 0x5f65, 0x11d7, 0xa3, 0xc5, 0, 0x7, 0x95,
0xda, 0x4c, 0x2f)
and again replace the funny numbers with new ones.
Then in Plant.odl locate
[ uuid(1B6A35C3-5F65-11D7-A3C5-000795DA4C2F),
helpstring(“PLANT Control”), control ]
and replace the number there. Here again, the number is in the Registry format.
Don’t forget to press the “New GUID” button and the “Copy” button in Guidgen.exe for a new GUID.
The third GUIDs goes into PlantCtl.cpp and Plant.odl. In PlantCtl.cpp, locate
const IID BASED_CODE IID_DPLANT =
{ 0x1b6a35c1, 0x5f65, 0x11d7, { 0xa3, 0xc5, 0, 0x7, 0x95,
0xda, 0x4c, 0x2f } };
and again replace the funny numbers with new ones.
Then, in Plant.odl, locate
[ uuid(1B6A35C1-5F65-11D7-A3C5-000795DA4C2F),
helpstring(“Dispatch interface for PLANT Control”), hidden ]
and replace the number there. Again, it is in the Registry format.
Don’t forget to press the “New GUID” button and the “Copy” button in Guidgen.exe for a new GUID.
The forth GUID goes into PlantCtl.cpp and Plant.odl. In PlantCtl.cpp, locate
const IID BASED_CODE IID_DPLANTEvents =
{ 0x1b6a35c2, 0x5f65, 0x11d7, { 0xa3, 0xc5, 0, 0x7, 0x95,
0xda, 0x4c, 0x2f } };
and again replace the funny numbers with new ones.
Then, in Plant.odl, locate
[ uuid(1B6A35C2-5F65-11D7-A3C5-000795DA4C2F),
helpstring(“Event interface for PLANT Control”) ]
and replace the number there. Here, the number is in the Registry format.
If you revise your NSP simulation and the new version should replace the old one, you can keep the GUIDs. But, if you create another NSP simulation from an existing one, you will need new GUIDs.
Save all and compile the ActiveX.
Step 4
And now, to the real meat of your NSP simulation.
To complete your simulation, you have to expand two functions, CPLANTCtrl::OnDraw() and CPLANTCtrl::Tick(). The Tick() functions get the mathematical part of your simulation, whereas the OnDraw() functions will perform the visual effects in the window.
These two functions will become your major work item.
The template just draws an ellipse into the window. And it copies one digital output to a digital input and one analog output to an analog input. See the code in the two functions.
The following picture shows NSP with a traffic light simulation in action.
A PLC executes the automation code. Here it is programmed in a ladder. Inputs and outputs are connected over Ethernet by using a Modbus/TCP client in the PLC. The Modbus/TCP I/O server runs on the same workstation as the Programming Support Environment does. So, you can see both, the running PLC program and the effect to the traffic lights.
Good luck.
Friedrich Haase