Die Heimautomatisierung mit speicherprogrammierbarer Steuerung (SPS)
Die Programmierung speicherprogrammierbarer Steuerungen führte in der Softwareentwicklung bislang ein Nischendasein. Die entsprechenden Steuerungen wurden hauptsächlich im industriellen Umfeld verwendet und waren, zusammen mit den notwendigen I/O-Modulen, relativ teuer. Nun rücken Automatisierungsprodukte gerade im Smart-Home-Bereich stärker in den technischen Fokus.
- Wolfgang Klimt
Die Programmierung speicherprogrammierbarer Steuerungen (SPS) führte in der Softwareentwicklung bislang ein Nischendasein. Die entsprechenden Steuerungen wurden hauptsächlich im industriellen Umfeld verwendet und waren, zusammen mit den notwendigen I/O-Modulen, relativ teuer. Mit dem Aufkommen des Internet der Dinge rücken Automatisierungsprodukte gerade im Smart-Home-Bereich stärker in den technischen Fokus.
Der Beitrag erläutert den Einsatz und die Programmierung einer SPS-Lösung für die Steuerung der Beleuchtung, Fußbodenheizung, Jalousien und einen Teil eines Aquariums in einem intelligenten Einfamilienhaus. Die Anwendung hat der Autor dieses Beitrags im Rahmen seines Hausbaus eingeführt und programmiert.
Einsatz einer SPS-Lösung für ein Smart Home
Im gewerblichen Gebäudesektor werden speicherprogrammierte Steuerungen aufgrund ihrer Vielseitigkeit und Robustheit seit vielen Jahren gerne eingesetzt. Die Nutzung ist allerdings mit hohen Kosten verbunden, was sie für den privaten Einsatz nachteilig machte. Einige Hersteller von SPS-Programmiersystemen haben nun den Raspberry Pi als Plattform für sich entdeckt und bieten eine entsprechende Unterstützung. Das macht die SPS-Programmierung auch für den privaten Bereich attraktiv. Zwar genügt die Raspberry-Plattform nicht den harten Echtzeitanforderungen, die im Bereich der Industrieanlagensteuerung existieren. Aber ein Jitter im Bereich von 50 bis 400 Mikrosekunden, wie ihn zum Beispiel 3S-Software für die eigene Codesys-Raspberry-Implementierung angibt, ist für viele Anwendungen im Smart-Home-Bereich ausreichend.
Da IO-Bausteine für die Raspberry-Bus-Systeme I2C und SPI im Elektronik-Fachhandel für wenig Geld erhältlich sind, prädestinieren sie den Pi für zahlreiche kleinere Automatisierungsaufgaben. Das Codesys-Programmiersystem ist nach der Registrierung kostenlos verfügbar und umfasst einen Simulator, der die Ausführung der Programme auch ohne Vorhandensein eines Zielsystems erlaubt. Die hier vorgestellten Programme und Funktionen sind unter Verwendung dieses Simulators entstanden.
Die von 3S-Software angebotene Raspberry-Laufzeitumgebung funktioniert im kostenlosen Demo-Modus zwei Stunden lang. Für die unbeschränkte Laufzeit ist eine Lizenz fällig, die an das Gerät gebunden ist und derzeit 35 Euro kostet. Im Download-Paket befinden sich sowohl eine um die Codesys-Komponenten erweiterte Raspbian-Umgebung für das Aufsetzen eines Neugeräts als auch ein Debian-Paket, das sich auf einem bereits konfigurierten Raspberry Pi einfach installieren lässt. Letzteres war im vorliegenden Fall allerdings mit einem kleinen Problem verbunden: Das installierte Programm /usr/bin/codesyscontrol.bin ist dynamisch gelinkt und erwartet eine Shared Lib unter [/lib/ld-linux-armhf.so.3. Diese existierte in der entsprechenden Raspbian-Distribution nicht, sodass sich das Programm nicht starten ließ. Ein
cd /lib; ln -s arm-linux-gnueabi/ld-2.13.so ld-linux-armhf.so.3
als Benutzer "root" löste das Problem.
SPS: Standards und Struktur
FĂĽr die SPS-Programmierung existiert seit vielen Jahren ein Standard: die IEC-Norm 61131. Sie definiert insgesamt fĂĽnf Programmiersprachen, drei davon grafisch, zwei textbasiert. Im vorliegenden Anwendungsbeispiel hat sich der Autor auf die textbasierte Sprache ST (strukturierter Text, structured text) und die grafische Sprache FB (Funktionsblock, function block) konzentriert.
In der SPS-Programmierung unterscheidet man zwischen den Konstrukten PROGRAM, FUNCTION und FUNCTION_BLOCK. Letztere beiden dienen zur Definition wiederverwertbarer Bausteine. FUNCTION ist zustandsfrei und entspricht dem klassischen Funktionsbegriff aus der herkömmlichen Programmierung, während FUNCTION_BLOCK Variablen umfassen darf, deren Inhalt über mehrere Aufrufe hinweg erhalten bleibt und der daher über einen inneren Zustand verfügt. Ein PROGRAM fasst Funktionen und Funktionsblöcke zu einer Einheit zusammen, die in der SPS ausgeführt wird und damit ihr Verhalten festlegt.
Für Entwickler, die mit Hochsprachen wie Pascal, C oder objektorientierten Sprachen vertraut sind, bedeutet die SPS-Programmierung eine gewisse Umstellung. Das eigene Programm wird in ein Laufzeitsystem der SPS eingebettet und von diesem zyklisch aufgerufen. Datenwerte im Speicher repräsentieren dabei Ein- und Ausgänge der an den Controller angeschlossenen I/O-Bausteine. Stellt beispielsweise ein Baustein digitale Eingänge zur Verfügung, wird der Zustand eines jeden Eingangs als ein bestimmtes Bit im Speicher der SPS dargestellt. Ein Baustein mit digitalen Ausgängen wird entsprechend durch das Setzen der korrespondierenden Bits auf "0" oder "1" angesteuert. Diese Bits lassen sich auch lesen und damit ebenfalls in der Programmlogik verwenden.
Ein schreibender Zugriff auf Eingänge durch das Programmiersystem wird typischerweise unterbunden. Zu beachten ist dabei: Die Übertragung der Daten vom Baustein in den Speicher der SPS erfolgt zu Beginn eines jeden Zyklus durch das Laufzeitsystem. Das Setzen der Ergebniswerte in den IO-Bausteinen findet am Ende eines jeden Zyklus statt. Erzeugt also ein Programm innerhalb eines Zyklus unterschiedliche Werte für einen Ausgang, wird nur der letzte davon tatsächlich an den Baustein übertragen.
Entwickler stellen sich am besten um das eigene Programm herum eine Endlosschleife der folgenden Art vor:
while true
{
sleep x ms
read IO values from bus
program execution
write output values to bus
}
Die Laufzeit des PROGRAM-Blocks sollte dabei möglichst kurz sein, da ja erst nach seiner Abarbeitung tatsächlich das Ergebnis an den angeschlossenen Bausteinen sichtbar wird. Aufgaben, die mehrere Schritte oder das Warten auf ein externes Ereignis oder einen bestimmten Zeitpunkt enthalten, sind in einzelne Schritte zu zerlegen. Dies muss so erfolgen, dass in einem Zyklus immer nur der Schritt ausgeführt wird, der gerade tatsächlich zur Ausführung ansteht. Das erfordert gelegentlich ein etwas aufwendiges internes Zustandsmanagement, insbesondere wenn komplexe Kommunikationsprotokolle zu befolgen sind.