GPIOs von einem RaspberryPi auf RevolutionPi

Mit den RevPiNet* Klassen, können wir über das Netzwerk auf das Prozessabbild zugreifen. Diese Funktion nutzen wir nun, um den Wert eines GPIO-Pins des Raspberry Pis in unserem Prozessabbild zu verwenden.

piCtory Konfiguration am Revolution Pi

Auf dem Revolution Pi legen wir ein virtuelles Device mit dem Namen virtrpi an, über das der Raspberry Pi mit dem Revolution Pi Daten austauscht. Den ersten Input nennen wir inputbyte1

Virtuelles Device virtrpi mit Positionsnummer 64
Erster INP auf virtrpi mit dem Namen inputbyte1.

Über das virtuelle Device können alle Programme, die das Prozessabbild verwenden, auf die Daten zugreifen. Ob es sich dabei um ein Steuerungsprogramm in Python3 mit RevPiModIO oder logi.CAD handelt, spielt keine Rolle! Auch Visualisierungslösungen, welche das Prozessabbild verwenden, erhalten Zugriff auf die Daten.

RevPiPyLoad auf dem Revolution Pi

Damit ein System mit RevPiNetIO über das Netzwerk auf das Prozessabbild zugreifen kann, muss RevPiPyLoad (ab Version 0.6.5) auf dem Revolution Pi installiert sein! [Installationsanleitung]

Nach der Installation muss die RevPiPyLoad-Konfiguration angepasst werden. Besonders wichtig ist ein Wert der Konfigurationsdatei /etc/revpipyload/revpipyload.conf, welche wir über SSH oder direkt am Revolution Pi bearbeiten.

pi@RevPi ~/ $ sudo nano /etc/revpipyload/revpipyload.conf
[DEFAULT]
(...)

[PLCSERVER]
plcserver = 0
(...)

Für die Aktivierung des Netzwerkzugriffs auf das Prozessabbild muss der Parameter plcserver auf 1 gesetzt werden!

Sehr wichtig ist auch die Datei /etc/revpipyload/aclplcserver.conf, über die die Zugriffsberechtigung auf das Prozessabbild gesteuert wird.
Jede Zeile der Datei hat folgende Syntax: IPADRESSE,RECHT
(mehrere dieser Berechtigungen werden durch eine neue Zeile getrennt)

  • IPADRESSE
    Einzelne IP-Adresse oder mit Platzhalter definierte Gruppen:
    192.168.178.10 -> Nur der eine Rechner
    192.168.178.* -> Alle Rechner, bei denen die IP mit 192.168.178. beginnt
  • RECHT
    0 = Nur lesen
    1 = Lesen und schreiben

Beispiel:

# PLC-SERVER Access Control List (acl)
# One entry per Line IPADRESS,LEVEL
#
192.168.178.*,0
192.168.178.10,1

Alle Rechner im Netz 192.168.178.xxx haben lesenden Zugriff, der Rechner mit IP 192.168.178.10 hat lesenden und schreibenden Zugriff.

Nach der Änderung muss die Datei gespeichert und der Dienst neu gestartet werden:

pi@RevPi ~/ $ sudo systemctl restart revpipyload

Alle weiteren Parameter sind HIER aufgeführt.

Raspberry Pi vorbereiten

Als erstes müssen wir das RevPiModIO2 Modul auf dem Raspberry Pi installieren. Dies können wir wie hier beschrieben oder über pip3 erledigen.

pi@raspberrypi:~ $ sudo pip3 install revpimodio2

Den ersten Test können wir nun vom Raspberry Pi vornehmen. Zu beachten ist, dass kein anderes Steuerungsprogramm auf dem Revolution Pi läuft, da wir den exklusiven Modus verwenden!
Hinweis: Die IP-Adresse muss natürlich auf euren Revolution Pi angepasst werden!!!

pi@raspberrypi:~ $ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04)                                                                                                                                                                                                                                  
[GCC 6.3.0 20170124] on linux                                                                                                                                                                                                                                                  
Type "help", "copyright", "credits" or "license" for more information.                                                                                                                                                                                                         
>>> import revpimodio2                                                                                                                                                                                                                              
>>> rpi = revpimodio2.RevPiNetIO("192.168.50.36", autorefresh=True)                                                                                                                                                                                                
>>> rpi.core.temperature
49                                                                                                                                                                                                                                                                             
>>> rpi.io.inputbyte1.value
0                                                                                                                                                                                                                                                                              
>>> rpi.disconnect()                                                                                                                                                                                                                                                           
>>> exit()

Sollte die Ausgabe so aussehen, ist der Test erfolgreich!

Raspberry Pi programmieren

Mit dem Raspberry Pi wollen wir nun Daten in die INPUTS des virtuellen Devices schreiben. Damit dies möglich ist (in Inputs schreiben) verwenden wir RevPiNetIODriver(...).

# -*- coding: utf-8 -*-
"""Dieses Programm sendet den Status der GPIO Pins an den Revolution Pi."""
import revpimodio2
from RPi import GPIO


def cyclefunc(ct):
    """Zuklusfunktion, welche vom cycleloop() zyklisch aufgerufen wird."""
    # Den Wert vom GPIO Pin 13 in den IO pin13 schreiben
    rpi.io.pin13.value = GPIO.input(13)


def endfunc():
    """Setzt alle Werte des virtuellen Device auf 0/False bei Programmende."""
    rpi.setdefaultvalues()


# Setup GPIO on RaspberryPi
GPIO.setmode(GPIO.BCM)
GPIO.setup(13, GPIO.IN)

# Setup RevPiModIODriver() für virtuelles Device 'virtrpi'
rpi = revpimodio2.RevPiNetIODriver(
    "192.168.50.36", "virtrpi", autorefresh=True
)

# Auf das Bit 0 des "inputbyte1" von unserem virtuellen Device registrieren wir
# einen "Eingang" mit dem namen "pin13".
# Da wir ein Treiber sind (RevPiNetIODriver) können wir in Eingänge schreiben!
rpi.io.inputbyte1.replace_io("pin13", "?", bit=0)

# Programm sauber beenden, wenn SIGINT oder SIGTERM gesendet wird
rpi.handlesignalend(endfunc)

# Bei einem Kommunikationsfehler das virtuelle Device auf 0 setzen!
rpi.net_setdefaultvalues()

# Zyklische Verarbeitung starten
print("Starte cycleloop()")
rpi.cycleloop(cyclefunc)

# Nach Beenden des cycleloop vom Revolution Pi trennen
rpi.disconnect()

# GPIO aufräumen
GPIO.cleanup()

Dieses Programm erzeugt eine Instanz von RevPiNetIODriver(...). Als Übergabeparameter geben wir die IP-Adresse des Revolution Pi und den Namen des virtuellen Devices an, welches unsere Treiberinstanz verwenden soll.

Da wir die GPIO Werte als BITs speichern wollen, können wir auf unserem inputbyte1 bis zu 8 BIT-IOs registrieren. Über rpi.io.inputbyte1.replace_io("pin13", "?", bit=0) registrieren wir einen neuen BIT-IO mit dem Namen pin13, welchen wir dann direkt über rpi.io.pin13 ansprechen können.

Da wir ein Treiber sind, können wir in Inputs schreiben und Outputs nur lesen!

WICHTIG: Mit rpi.net_setdefaultvalues() weisen wir den Revolution Pi an, alle Eingänge das virtuellen Device auf Standardwerte (normalerweise 0) zu setzen, sollte die Verbindung unterbrochen werden! Dies ist sehr wichtig, da im Falle eines Verbindungsabbruch sonst die gesetzten Eingänge ihren Status beibehalten würden! Sollte dieses Verhalten gewünscht sein, lässt man den Aufruf einfach weg.

Danach rufen wir rpi.cycleloop(cyclefunc) auf und das RevPiModIO führt zyklisch (Standard alle 50 Millisekunden) die Funktion cyclefunc(ct) aus. Diese Funktion ließt den aktuellen Status True / False des GPIO Pin 13 aus und schreibt den Wert in unseren Input pin13.

Auf dem Revolution Pi ist dieser Wert nun verfügbar!

Optional: Steuerungsprogramm auf dem Revolution Pi

Auf dem Revolution Pi führen wir folgendes Programm aus.

# -*- coding: utf-8 -*-
"""Beispielprogramm um auf Daten des Raspberry Pi zuzugreifen."""
import revpimodio2


def evt_raspberry(ioname, iovalue):
    """Eventfunktion fuer Datenaenderung des Raspberry Pi."""
    # Eine Zeile mit aktuellem Wert ausgeben
    print("Input: {} - Value: {}".format(ioname, iovalue))


# RevPiModIO Instanz erzeugen
rpi = revpimodio2.RevPiModIO(autorefresh=True)

# Auf das Bit 0 des "inputbyte1" von unserem virtuellen Device registrieren wir
# einen "Eingang" mit dem namen "pin13".
rpi.io.inputbyte1.replace_io("pin13", "?", bit=0)

# Für den neuen Eingang registrieren wir ein Event.
rpi.io.pin13.reg_event(evt_raspberry)

# Programm sauber beenden, wenn SIGINT oder SIGTERM gesendet wird
rpi.handlesignalend()

# Eventüberwachung starten und auf Events reagieren
print("mainloop()")
rpi.mainloop()

Wir erstellen auch hier einen neuen Eingang pin13 auf dem Bit 0 des Eingangs inputbyte1.

Im Anschluss registrieren wir mit rpi.io.pin13.reg_event(evt_raspberry) ein Event, welches bei Wertänderung die Funktion evt_raspberry(ioname, iovalue) ausführt. Die Funktion schreibt dann einfach den IO Namen und aktuellen Wert in die Ausgabe.

mainloop()
Input: pin13 - Value: True
Input: pin13 - Value: False
Input: pin13 - Value: True