OpenPLC
Vandaag gaan we het hebben over een fantastisch open-source Raspberry project, namelijk OpenPLC. Met OpenPLC maak je van je Raspberry Pi een open-source PLC (Programmable Logic Controller). Het OpenPLC-project is gemaakt in overeenstemming met de IEC 61131-3-standaard welke de basis software architectuur en programmeertalen voor PLC’s definieert. PLC’s kom je veel tegen in industriële automatisering en domotica, IoT (Internet of Things) en SCADA omgevingen. Normale PLC’s zijn aardig prijzig. Om toch te kunnen experimenteren met het programmeren, bedienen en testen van een PLC en daarbij behorende protocollen is het OpenPLC project een echte aanrader. Laten we die Raspberry Pi omtoveren tot een PLC.
Zoals jullie weten https://jarnobaselier.nl/proces-automatisering-pa-intro/ is een PLC een programmeerbare Logic Controller een elektronisch apparaat met een microprocessor. Een PLC stuurt n.a.v. bepaalde input bepaalde uitgangen aan. Het voordeel aan OpenPLC is dat het open-source is en dat het compatible is met hardware die betaalbaar is.
In bovenstaande post en in mijn ModBus post: https://jarnobaselier.nl/hoe-werkt-modbus kun je meer te weten komen over PLC’s en het ModBus (poort 502) protocol. Naast ModBus ondersteund OpenPLC ook nog het DNP3 (Distributed Network Protocol 3) SCADA protocol (poort 20.000).
OpenPLC kan geprogrammeerd worden in alle 5 de programmeertalen gedefinieerd door de IEC 61131-3 standaard. Dit zijn:
- ST – Structured Text
- IL – Instruction List
- LD – Ladder Logic
- FBD – Function Block Diagram
- SCF – Sequential Function Chart
In deze post richten we ons op de installatie en het programmeren van het OpenPLC master device. Zoals je op de website kunt zien bestaat de totale installatie uit 3 pakketten:
- Runtime – De runtime wordt geïnstalleerd op het apparaat welke als (slave) PLC gaat functioneren en dus de PLC programma’s gaat uitvoeren.
- Editor – De initiatieven editor maakt het mogelijk om de PLC applicaties te schrijven in alle 5 de programmeertalen die hierboven genoemd zijn. De editor is te downloaden voor Windows en Linux.
- ScadaBR HMI Builder – ScadaBR kun je gebruiken om interactieve applicaties te maken waarmee je grafisch je PLC’s kunt besturen. Dit noemen we ook vaak HMI (Human Machine Interface) systemen. ScadaBR is volledig compatible met OpenPLC.
In deze post maak ik slechts gebruik van de runtime en de editor. Het wordt pas echt leuk als je slave devices gaat toevoegen, een proces creëert en die vervolgens via ScadaBR bestuurd en controleert.
OpenPLC Editor Installeren
Alle downloads zijn te vinden op: https://www.openplcproject.com. De editor is beschikbaar voor Windows en Linux. Wij installeren hem binnen Windows. De installatie is simpelweg het uitpakken van het ZIP bestand. Om de applicatie te starten druk je op de “OpenPLC Editor” snelkoppeling in de root van de folders. OpenPLC start vervolgens op en is klaar voor gebruik.
OpenPLC Runtime Installatie
De eerste stap in de installatie van de OpenPLC Runtime op de Raspberry Pi is het installeren van de nieuwste versie van Raspbian. Nadat Raspbian geïnstalleerd en geüpdate is kunnen we middels GIT de juiste repository binnenhalen.
git clone https://github.com/thiagoralves/OpenPLC_v3.git cd OpenPLC_v3 ./install.sh rpi |
De installatie van OpenPLC op een Raspberry Pi 3B duurde ongeveer 30 minuten.
Reboot de Raspberry en je hebt je Raspberry veranderd in een PLC.
Configureer je OpenPLC
Om programma’s te uploaden naar je PLC kun je de ingebouwde webserver gebruiken welke luistert op poort 8080. De loginpagina van je OpenPLC webserver ziet er als volgt uit:
De default credentials zijn:
Gebruikersnaam: openplc
Wachtwoord: openplc
Het is uiteraard aan te raden om de default credentials aan te passen. Het volgende wat we aan gaan passen is de pin-mapping. Het is na installatie namelijk nog niet mogelijk om de GPIO pinnen te besturen. Om deze besturing in te schakelen ga je naar “Hardware” en vervolgens schakel je de “OpenPLC Hardware Layer” in op het “Raspberry Pi” schema.
De default GPIO pin layout van de Raspberry is als volgt:
OpenPLC gebruikt een board numbering layout met custom names. Dit ziet er als volgt uit:
Alle pinnen aan de linkerkant beginnen met de “%IX” aanduiding. Dit zijn “Discrete Inputs”. Deze kun je zien als “contacts” zoals switches en buttons (apparaten die stroom controleren). Alle pinnen aan de rechterzijde hebben een “%QX” aanduiding. Dit zijn “Discrete Outputs”. Voor het gemak kun je deze zien als “coils” zoals motoren en lampen (apparaten die stroom verbruiken).
Er is echter wel iets waar je op moet letten. De Raspberry Pi heeft slechts 1 analoge PWM output pin (12 – QW0.0) welke gebruikt wordt als analoge output pin door OpenPLC. Dit is de enige pin die je voor analoge doeleinden kunt gebruiken. In de praktijk zul je de QW0.0 pin vaak niet gebruiken. Daarnaast zijn de eerste 2 input pinnen (3 – IX0.0 en 5 – IX0.1) voorzien van zogenaamde “hardware pullups”. Dit betekend dat deze altijd “WAAR” zullen zijn als er niets op aangesloten zit. Dit zit by-default in het design van de Raspberry’s hardware en kan niet worden veranderd door OpenPLC. Algemene tip, gebruik deze dus gewoon niet.
In principe zijn we klaar om de PLC te voorzien van zijn eerste programma. Je kunt eventueel nog wat poortinstellingen aanpassen maar in de meeste gevallen zal dit niet nodig zijn. Wat ik wel fijn vind is om de PLC gewoon automatisch op te starten:
Eerste OpenPLC programma
Nu zijn we zover dat we de PLC kunnen laten functioneren. Maar hiervoor moeten we eerst een programma schrijven. Nu zijn ze zo vriendelijk geweest om de eerste applicatie, de zogenaamde “hello world” applicatie ter download aan te bieden. Als we deze openen in de editor dan ziet dit er als volgt uit:
Dit ziet er wellicht wat ingewikkeld uit maar dat valt best wel mee als je begrijpt hoe PLC’s geprogrammeerd worden. De OpenPLC editor bouwt PLC applicaties via zogenaamde “Ladder Logic”. Een wat uitgebreider PLC programma ziet er b.v. als volgt uit:
Dat lijkt al aardig op een “ladder” toch? Ladder Logic is een representatie van hard-wired relay circuits en daarom ideaal voor het programmeren van een PLC. PLC applicaties worden van boven naar beneden en van links naar rechts uitgevoerd. Precies zoals we een boek lezen dus. Elke trede (stap) noemen we een “Rung”. Wanneer een cycles (een programma) is doorlopen noemen we dat een “scan”. Een PLC voert vaak meerdere scans per seconde uit.
Verder zie je 2 rails in bovenstaande schema. Dit zijn power rails. Om dit te visualiseren, de stroom begint links boven en komt bij de eerste “rung”. Hier bevind zich een “contact”. Dit kun je zien als een “button” om de status naar “waar” te veranderen. Maar dit kan ook een logisch contact zijn (dus geen fysieke schakeling). Door het contact wordt dus een contactmoment geïllustreerd. Als er contact gemaakt wordt dan zal de relay (coil) worden ingeschakeld. Vervolgens gaat de PLC verder met rung 2 waar hetzelfde wordt herhaald om een lamp (coil) te laten branden. Op rung 3 bevind zich bijna eenzelfde scenario behalve dat dit een contact is welke al verbonden is (negated). Dit kun je zien als een noodstop. Dus alleen als deze verbroken wordt zal lamp 2 uitgaan maar normaliter is dit een open verbinding.
Met deze informatie moeten we de “Hello World” applicatie kunnen begrijpen. Laten we de editor nogmaals bekijken. Deze bestaat uit de volgende onderdelen:
Links boven zie je je projectbestand (huidige weergave) en een config file. Wanneer een project aangemaakt wordt dan wordt er eveneens altijd een config file aangemaakt. In dit bestand worden de volgende zaken voor je project gedefinieerd:
- Global Variables
- Tasks – B.v. hoe vaak wordt een PLC cycle uitgevoerd per miliseconde (50 is meestal een veilige waarde).
- Instances
Het config venster ziet er als volgt uit:
Het is voor de Hello World applicatie niet nodig om deze globale config aan te passen. De Hello World applicatie ziet er dus als volgt uit:
De hele applicatie bestaat uit 1 rung. Wanneer de button (my_button) ingedrukt wordt gaat de coil (lamp) branden. In het midden staat echter nog een speciaal blok, “TOF0”. Dit is een “Timer Off” ofwel een “Off Delay Timer” functieblok. In dit functieblok definiëren we de functie PT welke Q op “True” laat voor de gedefinieerde tijdsperiode als de stroom van “IN” onderbroken wordt. Met andere woorden. Als de button wordt losgelaten dan zal de lamp nog 2 seconde blijven branden.
Het volgende wat we aan moeten passen is de input pin voor de pushbutton. Remember… IX0.0 en IX0.1 zijn off limits… en dus gebruiken we IX0.2.
Nadat we dit aangepast hebben zijn we klaar om het programma te genereren:
Er wordt nu een *.st file gemaakt welke we kunnen uploaden via de “Programs” – “Upload Program” sectie.
Het programma zal gecompiled worden en actief geplaatst worden:
Je Raspberry Pi OpenPLC is klaar voor gebruik. Nu moet het hardware technisch nog goed aangesloten worden. Het aansluitschema ziet er als volgt uit:
- De lamp wordt met de positieve pin aangesloten op signaalpin QX0.0 en met de negatieve pin op de ground met een 100 Ohm resistor ertussen.
- De pushbutton word met de positieve kant aangesloten op de 3.3V power pin en met de signaalpin op IX0.2 met een 100 Ohm resistor ertussen.
Omdat de Raspberri Pi ook interne resistentie heeft heb ik de 100 Ohm resistor bij de pushbutton achterwege gelaten. Dit ziet er als volgt uit:
Nu zijn we klaar om de PLC te starten.
Het programma werkt. Via de “Monitoring” pagina is deze status exact te volgen:
Onze eerste PLC applicatie via ModBus (default) is gemaakt. Nu kunnen we dus eventueel vanuit pentesters perspectief hier diverse testen op uitvoeren.
Uiteraard kun je nu, als je zin hebt de ScadaBR software installeren zodat je een HMI interface kunt genereren om dit proces actief te volgen. Dit nemen we niet mee in deze post.
OpenPLC Hello-World-2 Voorbeeld
Nog een iets uitgebreider voorbeeld. Kijk eens naar onderstaande schema.
We zien hier een uitgebreider schema dan voorgaande voorbeeld. Het diagram is uitgebreid met een extra schakelaar (emergency_button) en een extra lamp (lamp2).
Dit ziet er als volgt uit:
Zoals je in het schema kunt zijn is de emergency_button een zogenaamde “inverted button”. Dit betekend dat er altijd stroom doorheen loopt behalve als de button wordt ingedrukt. Omdat de button tussen lamp1 en lamp2 zit zorgt de button ervoor dat lamp2 meteen wordt uitgeschakeld als de noodknop ingedrukt wordt. Lamp1 zal gewoon blijven functioneren.
Dit zie je terug in de monitoring:
En natuurlijk in de werkelijke schakeling:En natuurlijk in de werkelijke schakeling:
OpenPLC Hello-World-3 Voorbeeld
Bovenstaande concept kunnen we weer wat uitbreiden. Zie onderstaande schema:
Je ziet hier dat we nog een lamp (lamp3) erbij geplaatst hebben. Deze lamp hebben we aangesloten op de emergency_button in een nieuwe rung. Deze button is in het de nieuwe rung geen inverted button en dus levert hij in pas stroom als hij ingedrukt wordt. Dit is echter wel dezelfde button. Deze button levert stroom aan lamp3 middels een TON functieblok. Het TOF functieblok (in rung 1) hield Q nog 2 seconde aan (true) nadat op de button losgelaten was. Het TON functieblok zet Q pas aan als de button 2 seconde ingedrukt wordt.
Het resultaat in dit schema is dat lamp2 uit gaat als de emergency_button wordt ingedrukt en dat lamp3 aan gaat als de emergency_button langer dan 2 seconde wordt ingedrukt.
Zo ziet het eruit qua aansluitingen:
*ps… zie je ook dat de kleuren van de knopjes spontaan veranderd zijn? 🙂
En zo werkt het:
En uiteraard laat de monitoring dit weer heel duidelijk zien:
Monitoring” pagina is deze status exact te volgen:
Conclusie
OpenPLC is een fantastisch project. Het werkt, het is compleet en het is helemaal niet duur. Daarnaast lijkt alles super stabiel te draaien en zijn alle benodigde functies aanwezig. Wil je meer weten over elektrische schema’s, ladder logic, plc protocollen zoals modbus of wil je je eigen mini fabriek bouwen? OpenPLC maakt dit mogelijk. Ik ben serieus onder de indruk en ben van plan om een eigen geautomatiseerd poppenhuis o.i.d. te gaan bouwen met OpenPLC. Als ik dat ga doen is dat uiteraard te volgen op deze blog.
Mijn posts kosten meestal aardig wat tijd. Denk aan research, vertalen naar hapklare brokken, fotograferen, video’s maken, opschrijven en publiceren. En ik maak ze graag want ik leer er zelf heel veel van. Ik hoop hiermee echter jullie ook iets te leren! Vond je deze post nou interessant of heb je er op een andere manier iets aan gehad, laat het blijken! Deel deze post op je sociale kanalen of eigen website. Geef hem een like of stuur me een leuk berichtje. Al deze zaken geven me nog meer zin om weer aan de volgende post te werken! Alvast ontzettend bedankt!