In diesem Tutorial wird erklärt, wie man über TCP/IP die aktuelle I/O Beschaltung eines RS485 Moduls abfragt.
Folgende Komponenten wurden dafür verwendet:
- EX9133C-RS485 - Ethernet zu 1 • RS485/RS422 Konverter
- EX-9044D - 4 Kanal isolated digital input, 8 Kanal isolated open collector output RS485 module
Dieses Script kann mit kleinen Änderungen auch dazu benutzt werden, andere Module auszulesen oder zu konfigurieren.
Vorbereitende Maßnahmen
Stellen Sie sicher, dass Sie die Scriptsprache Python auf Ihrem System/Datenlogger installiert haben. Auf vielen linuxbasierten Systemen ist diese bereits vorinstalliert.
Die Verbindung zum EX-9044D wurde über die Webschnittstelle des EX-9132 konfiguriert.
Anpassung der Konfiguration
Im konkreten Fall möchten wir die aktuelle Beschaltung des EX-9044D 10x im Abstand von 0,5 Sekunden von einem linuxbasierten System aus auslesen und in eine CSV-Datei mit dem Pfad /tmp/output.csv speichern.
Unser EX-9132 Ethernet zu 485 Konverter hat die IP-Adresse: 192.168.0.100 und den Port 100 und ist mit unserem EX-9044D Modul verbunden
In der Anleitung zu Modulen der EX-90xx Reihe auf Seite -26-
ist unsere Abfrage „Read Digital I/O Status“ näher beschrieben.
Der Befehl zum Auslesen ist hier mit $AA6 angegeben. Da dies hier unser einziges Modul ist, werden wir die Abfrage mit $006 durchführen.
Im Script geschieht das mit der Zeile: s.send('$006\r\n')
Mit dem Befehl s.recv(1024) erhalten wir die Antwort und damit die aktuelle Beschaltung des Moduls.
Die weiteren Befehle dienen lediglich dazu, den erhaltenen Wert auf die wesentlichen 16 Ports zu kürzen und von Hex nach Binär umzuwandeln.
So kann man erkennen wie der Entsprechende Port beschaltet ist, je nachdem ob das entsprechende Bit 1 oder 0 ist.
Zum Schluss wird dieser Wert mit einem Zeitstempel in der CSV-Datei abgelegt.
Ausführung
Wir speichern den angepassten Code in einer Datei, z.B. unter /home/user1/datenlogger.py.
Anschließend machen wir die Datei mit chmod +x /home/user1/datenlogger.py ausfürbar und führen sie mit /home/user1/datenlogger.py aus.
Sofern kein Fehler in der Konfiguration gemacht wurde, steht nun das gewünschte Ergebnis in /tmp/output.csv.
#!/usr/bin/python
import socket
import time
import datetime
import csv
## Konfiguration ##
host = "192.168.0.100"
port = 100
csvdatei = "/var/log/output.csv"
delay = 0.5
counts = 10
## Konfiguration ENDE ##
i=0;
writer = csv.writer(open(csvdatei, "a"))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
buffer=""
while i < counts :
s.send('$006\r\n')
time.sleep(0.5);
data = s.recv(1024).strip()[:-2]
data = int(data, 16)
data = bin(data)[2:]
writer.writerow([str(datetime.datetime.now()),(data)])
i=i+1
s.close
Example Thermocouple Type K
Thermocouple Type K Factor: 0.0418701
Temp
= Modbus_data * 1372 / 0x7FFF
= 435 * 1372 / 32768
= 435*0.0418701
= 18.21
Example RTD PT100
RTD PT100 Factor: 0.00305176
Temp
= Modbus_data * 200 / 65536 - 50
= 25500 * 200 / 65536 - 50
= 25500 * 0.00305176 - 50
= 27.82
Modbus example code
For more information see: pymodbus docs
from pymodbus.client.sync import ModbusTcpClientfactor = 0.00305176 # 200 / 65536 offset = 50
ipaddress = 192.168.100.100data = read_analog_input_registers(channel) temp = (data.registers[0] * factor) + offset value=round(temp, 2)
def read_analog_input_registers(channel, ipaddress): # Function Code 04 (04 hex) client = ModbusTcpClient(ipaddress) response = client.read_input_registers(channel.address, 1, unit=channel.device.deviceid) client.close() return response