[Gelöst:] Hilfe zu Modbus RS485 Programierung

Begonnen von DJ-Mix, 11 Juli 2016, 12:51:37

Vorheriges Thema - Nächstes Thema

DJ-Mix

Hallo zusammen,

ich benötige Hilfe zu einer Modbus RS485 Schnittstelle.

Mein gerät: Salzelektrolyse Steuerung mit RS 485 (5-Pin Connector siehe Anhang)
Mein Ziel: Auslesen der Register und Aufbereitung/Schaltung über FHEM

Leider habe ich keinerlei Programmierkenntnisse   auf diesem Gebiet. Ist vielleicht jemand so nett und kann mir helfen, auch bezüglich
der benötigten Hardware ,welche ich verwenden sollte?

Modbus Register liegen vor.

Vielen dank vorab

Gruß
DJ-Mix

tante ju

Zitat von: DJ-Mix am 11 Juli 2016, 12:51:37
Hallo zusammen,

ich benötige Hilfe zu einer Modbus RS485 Schnittstelle.

Mein gerät: Salzelektrolyse Steuerung mit RS 485 (5-Pin Connector siehe Anhang)
Mein Ziel: Auslesen der Register und Aufbereitung/Schaltung über FHEM

Leider habe ich keinerlei Programmierkenntnisse   auf diesem Gebiet. Ist vielleicht jemand so nett und kann mir helfen, auch bezüglich
der benötigten Hardware ,welche ich verwenden sollte?

Modbus Register liegen vor.

Ist ein wenig schwierig, da die Infos ein wenig mau sind.
RS485 kann als Halb-Duplex (2-Draht) oder Voll-Duplex (4-Draht) ausgelegt sein. Dann wird oft auch eine Versorgungsspannung mitgeführt (2-Draht), manchmal auch nur eine Gerätemasse (1-Draht), obwohl es da durchaus kontroverse Diskussionen über den Nutzen gibt.

Da Du 5 Kontakte hast, könnte das also eine Voll-Duplex Verbindung mit Gerätemasse sein. Das gäbe 5 Kontakte. Es könnte aber auch Halb-Duplex, mit Versorgungsspannung und doppelter Masse sein usw. usf.

Diese Details müsstest Du rausbekommen. Sonst müsste man das Durchmessen, was ein wenig Gerätschaften erfordert.

Ist das geklärt, dann wird wichtig, welche Baudrate verwendet wird. Obwohl man das relativ einfach testen kann.

Hast Du das alles, dann brauchst Du einen entsprechenden RS485 Adapter für Deinen Computer, der das unterstützt, was Du brauchst.

Der Rest ist dann ziemlich einfach, da FHEM ja schon eine MODBUS Implementierung hat.

DJ-Mix

vielen Dank erstmal.
Werde die Informationen besorgen.

Laut Register Übersicht:


tante ju

Zitat von: DJ-Mix am 12 Juli 2016, 13:01:02
habe weitere Informationen:

- Baudrate 19200
- halb Duplex
- gnd / -(B) / +(A)
- keine Versorgungsspannung

Adapter würde ich so einen nehmen:
http://www.ebay.de/itm/like/Digitus-DA-70157-Seriell-Adapter-USB-2-0/201583186437?hlpht=true&ops=true&viphx=1&_trksid=p2050601.c100103.m2451&_trkparms=aid%3D111001%26algo%3DREC.SEED%26ao%3D1%26asc%3D20150422114059%26meid%3Dca46de1fd079462d94b21e4efa06170a%26pid%3D100103%26rk%3D1%26rkt%3D4%26sd%3D201583186437%26clkid%3D6767854574877802900&_qi=RTM2266087

Das ist doch mal was. Jetzt musst Du nur noch rausbekommen, auf welchen der 5 Pins jeweils welches Signal liegt.
Der Adapter, den Du hast, ist aber normal seriell. Für RS485 brauchst Du sowas: http://www.ebay.de/itm/USB-auf-RS485-Adapter-RS-485-USB-Adapter-Konverter-Seriell-Adapter-Arduino-108-/121974380677?hash=item1c663d5885:g:M~8AAOSwbwlXASTQ

(keine Ahnung, ob der auch unter Linux läuft, würd mich aber wundern wenn nicht)

Danach in FHEM in den MODBUS definieren, dann darauf das Device mit den Registern.
Also, so etwa:

define ModBusLine Modbus /dev/ttyAMA0@19200
define MeinDevice ModbusAttr 1 10
attr MeinDevice obj-c1-poll 1
attr MeinDevice obj-c1-reading IO1
attr MeinDevice obj-c1-set 1


Hier wird ein Modbus auf AMA0 (das ist beim RPi der eingebaute serielle, also bei Dir dann sicher was anderes) mit 19200 Bit/s definiert und dann ei Device "MeinDevice" angelegt mit Adresse 1 und 10 Sekunden Pollrate.
Auf diesem Device ei Register vom Typ coil (also quasi Relais) mit Adresse 1 angelegt, welches gelesen (poll) wird und auch geschrieben werden kann (set) und als reading "IO1" erscheint.
Das muß man natürlich entsprechend Deinem Device anpassen.

DJ-Mix

den USB Adapter hatte ich auch ins Auge gefasst, jedoch benötige ich gnd / + / -
und der von Dir ausgesuchte USB hat nur + / -
Belegung auf der Platine ist von unten nach oben: gnd / + / - / frei / 24V

Sobald alles da ist, werde ich mal testen und einen 2 Raspi (mit FHEM2FHEM) anschließen.

Wie lege ich den das Register an? Habe als Anhang mal die Übersicht beigefügt.


tante ju

Zitat von: DJ-Mix am 13 Juli 2016, 08:44:46
den USB Adapter hatte ich auch ins Auge gefasst, jedoch benötige ich gnd / + / -
und der von Dir ausgesuchte USB hat nur + / -
Belegung auf der Platine ist von unten nach oben: gnd / + / - / frei / 24V

Sobald alles da ist, werde ich mal testen und einen 2 Raspi (mit FHEM2FHEM) anschließen.

Wie lege ich den das Register an? Habe als Anhang mal die Übersicht beigefügt.

Je nach Kabellänge ist GND wichtig oder auch nicht. Aber GND kannst Du auch vom USB nehmen oder von der Spannungsversorgung. Dazu brauchst Du keinen anderen RS485 Adapter.

In der Anleitung fehlt, welchen Typ die Register haben.
Bei Modbus gibt es verschiedene Typen und innerhalb derer dann die Adressen. Das sind also eigene Adressräume pro Typ. Ich vermute mal, es sind Holding-Register.

Dann kannst Du das erste 0x0100 mit

define MeinDevice ModbusAttr 1 10
attr MeinDevice obj-h256-reading Wert1
attr MeinDevice obj-h256-poll 1

anlegen.

Also das Device mit define anlegen, dabei Modbus-Adresse (1) und Poll-Zyklus (10 Sekunden) angeben.

Mit dem ersten attr wird dann durch das h256 angegeben, Holding, Adresse 256 (also 0x0100) and als Reading "Wert1" festgelegt. Das zweite attr veranlasst dann, daß dieser Wert gelesen wird. Du solltest dann also kurze Zeit später im Device ein Reading "Wert1" sehen, mit dem aktuellen Wert von Register 0x0100.

Wenn da nix kommt, dann müsstest Du selbiges mal i anstelle h für Input probieren.

DJ-Mix

ok, das mit der Kabellänge wusste ich nicht - so Long - habe den von mir ausgesuchten Adapter bestellt :-)
(falls es nicht klappt - kann ich den von Dir vorgeschlagenen ja nachbestellen)

das mit den Registern verstehe ich leider nicht.

wie kommst du auf die h256? dies finde ich in der Übersicht nicht . . . .
(habe mal den Anfang von Measure Register angehangen)
hier sind die Dinge, die mich als erstes Interessieren . .
aufgebaut nach 0x0100 / 0x0101 / 0x0102 / etc. diese möchte ich gerne in FHEM darstellen
im weiteren Verlauf gibt es dann noch eine Unterteilung der Description nach Bits - wie stelle ich diese dar.

Sorry für so viele Fragen, aber kann mir im Moment leider keinen Reim darauf machen, wie diese Register aufgebaut werden.
Und nochmals Vielen dank für deine Hilfe.




DJ-Mix

#8
ok, gerade noch was rumgesurft im I-Net und prompt die Lösung für
die 256 gefunden (Hex nach Dez Umrechnung).
Und wieder was schlauer geworden  :)

bleibt noch die Unterteilung der Bits . . . .


würde das so funktionieren???
define ModBusLine Modbus /dev/ttyUSB0@19200 # USB Adapter
define Saltlange ModbusAttr 1 10 # Abfragezeit 10sec
attr Saltlange obj-h256-poll 1 # Auto Abfrage
attr Saltlange obj-h256-reading ION # 1 Register "ION"
attr Saltlange obj-h258-poll 1 # Auto Abfrage
attr Saltlange obj-h258-reading pH / 100 # 2 Register "pH" geteilt durch 100
attr Saltlange {sprintf("%.1f", ReadingsVal($name,"pH",0))}        # Format Reading pH 0.00



pc1246

Moin DJ
Die Bits sind genauso einfach! 400 hex gibt das 10. Bit! Nimm den Windofs taschenrechner, stell Ihn auf Programmierer um, und schon hast Du alles!
Gruss Christoph
HP T610
Onkyo_AVR;Enigma2; SB_Server; SB_Player; HM-USB; PhilipsTV; harmony hub; Jeelink mit PCA301; Somfy; S7-300; LGW; HUE; HM-IP auf Charly; div

DJ-Mix

noch ne Frage zu den Bits . . .

gebe ich diese dann so an?
attr Saltlange obj-h1-reading pH-high    #bit 1 hex 0x000F "Alarm Code"

pc1246

Nein
Das Register ist 0x0107, und es sind mehrere Bits! "F" in hex sind die Bits 0-3, also 4! Das mask in der Tabelle meint, das Du diese Maske brauchst, um die entsprechenden Informationen zu erhalten. Das Register 0x0107 hat insgesamt 16 Bits! Da ich aber mit Modbus nur ganz kuez rumgespielt habe, kann ich Dir die genaue Definition nicht sagen!
Gruss Christoph
HP T610
Onkyo_AVR;Enigma2; SB_Server; SB_Player; HM-USB; PhilipsTV; harmony hub; Jeelink mit PCA301; Somfy; S7-300; LGW; HUE; HM-IP auf Charly; div

DJ-Mix

Ok,mit den Bits muss ich mich dann noch auseinander setzen . . .

sollte mein Beispiel (leicht geändert) so funktionieren?
define ModBusLine Modbus /dev/ttyUSB0@19200 # USB Adapter
define Saltlange ModbusAttr 1 10 # Abfragezeit 10sec
attr Saltlange obj-h256-poll 1 # Auto Abfrage
attr Saltlange obj-h256-reading ION # 1 Register "ION"
attr Saltlange obj-h258-poll 1 # Auto Abfrage
attr Saltlange obj-h258-expr $val / 100 # Wert dividiert durch 100
attr Saltlange obj-h258-reading pH # 2 Register "pH"
attr Saltlange {sprintf("%.1f", ReadingsVal($name,"pH",0))}        # Format Reading pH 0.00

tante ju

Zitat von: DJ-Mix am 14 Juli 2016, 14:40:25
Ok,mit den Bits muss ich mich dann noch auseinander setzen . . .

sollte mein Beispiel (leicht geändert) so funktionieren?
define ModBusLine Modbus /dev/ttyUSB0@19200 # USB Adapter
define Saltlange ModbusAttr 1 10 # Abfragezeit 10sec
attr Saltlange obj-h256-poll 1 # Auto Abfrage
attr Saltlange obj-h256-reading ION # 1 Register "ION"
attr Saltlange obj-h258-poll 1 # Auto Abfrage
attr Saltlange obj-h258-expr $val / 100 # Wert dividiert durch 100
attr Saltlange obj-h258-reading pH # 2 Register "pH"
attr Saltlange {sprintf("%.1f", ReadingsVal($name,"pH",0))}        # Format Reading pH 0.00


Mit der letzten Zeile bin ich nicht glücklich.

Zu den Bits:
ein Reading liest, wie ja schon erklärt, den ganzen 16 Bit-Wert. Solltest Dich ein wenig mit der Bitdarstellung beschäftigen, wenn das folgende Dir nichts sagt.
Wenn Du also das Bit 7 haben möchtest (das ganz rechte wird normalerweise mit 0 bezeichnet, also ist 7 das 8te Bit von rechts, der entsprechende Hex-Wert wäre 0x80 oder in Dezimal 128), dann musst Du 7 mal nach rechts schieben und alle höheren Bits ausmaskieren.

Das würde man so machen:

attr Saltlange obj-h256-expr ($val >> 7) & 0x01


Das >> schiebt das Bitfeld nach rechts und das & ist eine bitweise UND Operation mit dem Wert 0x01, also nur Bit 0 gesetzt.

Wenn Du nur an Bit 0 möchtest, dann kannst Du Dir das schieben sparen und würdest direkt $val & 0x01 machen.

DJ-Mix

erst mal Vielen dank

letzte Zeile
attr Saltlange obj-h258 stateFormat {sprintf("%.1f", ReadingsVal($name,"pH",0))}

zu den Bits
heißt das ich jeweils um x nach recht schieben muss um an das Bit zu kommen welches ich benötige.
Also wenn ich Bit 16 sehen möchte muss ich attr Saltlange obj-h256-expr ($val >> 16) & 0x01 eingeben!?