Modbus-Kommunikation mit RaspberryPi und PyModbus

Wie man vielleicht bemerkt, beschäftige ich mich gerade mal wieder mit einem meiner Lieblingsgeräte, dem RaspberryPi, lange lagen die beiden Modelle hier herum und staubten ein, in der letzten Zeit müssen sie wieder viel über sich ergehen lassen.

Auf wemaflo.net schrieb ich schon einmal über den RaspberryPi und Modbus, der Artikel bietet aber nicht wirklich viel Mehrwert, daher habe ich mich entschlossen, ihn neu zu schreiben, statt ihn zu übernehmen. Los geht’s!

Ich habe also:

  • Einen RaspberryPi B+ V1.2 mit CODESYS-Laufzeit, welchen ich als Controller benutze (Installation ist hier beschrieben)
  • Einen RaspberryPi B V1, welchen ich als Modbus-Master nutze

Auf beiden Geräten läuft Debian bzw. Raspbian.

RaspberryPi B und RaspberryPi B+
RaspberryPi B und RaspberryPi B+

Zuerst installieren wir auf dem Modbus-Master den Python-Paketinstaller easy_install:

wget https://bootstrap.pypa.io/ez_setup.py -O - | python

Danach installieren wir noch build-essential (vermutlich schon vorhanden) und das Dev-Paket von Python 2.7:

apt-get install build-essential python2.7-dev

Nun fehlt noch das tatsächliche Modbus-Programm, welches wir nun über easy_install installieren (was einen Moment dauern kann):

easy_install -U pymodbus

Nun fehlt noch ein Python-Programm, welches die PyModbus-Bibliothek nutzt. Ich habe hier ein einfaches Beispielprogramm geschrieben, welches einen Inputwert abfragt und diesen dann so lange per Modbus auf den Slave schreibt, bis es mit Enter abgebrochen wird (die IP-Adresse des Modbus-Slave muss natürlich angepasst werden):

#!/usr/bin/env python
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
import thread, time

def input_thread(L):
        raw_input()
        L.append(None)

def do_write_modbus():
        L = []
        thread.start_new_thread(input_thread, (L,))

        #Modbus-Slave
        RPiCODESYS = ModbusClient(host = '192.168.178.123', port=502)
        write_value = input ('Inputvalue: ')
        loop = input ('Loop starten: ')
        write_register = 0

        while 1:
                time.sleep(.1)
                if L: break
                RPiCODESYS.write_register(write_register, write_value)

do_write_modbus()

Herunterladen: Python-Script: Modbustest

Dieses Programm kann nun mit python ausgeführt werden (python modbustest.py).

Ohne Modbus-Slave auf der Gegenseite hilft das aber wenig, wir benötigen noch einen Beweis, dass alles funktioniert.
Unter CODESYS 3 sollten wir nun also ein neues Projekt erstellen, in meinem Falle wieder mit dem RaspberryPi als Zielsystem. Per Rechtsklick auf das Device kann nun ein weiteres Gerät angehängt werden, hier wählen wir den Ethernet-Adapter.

Gerät an den RaspberryPi anhängen
Gerät an den RaspberryPi anhängen

Per Rechtsklick auf den neuen Ethernet-Adapter hängen wir nun noch das Modbus TCP Slave Device an.

Modbus Slave Device an den Ethernet-Adapter anhängen
Modbus Slave Device an den Ethernet-Adapter anhängen

Nun schreiben wir eine Variable in unser Standard-Programm PLC_PRG, um an dieser nachher die über Modbus geschriebenen Werte sehen zu können:

Variable wModbusInput in PLC_PRG einfügen
Variable wModbusInput in PLC_PRG einfügen

Auf diese Variable können wir nun unseren Modbus-Input mappen. In das entsprechende Menü gelangen wir durch einen Doppelklick auf den Modbus TCP Slave:

Modbus-Input auf wModbusInput mappen
Modbus-Input auf wModbusInput mappen

Nun muss nur noch die Verbindung mit dem Controller hergestellt werden. Hierzu öffnen wir per Doppelklick auf den RaspberryPi (Device CODESYS Control for Raspberry Pi) das entsprechende Menü und geben dort die IP des Gerätes ein. Mit Enter wird die IP übernommen und die Verbindung überprüft.

CODESYS mit RaspberryPi verbinden
CODESYS mit RaspberryPi verbinden

Per Klick auf das Zahnrad (oder Alt + F8) loggen wir uns auf dem Gerät ein und starten das Programm mit F5. Nun können wir im PLC_PRG in Quasi-Echtzeit unsere Eingaben aus modbustest.py sehen.

modbustest.py schreibt Daten auf CODESYS-Slave
modbustest.py schreibt Daten auf CODESYS-Slave

Jetzt bin ich gespannt: Funktioniert bei euch auch alles (wenn nein helfe ich gerne) und wofür benutzt ihr das ganze?