Hello SPS! Teil 2: Mit OpenPLC vom Lernen zum Anwenden

Seite 4: Generelle Strukturierung von PLC-Anwendungen

Inhaltsverzeichnis

Nach dieser eher pragmatischen Vorstellung fehlt noch eine kurze Erläuterung zu der generellen Strukturierung von PLC-Anwendungen. Die genannten Konzepte sollten an dieser Stelle, das heißt nach den vorangegangenen Abschnitten und Beispielen Sinn ergeben.

Gemäß des IEC 61131-3-Standards setzen sich PLC-Anwendungen nämlich aus folgenden Ingredienzen zusammen:

  • Program: besteht aus einer Sequenz von Anweisungen, die eine PLC ausführt.
  • Task: besteht aus ein oder mehreren Programs. Es kann mehrere Tasks geben, die jeweils in einem bestimmten Zeitintervall oder aufgrund eines bestimmten Ereignisses zur Ausführung gelangen.
  • Networks: Programs können sich aus Networks zusammensetzen, von denen jedes eine eigene Substruktur des Programms oder der Schaltung definiert.
  • Inputs und Outputs: definieren die Eingänge beziehungsweise Ausgänge einer Anwendung.
  • Function Blocks: sind wiederverwendbare Komponenten, die dem Anwender das wiederholte Schreiben komplexer Sequenzen von Instruktionen ersparen.
  • Variables: gibt es in zwei Facetten: lokale Variablen gelten nur innerhalb eines Program oder Function Block, globale Variablen sind Program- und sogar Task-weit verfügbar.

Nicht jede PLC oder Programmierumgebung für eine PLC unterstützt all diese Konzepte vollumfänglich.

Wer auf der OpenPLC-Runtime für Raspberry-Pi, Linux- oder Windows-Computer ein Mikrocontrollerboard nutzen möchte, um dessen Ports über die Host-Runtime anzusprechen, erreicht dies über ein "leeres" Dummy-Projekt. Ein adäquates Projekt speziell für diesen Zweck befindet sich auf der Webseite für Slave-Devices als Datei Blank Project.zip. Diese Datei müssen Entwicklerinnen und Entwickler entpacken und über den OpenPLC-Editor als Projekt laden, um danach die Runtime auf das Board zu bringen. Anschließend melden sie sich über die URL bei der Host-Runtime an und fügen im Menüpunkt Slaves über <add new Device> das entsprechende Board hinzu. Als Einstellung ist unter anderem erforderlich, ob das Target-Gerät über einen seriellen Port (USB) oder über TCP erreichbar ist. Im ersteren Fall verbindet sich der Host mit dem Target über Modbus RTU, andernfalls über Modbus TCP. Bei Modbus RTU sind noch die Baudrate, die serielle Schnittstelle oder COM-Port des Hosts und die Slave ID anzugeben. Verfügt das Board über TCP, also einen Ethernet- oder WiFi-Anschluss, kann stattdessen Modbus TCP zum Einsatz kommen. Angeben müssen wir dann unter anderem die IP-Adresse des gewünschten Slaves.

Die OpenPLC-Runtime des Hosts bildet die I/O-Ports des als Slave angeschlossenen Boards gemäß oberem Adressierungsschema in Host-eigene Adressen ab: zum Beispiel auf %IX100.0 bis %I100.3, sofern das Board vier digitale Ports anbietet, oder entsprechend auf %QX100.0 bis %QX100.5 bei Verfügbarkeit von sechs digitalen Ausgabeports – ähnliches gilt für analoge Eingabe- und Ausgabeports. Bei Anschluss eines weiteren Boards, mit beispielsweise vier digitalen Eingabe-Anschlüssen, setzt OpenPLC einfach die Nummerierung auf dem Host fort, etwa mit %IX100.4 bis %IX100.7. Ein auf der Host-Runtime ablaufendes Programm kann diese Adressen dann transparent wie eigene Eingänge und Ausgänge nutzen, um I/O-Operationen auf dem Target durchzuführen. Der Mikrocontroller, genauer gesagt die auf ihm laufende Runtime, unterstützt somit eine Erweiterung des Hosts mit I/O-Schnittstellen.

Keine PLC unterstützt jede erdenkliche Sensorik- oder Aktorik-Hardware, etwa alle weltweit verfügbaren Sensoren. Gehört zum Beispiel ausgerechnet der in einem Projekt benötigte Sensor mangels Treiber nicht zu den unterstützten Komponenten einer PLC, so erweist sich dies bei kommerziellen PLCs unter Umständen als echtes Problem. Dort sind die Treiber meistens fest integriert, also durch Nutzer nicht änderbar.

Für Runtime-Instanzen auf Windows, macOS oder Linux/Raspberry Pi hat OpenPLC eine Lösung für dieses Problem geschaffen. Entsprechende PSM-Treiber (PSM = Python SubModule) lassen sich dort in der OpenPLC-Runtime unter dem Menüpunkt Hardware selbst erstellen. Als Programmiersprache ist dafür – nomen est omen – Python ab Version 3 notwendig.

Ein solcher Treiber besteht aus drei Teilen: einer Initialisierungsmethode für die Hardware sowie einer Methode zum Update der Eingänge und einer zum Update der Ausgänge.

Da die OpenPLC-Runtime mit privilegierten Super-User-Rechten läuft, sollten die im Treiber benötigten Python-Bibliotheken auf macOS-, Linux- oder Raspberry-Pi-Umgebungen immer mit sudo pip3 install <Paketname> installiert werden.

Hier exemplarisch ein Code-Template, das sich in der OpenPLC-Runtime über einen Browser (Menüpunkt Hardware) nutzen lässt. Für Windows ist beispielsweise PSM für Windows zu selektieren und für Linux oder ein Raspberry-Pi-Board PSM für Linux.

# Importieren der notwendigen Bibliotheken:
import psm
import time
# ...

# Variablen:
# z.B. var_state = True
# ...

# Initialisierungsroutine
def hardware_init():
    # ...
    psm.start()
    
# Code zum Setzen von Inputs
def update_inputs(var_state):
    # z.B. psm.set_var("IX0.0", var_state)
    # ...
    
    
# Code zum Schreiben der Outputs:
def update_outputs():
    # z.B. a = psm.get_var("QX2.1")
    # ...
# Zyklische Hauptroutine
if __name__ == "__main__":
    hardware_init()
    while (not psm.should_quit()):
        #Inputs
        #PSM HeartBeat
            # ...
        else:
            # ...
        update_inputs(var_state)
        
        #Outputs
        # ...
        update_outputs()
        time.sleep(0.1) # PSM Zyklus Zeit einstellen
    psm.stop()

In einem PLC-Programm sind die Messungen des Sensors über im Treiber festgelegte Adressen als Variablen definierbar, etwa als eine Variable temp mit Adresse %QW0. Dadurch erlauben sie ein Einbringen dieser Messwerte in eigene Programme (-> Variablendefinition im OpenPLC-Editor).

Der PSM-Treiber läuft in einem eigenen Thread, um den Zyklen der Runtime nicht in die Quere zu kommen. Manche Sensorzugriffe können Sekunden dauern.

Dank PSM sind entsprechende Änderungen und Erweiterungen der OpenPLC-Runtime kein Problem mehr.

Einen Wermutstropfen gibt es jedoch. Wer auf einer OpenPLC-Runtime für Raspberry Pi einen PSM-Treiber integriert, ersetzt damit vollständig die von OpenPLC bereitgestellte Treiberunterstützung für GPIO-Pins. Darum müsste sich dann ebenfalls der PSM-Treiber kümmern.