Part 2 of this series explained how OOIP uses new I/O mapping and configuration techniques, and this Part 3 will show how Interfaces and Methods are used to implement those new configuration techniques as well as other centralized services.
In OOIP, objects are distributed throughout a control design just like objects are scattered throughout a plant or piece of equipment. For instance, say a refrigerator manufacturing plant has an assembly line system, which has an insulation injection subsystem, which has a polyurethane processing subsystem, which has an isocyanate material subsystem, which has a tank subsystem. In this plant, there are thousands of sensor objects distributed from the top-level assembly line all the way down to the tank subsystems and throughout adjoining branches.
During the time the task-based programming approach described in Part 2 became popular, there was no practical way to implement central services which could accommodate the distributed nature of an OOIP design. The only solution was to centralize the entire design. Fortunately, newer development environments have implemented features which allow the best of both worlds: distributed control objects (so the control design can mirror the plant design) and centralized services (to manage these distributed objects).
In Part 2 we introduced the analogy that the older task-based programming technique was akin to a strong centralized government where each tag had to be registered with the service it required (like the Bureau of Scaling, the Bureau of Alarming, the Bureau of Persistence, and such). OOIP is more like self-governing society where citizens largely take care of themselves. But even the most ardent fan of small government agrees that some level of central government is necessary. How are these distributed objects configured? How are their alarms managed (aggregated, acknowledged and shelved)? How are their state values saved and restored in case of a power failure or controller replacement? Interfaces and Methods play a key role in managing these tasks.
A Method can be thought of as a Function which belongs to a Function Block and can be accessed through the instance of that Function Block. Figure 2 shows an example of the “AnalogSensor” Function Block which has an “AcceptConfig” Method and how an instance of “AnalogSensor” named “L1” is placed on the isocyanate tank deep in the refrigerator manufacturing plant described earlier. At startup, a central service can read the configuration information from a central database and pass the configuration parameters to that instance by making a call to that instance’s “AcceptConfig” method using its full path name “Plant.AS1.II1.PP1. Isocyanate.L1.AcceptConfig."
Methods also have access to their parent Function Block’s variables and can be overridden by Methods in extended Function Blocks. Methods can also have access control to limit access to the parent only (private), the parent and all extended Function Blocks (protected), or be open to all (public).
Interfaces are a tool for organizing access to a Function Block’s Methods. An Interface is a contract made by a Function Block to support a specific set of Methods and for those Methods to have a specific set of Inputs and Outputs. In addition to making Methods easier to manage, Interfaces allow Function Blocks which agree to that contract to be treated as a homogeneous group. A central service can then manage all the Function Blocks as a single set.
For example, say we have a variety of types of Function Blocks which need to know if it is day or night as shown in Figure 3. Each of these Function Blocks agree to the “DayOrNightInterface” contract by adding the words “Implements DayOrNightInterface” to their declaration. Then, all instances of Function Blocks which have implemented the “DayOrNightInteface” (lines 3 and 4) can be assembled into an array of type “DayOrNightInterface” (lines 6 and 7). This array can then be used to notify the instances as a single group at dawn or dusk (Main implementation line 3).
In traditional PLC programming, every function that needed to know if it is day or night would individually poll the light sensor. This is somewhat akin to the family vacation parody where each child in the station wagon repeatedly asks dad “are we there yet?” Using Methods and Interfaces as in Figure 3, the sensor is instead polled in one place and the functions are then notified when the status has changed. In this modern SUV, all the children quietly pursue their own interests trusting dad to let them know when they arrive. The parents can travel in peace.
The approach above works fine when the objects are all instantiated in the same program (i.e., for an SUV full of children where presumably the dad knows all his children). But further steps are required for Object Oriented Industrial Programing (OOIP) where instances of objects can be instantiated inside other objects and objects become distributed throughout the hierarchy of a plant design (such as in the refrigerator plant example above). In this type of system, additional features are used to allow the distributed objects to register themselves with a central service. This system is analogous to families taking a night Amtrak train on vacation where the dad lets the conductor know their destination and seat numbers. The conductor can then wake up each family when approaching their destination.
This self-registration relies on a key feature in CODESYS shown in Figure 4. Every Function Block which needs configuration services implement the “ConfigMgrInt” Interface and has “AcceptConfig” and “RegisterMyConfig” Methods. The first line of the “RegisterMyConfig” method contains the “call_after_global_init_slot” attribute which causes that method to be automatically executed when the programs initiates.
The remainder of the registration and configuration process is shown in Figure 5. Each instance of each Function Block which implements “ConfigMgrInt” uses its “RegisterMyConfig” method to pass a pointer to itself, its Function Block name, and its Instance name to the “RecieveObjectRegistration” Method of the “Configurator” Central Service. The Configurator then places that information into an array of type “ConfigMgrInt." The Configurator then obtains the configuration data for the configurable objects (from a CSV file or SQL Database), finds the matching instance name in the array, and uses the pointer that was provided by the object at initiation time to pass this data to each objects’ “AcceptConfig” method. The “AcceptConfig” Method then writes the data to the appropriate configuration inputs.
The actual implementation of the Configuration and Alarm central service is shown in Figure 6. Notice the Configuration service also includes “ProvideConfigTitles” and “ProvideConfig” methods. These methods allow the system to write a well-formatted configuration parameter file with the configurations grouped by Function Block type prefaced with a parameter name header line as shown in Figure 7. This file serves as an ideal starting point for the controls engineer to begin the configuration specification process. Once the plant or equipment is up and running, these methods can also be used to store the configuration values of specific instances. This is useful for saving tuning parameters or other changes made to specific instances during operation, or archiving snapshots of critical variable values so the state of the system can be restored after a power failure or controller replacement.
Object Oriented Industrial Programming allows engineers to quickly create highly intuitive control designs by assembling control objects in the same way matching hardware objects are assembled in the plant or equipment. In addition to the concepts of OOIP described in Parts 1 and 2 of this series, Methods and Interfaces are two additional key features of OOIP. These features provide a way for objects which are distributed throughout the plant hierarchy to receive central services such as configuration, alarming, persistence, and checkpoints. Just as the best of other general software advancements have been adopted into the industrial controls world, Object Oriented Industrial Programming is following that same pattern. OOIP is clearly the future of Controls Engineering.
Part 1 of this article can be found here.
Part 2 of this article can be found here.
A clearinghouse for open-source OOIP Functions Blocks and design examples can be found here.
A demo on Configurable I/O mapping can be viewed here.
The CODESYS IDE used for the examples in this article can be downloaded at no charge from this site. The download includes a complete SoftPLC which will run for 2 hours between resets.
For a video demonstration of Object Oriented Industrial Programming, Simulation, and Configuring Objects, see this video.
For more elaborate examples of Discrete, Batch, and Continuous control system designs implemented in OOIP, see this video.
This article is dedicated to the memory of Chuck Piper, K9TRN, of Madison, Wisconsin who tolerated and mentored a pesky 11-year old through building his first novice transmitter, and was key to launching a lifelong passion for electrical engineering.
Author Gary L. Pratt, P.E., is president of ControlSphere Engineering.