Inleiding
Object-Oriented Programming (OOP) is al decennialang een belangrijke programmeermethode binnen softwareontwikkeling. Concepten zoals encapsulatie, overerving en polymorfisme helpen om complexe systemen beheersbaar, herbruikbaar en schaalbaar te maken. Binnen industriële automatisering heeft OOP echter relatief laat zijn intrede gedaan.
Met de komst van IEC 61131-3 (3e editie) en moderne PLC-platformen zoals Beckhoff TwinCAT 3, Codesys en Simatic AX werd het mogelijk om objectgeoriënteerde programmeerprincipes ook binnen PLC-omgevingen toe te passen. Hierdoor kunnen engineers PLC-software op een meer gestructureerde en modulaire manier ontwikkelen.
Hoewel deze platformen uitgebreide OOP-functionaliteit bieden, blijkt het toepassen ervan in de praktijk vaak complexer dan verwacht. Veel PLC-programmeurs zijn gewend aan traditionele programmeerstructuren zoals Ladder of FBD. Het werken met objectgeoriënteerde concepten vraagt daarom vaak om een andere manier van denken.
OOP-concepten binnen PLC-programmering
Binnen PLC-programmering worden objectgeoriënteerde concepten meestal toegepast met behulp van function blocks, die worden uitgebreid met methodes, properties, interfaces en overerving. Deze elementen vormen samen de basis voor het ontwikkelen van modulaire en herbruikbare PLC-software.
Function Blocks als classes
Binnen OOP fungeren function blocks (FB’s) vaak als classes. Een functieblok kan interne data bevatten (VAR), maar ook methodes en properties. Daarnaast kunnen function blocks interfaces implementeren en gebruikmaken van overerving.
Door function blocks op deze manier te gebruiken kunnen engineers logica, data en gedrag scheiden binnen één softwarecomponent. Dit maakt PLC-software overzichtelijker en beter herbruikbaar.
Methodes
Methodes maken het mogelijk om logica binnen een functieblok te structureren. In plaats van alle functionaliteit in de cyclische body van een function block te plaatsen, kan specifieke logica worden ondergebracht in afzonderlijke methodes.
Een eenvoudig voorbeeld is het starten van een motor. In plaats van de startlogica direct in de hoofdcode te plaatsen, kan een methode StartMotor worden aangemaakt. Deze methode kan vervolgens vanuit andere delen van de software worden aangeroepen.
Door gebruik te maken van methodes blijft de code beter gestructureerd en eenvoudiger te onderhouden.
Properties
Properties bieden een gecontroleerde manier om interne variabelen te lezen of te schrijven. Bij het lezen of aanpassen van een property kan een stukje code worden uitgevoerd. Hierdoor kan er bijvoorbeeld validatie of conversie van waarden plaatsvinden.
Een typisch voorbeeld is het beperken van instellingen. Denk bijvoorbeeld aan een snelheid die alleen tussen 0% en 100% ingesteld mag worden. De property kan dan automatisch controleren of de waarde binnen deze grenzen valt. Indien dit niet het geval is, wordt deze vervolgens gelimiteerd. Een andere optie is bijvoorbeeld iets naar een log-file te schrijven als een property wordt gewijzigd.
Properties ondersteunen daarmee het principe van encapsulatie, waarbij interne data beschermd blijft tegen ongecontroleerde wijzigingen.
Interfaces
Interfaces maken het mogelijk om verschillende function blocks op een uniforme manier aan te sturen. In een interface wordt vastgelegd welke methodes en properties een functieblok minimaal moet bevatten.
Dit is bijvoorbeeld nuttig wanneer verschillende typen motoren worden aangestuurd. Een functieblok voor een SEW-motor en een functieblok voor een Lenze-motor kunnen intern sterk verschillen, maar toch dezelfde interface implementeren.
Een motorinterface kan bijvoorbeeld de volgende onderdelen bevatten:
- Start (methode)
- Stop (methode)
- Reset (methode)
- SetSpeed (property)
- SetAcceleration (property)
- SetDeceleration (property)
- AlarmState (property)
Omdat interfaces alleen methodes en properties ondersteunen, verschuift de communicatie tussen function blocks in de praktijk vaak van traditionele in- en uitgangsvariabelen naar properties.
Overerving
Overerving maakt het mogelijk om bestaande function blocks uit te breiden met extra functionaliteit. Een basisfunctieblok bevat generieke logica, terwijl bovenliggende klassen deze functionaliteit kunnen uitbreiden of aanpassen.
Het bepalen van de juiste overervingsstructuur is vaak een iteratief proces. In veel projecten begint het ontwerp met een aantal basisklassen en interfaces. Tijdens de verdere ontwikkeling wordt functionaliteit verplaatst of opgesplitst om een logische architectuur te creëren.
Praktisch voorbeeld: een klep control module
Als voorbeeld kan een control module voor een klep worden uitgewerkt.

Hierbij wordt een hiërarchie van function blocks gebruikt waarbij iedere klasse een specifieke verantwoordelijkheid heeft.
FB_Base
Dit functieblok vormt de basis voor alle function blocks binnen een project. Hierin kan generieke functionaliteit worden ondergebracht, zoals logging of het bepalen van de instantie-naam.
FB_CM_Base
Binnen Gain wordt vaak gewerkt volgens de PackML-standaard. Control modules worden daarom meestal gebaseerd op deze klasse. Functionaliteit zoals alarmafhandeling en mode control wordt hier afgehandeld.
CM_Valve_Base
Dit functieblok bevat de basislogica voor de aansturing van een klep. Methodes kunnen bijvoorbeeld worden gebruikt voor het openen en sluiten van de klep. Daarnaast zijn properties aanwezig voor de open- en dichtstatus.
De daadwerkelijke aansturing van de IO gebeurt echter in een verdere uitbreiding van deze klasse.
CM_Valve
Dit functieblok bevindt zich op het hoogste niveau en wordt gebruikt in de uiteindelijke applicatiecode. Hier wordt de logica uitgebreid met de daadwerkelijke IO-aansturing en controle van terugkoppelsignalen.
Varianten via overerving
Door gebruik te maken van overerving kunnen eenvoudig verschillende varianten van dezelfde component worden ontwikkeld.

Voor een klep kunnen bijvoorbeeld varianten bestaan zoals:
- een standaard klep (CM_Valve)
- een klep met meerdere feedbacksignalen (CM_Valve_TrippleFeedBack)
- een klep met analoge positie-terugkoppeling (CM_Valve_AnalogFeedback)
In plaats van alle functionaliteit opnieuw te schrijven, kan een nieuwe klasse eenvoudig overerven van CM_Valve_Base en alleen de specifieke verschillen implementeren.
Functionaliteit aanpassen met overriding
Naast het uitbreiden van functionaliteit is het ook mogelijk om bestaande methodes te overriden. Dit betekent dat een methode in een afgeleide klasse wordt aangepast.
Stel dat een specifieke klep een extra uitgang heeft. In dat geval kan een nieuwe klasse worden gemaakt die van CM_Valve overerft en de methode voor het aansturen van de uitgangen uitbreidt met deze extra functionaliteit.
Voordelen van Object-Oriented Programming in PLC-projecten
Het toepassen van OOP in PLC-software biedt verschillende voordelen:
- betere schaalbaarheid bij grote installaties
- hogere herbruikbaarheid van componenten
- betere onderhoudbaarheid door encapsulatie
- verbeterde testbaarheid door het gebruik van interfaces
Door software modulair op te bouwen wordt het eenvoudiger om installaties uit te breiden of aan te passen.
Uitdagingen van OOP in PLC-systemen
Hoewel OOP veel voordelen biedt, brengt het ook enkele uitdagingen met zich mee.
Performance en realtime-eisen
PLC-systemen werken in realtime omgevingen met strikte cyclustijden. Extra abstractielagen zoals method calls en interfaces kunnen invloed hebben op de performance wanneer de softwarearchitectuur niet goed ontworpen is.
Complexiteit van overerving
Diepe inheritance-structuren kunnen onoverzichtelijk worden. Waar een functie zonder OOP soms uit één function block bestaat, kan een objectgeoriënteerde implementatie uit meerdere lagen bestaan.
Wanneer functionaliteit echter goed wordt gescheiden, blijft de structuur juist overzichtelijk en is code eenvoudiger terug te vinden.
Best practices voor OOP in PLC-software
Bij het toepassen van Object-Oriented Programming in PLC-projecten is een aantal richtlijnen belangrijk:
- begin met een duidelijk klassemodel
- gebruik compositie waar mogelijk
- scheid hardware-I/O van businesslogica
- documenteer de softwarearchitectuur
Deze aanpak helpt om complexe automatiseringssystemen beheersbaar te houden.
Conclusie
Object-Oriented Programming biedt binnen moderne PLC-platformen krachtige mogelijkheden om industriële software professioneel en schaalbaar op te bouwen. Door gebruik te maken van klassen, interfaces en overerving kan PLC-software beter gestructureerd en herbruikbaar worden gemaakt.
Tegelijkertijd vraagt het toepassen van OOP om een goede softwarearchitectuur en een andere manier van denken voor PLC-programmeurs.
Binnen Gain hebben we inmiddels veel ervaring opgedaan met het toepassen van OOP binnen PLC-besturingen. Op basis van deze ervaring hebben we een eigen framework ontwikkeld voor Beckhoff-systemen dat vrij beschikbaar is via GitHub.
