RS 485 Modbus Kommunikation
- heiße Luft
 - Beiträge: 45
 - Registriert: 21.04.2009 12:04
 - Computerausstattung: Ausreichend. 3 Pc, 1 Laptop
BS: Win 7 (zum spielen),XP (weils noch da ist), Win 2000(laptop) und Linux (Umbuntu und Mint) - Wohnort: NRW
 
RS 485 Modbus Kommunikation
Hallo Leute,
ich habe wieder ein Hardware-Projekt bei dem ich nicht so recht weiss wie ich anfangen soll.
Ich habe einen Regler der Firma Gefran ( Typ 600) mit RS485 Schnittstelle bekommen. Als Protokoll wird MODBUS verwendet.
In meiner Elektronik Grabbelkiste habe ich noch einen ADAM Schnittstellen Konverter (RS485/RS232) gefunden.
Im Netz habe ich ein Konfigurations- Tool von Gefran gefunden. Damit konnte über den ADAM auf den Regler zugreifen. Die Hardware funktioniert also.
In Netz bieten etliche Firmen DLLs für die Kommunikation über Modbus mit ihren Geräten an. Auch kommerzielle allgemeine DLLs für die Modbus- Kommunikation habe ich gefunden.
Auch eine freie DLL habe ich gefunden, jedoch keine gute Beschreibung bisher (rxmod.dll).
Jetzt bin ich ein wenig verwirrt.
Ich dachte Modbus ist lediglich die Art (Reihenfolge) wie ich Anfragen über die RS232 schicke um eine bestimmte Antwort zu bekommen.
Hat jemand damit schon Erfahrungen gemacht?
Grüße hL
			
			
									
									ich habe wieder ein Hardware-Projekt bei dem ich nicht so recht weiss wie ich anfangen soll.
Ich habe einen Regler der Firma Gefran ( Typ 600) mit RS485 Schnittstelle bekommen. Als Protokoll wird MODBUS verwendet.
In meiner Elektronik Grabbelkiste habe ich noch einen ADAM Schnittstellen Konverter (RS485/RS232) gefunden.
Im Netz habe ich ein Konfigurations- Tool von Gefran gefunden. Damit konnte über den ADAM auf den Regler zugreifen. Die Hardware funktioniert also.
In Netz bieten etliche Firmen DLLs für die Kommunikation über Modbus mit ihren Geräten an. Auch kommerzielle allgemeine DLLs für die Modbus- Kommunikation habe ich gefunden.
Auch eine freie DLL habe ich gefunden, jedoch keine gute Beschreibung bisher (rxmod.dll).
Jetzt bin ich ein wenig verwirrt.
Ich dachte Modbus ist lediglich die Art (Reihenfolge) wie ich Anfragen über die RS232 schicke um eine bestimmte Antwort zu bekommen.
Hat jemand damit schon Erfahrungen gemacht?
Grüße hL
Wissen ist das einzige Gut das sich vermehrt wenn man es teilt!
						Re: RS 485 Modbus Kommunikation
Erfahrung: Nein
Infos:
==> http://de.wikipedia.org/wiki/Modbus
==> Modbus-Spezifikation über serielle Leitung (englisch), mit Data-Link Layer und physischem Layer (auch Steckerbelegung)
			
			
									
									Infos:
==> http://de.wikipedia.org/wiki/Modbus
==> Modbus-Spezifikation über serielle Leitung (englisch), mit Data-Link Layer und physischem Layer (auch Steckerbelegung)
Windows 10
PB Last Final / (Sometimes testing Beta versions)
						PB Last Final / (Sometimes testing Beta versions)
- heiße Luft
 - Beiträge: 45
 - Registriert: 21.04.2009 12:04
 - Computerausstattung: Ausreichend. 3 Pc, 1 Laptop
BS: Win 7 (zum spielen),XP (weils noch da ist), Win 2000(laptop) und Linux (Umbuntu und Mint) - Wohnort: NRW
 
Re: RS 485 Modbus Kommunikation
Hallo Helpy,
danke für die links. Habe ich natürlich selbst gefunden.
Mich verwunderte nur das viele Hersteller DLLs zur Kommunikation über Modbus für ihre Geräte anbieten.
Da es auch die erwähnte freie DLL gibt dachte ich, dass man das Ganze vereinfachen könnte und nicht alles „zu Fuß“ programmieren muß. Ich bin halt von Haus aus faul und möchte mir nicht mehr Arbeit machen als nötig. Für Tipps bin ich immer dankbar.
Viele Grüße hL
			
			
									
									danke für die links. Habe ich natürlich selbst gefunden.
Mich verwunderte nur das viele Hersteller DLLs zur Kommunikation über Modbus für ihre Geräte anbieten.
Da es auch die erwähnte freie DLL gibt dachte ich, dass man das Ganze vereinfachen könnte und nicht alles „zu Fuß“ programmieren muß. Ich bin halt von Haus aus faul und möchte mir nicht mehr Arbeit machen als nötig. Für Tipps bin ich immer dankbar.
Viele Grüße hL
Wissen ist das einzige Gut das sich vermehrt wenn man es teilt!
						Re: RS 485 Modbus Kommunikation
@heiße Luft
vielleicht wirst du hier fündig:
http://www.codeproject.com/info/search. ... tkw=modbus
oder hier:
http://sourceforge.net/search/?type_of_ ... rds=modbus
Grüße ... Kiffi
			
			
									
									vielleicht wirst du hier fündig:
http://www.codeproject.com/info/search. ... tkw=modbus
oder hier:
http://sourceforge.net/search/?type_of_ ... rds=modbus
Grüße ... Kiffi
a²+b²=mc²
						Re: RS 485 Modbus Kommunikation
Das Modbus-Protokoll ist wirklich kein geheimnis. Sollte ohne probleme in PB Programmiert werden können.
Der einzige Unterschied zwischen Modus und Modus-TCP ist, das bei TCP noch ein Header von 3 Worter (16bit) hat und das CheckByte nicht mit übertragen wird. Habe den quatsch schon mit einer Siemens SPS (Step7) selber programmiert.
Mit einen PC sollte es noch leichter gehen.
			
			
									
									Der einzige Unterschied zwischen Modus und Modus-TCP ist, das bei TCP noch ein Header von 3 Worter (16bit) hat und das CheckByte nicht mit übertragen wird. Habe den quatsch schon mit einer Siemens SPS (Step7) selber programmiert.
Mit einen PC sollte es noch leichter gehen.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
						Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: RS 485 Modbus Kommunikation
@heiße Luft
Das Modbus Protokoll ist wirklich kein Problem, habe das auch mal in einem Projekt von mir umgesetzt (auslesen der Messwerte aus einem SENTRON PAC 3000 von Siemens über Ethernet - MODBUS Protokoll). Wenn Du Interesse hast, kann ich Dir die Sourcen mal zukommen lassen.
Gruß, BI2
Edit: hier noch meine gesammelten Links zu dem Projekt (waren mir seinerzeit eine große Hilfe):
http://www.anybus.de/technologie/modbustcp.shtml
http://www.google.com/codesearch/p?hl=d ... dbus%20tcp
http://mbserver.tripod.com/
http://sites.google.com/site/plcsimulator/
http://www.modbus.org/
http://www.industry.siemens.com/industr ... us_tcp.htm
http://www.buildingtechnologies.siemens ... c3200.aspx
http://www.simplymodbus.ca/TCP.htm
http://www.ipsta.de/seiten_html/technologie_modbus.html
http://de.wikipedia.org/wiki/Modbus
			
			
									
									Das Modbus Protokoll ist wirklich kein Problem, habe das auch mal in einem Projekt von mir umgesetzt (auslesen der Messwerte aus einem SENTRON PAC 3000 von Siemens über Ethernet - MODBUS Protokoll). Wenn Du Interesse hast, kann ich Dir die Sourcen mal zukommen lassen.
Gruß, BI2
Edit: hier noch meine gesammelten Links zu dem Projekt (waren mir seinerzeit eine große Hilfe):
http://www.anybus.de/technologie/modbustcp.shtml
http://www.google.com/codesearch/p?hl=d ... dbus%20tcp
http://mbserver.tripod.com/
http://sites.google.com/site/plcsimulator/
http://www.modbus.org/
http://www.industry.siemens.com/industr ... us_tcp.htm
http://www.buildingtechnologies.siemens ... c3200.aspx
http://www.simplymodbus.ca/TCP.htm
http://www.ipsta.de/seiten_html/technologie_modbus.html
http://de.wikipedia.org/wiki/Modbus
PB 5.7x (x64), LinuxMint 18.3 - Xfce (x64)
Einsteigerbuch: PureBasic - Eine Einführung in die Computer Programmierung
						Einsteigerbuch: PureBasic - Eine Einführung in die Computer Programmierung
- heiße Luft
 - Beiträge: 45
 - Registriert: 21.04.2009 12:04
 - Computerausstattung: Ausreichend. 3 Pc, 1 Laptop
BS: Win 7 (zum spielen),XP (weils noch da ist), Win 2000(laptop) und Linux (Umbuntu und Mint) - Wohnort: NRW
 
Re: RS 485 Modbus Kommunikation
Hallo Leute,
sorry, das ich mich erst jetzt melde, aber ich war im Urlaub.
Jetzt geht es weiter.
@B12
oh ja, an Beispiel- Code bin ich sehr interessiert!
Ich habe auch noch eine schöne Website zum Thema gefunden.
 
http://pvbrowser.org/pvbrowser/sf/manua ... odbus.html
Grüße hL
			
			
									
									sorry, das ich mich erst jetzt melde, aber ich war im Urlaub.
Jetzt geht es weiter.
@B12
oh ja, an Beispiel- Code bin ich sehr interessiert!
Ich habe auch noch eine schöne Website zum Thema gefunden.
http://pvbrowser.org/pvbrowser/sf/manua ... odbus.html
Grüße hL
Wissen ist das einzige Gut das sich vermehrt wenn man es teilt!
						Re: RS 485 Modbus Kommunikation
Da ich jetzt schon ein paar Anfragen hatte Poste ich das ganze einfach mal hier:
Gruß, BI2
			
			
									
									Code: Alles auswählen
;/ SENTRON PAC3200 Viewer
;/ 13.09.2009 PureBasic 4.31
EnableExplicit
Global PRGName$   = "SENTRON PAC3200 Viewer"
Global Version$   = "1.0"
Global Copyright$ = "© 2009 ASW"
Enumeration ;Konstanten
	#frmHaupt
	#ListIcon_0
	#ToolBar_0
	#tlbInfo
	#tlbResetMin
	#tlbResetMax
	#StatusBar_0
EndEnumeration
;==================================================================================================
Global *Anfrage = AllocateMemory(12)
Global *Antwort = AllocateMemory(300)
Global Abfragecode
Global NewList Messgroessen.s()
Global NewList IPListe.s()
Global Dim Messwerte.f(0,0)
Global Leseintervall
Global Programmende
;- Images
Global ImgInfo   = CatchImage(1, ?info)
Global ImgRed    = CatchImage(3, ?red)
Global ImgGreen  = CatchImage(4, ?green)
Global ImgYellow = CatchImage(5, ?yellow)
Global ImgRmin   = CatchImage(6, ?rmin)
Global ImgRmax   = CatchImage(7, ?rmax)
DataSection ;info.ico   hat eine Länge von 318 Bytes
	info:
	Data.b $00, $00, $01, $00, $01, $00, $10, $10, $00, $00, $01, $00, $04, $00, $28, $01
	Data.b $00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $10, $00, $00, $00, $20, $00
	Data.b $00, $00, $01, $00, $04, $00, $00, $00, $00, $00, $80, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $80, $00, $00, $00, $00, $80, $00, $00, $80, $80, $00, $00, $00, $00
	Data.b $80, $00, $80, $00, $80, $00, $00, $80, $80, $00, $C0, $C0, $C0, $00, $80, $80
	Data.b $80, $00, $FF, $00, $00, $00, $00, $FF, $00, $00, $FF, $FF, $00, $00, $00, $00
	Data.b $FF, $00, $FF, $00, $FF, $00, $00, $FF, $FF, $00, $FF, $FF, $FF, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $0E, $60, $00, $00, $00, $00, $00, $00, $0E, $60, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $0E, $60, $00, $00, $00, $00, $00
	Data.b $00, $0E, $60, $00, $00, $00, $00, $00, $00, $0E, $60, $00, $00, $00, $00, $00
	Data.b $00, $0E, $E6, $00, $00, $00, $00, $00, $00, $00, $EE, $60, $00, $00, $00, $00
	Data.b $E6, $00, $0E, $E6, $00, $00, $00, $00, $E6, $00, $00, $E6, $00, $00, $00, $00
	Data.b $EE, $60, $0E, $E6, $00, $00, $00, $00, $0E, $EE, $EE, $60, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF
	Data.b $00, $00, $FE, $7F, $00, $00, $FC, $3F, $00, $00, $FC, $3F, $00, $00, $FE, $7F
	Data.b $00, $00, $FC, $3F, $00, $00, $FC, $3F, $00, $00, $FC, $3F, $00, $00, $FC, $1F
	Data.b $00, $00, $F2, $0F, $00, $00, $E1, $07, $00, $00, $E1, $87, $00, $00, $E0, $07
	Data.b $00, $00, $F0, $0F, $00, $00, $F8, $1F, $00, $00, $FF, $FF, $00, $00
EndDataSection
DataSection ;green.ico  hat eine Länge von 318 Bytes
	green:
	Data.b $00, $00, $01, $00, $01, $00, $10, $10, $10, $00, $00, $00, $00, $00, $28, $01
	Data.b $00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $10, $00, $00, $00, $20, $00
	Data.b $00, $00, $01, $00, $04, $00, $00, $00, $00, $00, $C0, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $80, $00, $00, $80, $00, $00, $00, $80, $80, $00, $80, $00
	Data.b $00, $00, $80, $00, $80, $00, $80, $80, $00, $00, $80, $80, $80, $00, $C0, $C0
	Data.b $C0, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $00, $FF, $FF, $00, $FF, $00
	Data.b $00, $00, $FF, $00, $FF, $00, $FF, $FF, $00, $00, $FF, $FF, $FF, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA, $AA, $AA, $AA, $AA, $AA, $00, $AA, $AA
	Data.b $AA, $AA, $AA, $AA, $AA, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $FF, $FF, $00, $00
EndDataSection
DataSection ;red.ico    hat eine Länge von 318 Bytes
	red:
	Data.b $00, $00, $01, $00, $01, $00, $10, $10, $10, $00, $00, $00, $00, $00, $28, $01
	Data.b $00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $10, $00, $00, $00, $20, $00
	Data.b $00, $00, $01, $00, $04, $00, $00, $00, $00, $00, $C0, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $80, $00, $00, $80, $00, $00, $00, $80, $80, $00, $80, $00
	Data.b $00, $00, $80, $00, $80, $00, $80, $80, $00, $00, $80, $80, $80, $00, $C0, $C0
	Data.b $C0, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $00, $FF, $FF, $00, $FF, $00
	Data.b $00, $00, $FF, $00, $FF, $00, $FF, $FF, $00, $00, $FF, $FF, $FF, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $99, $99, $99, $99, $99, $99, $99, $00, $99, $99
	Data.b $99, $99, $99, $99, $99, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $FF, $FF, $00, $00
EndDataSection
DataSection ;yellow.ico hat eine Länge von 318 Bytes
	yellow:
	Data.b $00, $00, $01, $00, $01, $00, $10, $10, $10, $00, $00, $00, $00, $00, $28, $01
	Data.b $00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $10, $00, $00, $00, $20, $00
	Data.b $00, $00, $01, $00, $04, $00, $00, $00, $00, $00, $C0, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $80, $00, $00, $80, $00, $00, $00, $80, $80, $00, $80, $00
	Data.b $00, $00, $80, $00, $80, $00, $80, $80, $00, $00, $80, $80, $80, $00, $C0, $C0
	Data.b $C0, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $00, $FF, $FF, $00, $FF, $00
	Data.b $00, $00, $FF, $00, $FF, $00, $FF, $FF, $00, $00, $FF, $FF, $FF, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB, $BB, $BB, $BB, $BB, $BB, $00, $BB, $BB
	Data.b $BB, $BB, $BB, $BB, $BB, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $00, $03
	Data.b $00, $00, $00, $03, $00, $00, $00, $03, $00, $00, $FF, $FF, $00, $00
EndDataSection
DataSection ;rmin.ico   hat eine Länge von 318 Bytes
	rmin:
	Data.b $00, $00, $01, $00, $01, $00, $10, $10, $10, $00, $00, $00, $00, $00, $28, $01
	Data.b $00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $10, $00, $00, $00, $20, $00
	Data.b $00, $00, $01, $00, $04, $00, $00, $00, $00, $00, $C0, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $80, $00, $00, $80, $00, $00, $00, $80, $80, $00, $80, $00
	Data.b $00, $00, $80, $00, $80, $00, $80, $80, $00, $00, $80, $80, $80, $00, $C0, $C0
	Data.b $C0, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $00, $FF, $FF, $00, $FF, $00
	Data.b $00, $00, $FF, $00, $FF, $00, $FF, $FF, $00, $00, $FF, $FF, $FF, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF
	Data.b $00, $00, $FF, $FF, $00, $00, $9E, $77, $00, $00, $9C, $63, $00, $00, $9C, $C1
	Data.b $00, $00, $98, $F7, $00, $00, $91, $F7, $00, $00, $83, $F7, $00, $00, $80, $F7
	Data.b $00, $00, $9C, $77, $00, $00, $9E, $77, $00, $00, $9C, $77, $00, $00, $80, $F7
	Data.b $00, $00, $81, $F7, $00, $00, $FF, $FF, $00, $00, $FF, $FF, $00, $00
EndDataSection
DataSection ;rmax.ico   hat eine Länge von 318 Bytes
	rmax:
	Data.b $00, $00, $01, $00, $01, $00, $10, $10, $10, $00, $00, $00, $00, $00, $28, $01
	Data.b $00, $00, $16, $00, $00, $00, $28, $00, $00, $00, $10, $00, $00, $00, $20, $00
	Data.b $00, $00, $01, $00, $04, $00, $00, $00, $00, $00, $C0, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $80, $00, $00, $80, $00, $00, $00, $80, $80, $00, $80, $00
	Data.b $00, $00, $80, $00, $80, $00, $80, $80, $00, $00, $80, $80, $80, $00, $C0, $C0
	Data.b $C0, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $00, $FF, $FF, $00, $FF, $00
	Data.b $00, $00, $FF, $00, $FF, $00, $FF, $FF, $00, $00, $FF, $FF, $FF, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	Data.b $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF
	Data.b $00, $00, $FF, $FF, $00, $00, $9E, $77, $00, $00, $9C, $77, $00, $00, $9C, $F7
	Data.b $00, $00, $98, $F7, $00, $00, $91, $F7, $00, $00, $83, $F7, $00, $00, $80, $F7
	Data.b $00, $00, $9C, $77, $00, $00, $9E, $77, $00, $00, $9C, $41, $00, $00, $80, $E3
	Data.b $00, $00, $81, $F7, $00, $00, $FF, $FF, $00, $00, $FF, $FF, $00, $00
EndDataSection
Procedure.w BLEconvW(WordWert.w)  ; Big-Little-Endian Konverter für Wordwerte
	Protected temp.w
	PokeB(@temp    , PeekB(@WordWert + 1))
	PokeB(@temp + 1, PeekB(@WordWert))
	ProcedureReturn temp
EndProcedure
;==================================================================================================
Procedure.l BLEconvL(LongWert.l)  ; Big-Little-Endian Konverter für Longwerte
	Protected temp.l
	PokeB(@temp    , PeekB(@LongWert + 3))
	PokeB(@temp + 1, PeekB(@LongWert + 2))
	PokeB(@temp + 2, PeekB(@LongWert + 1))
	PokeB(@temp + 3, PeekB(@LongWert))
	ProcedureReturn temp
EndProcedure
;==================================================================================================
Procedure.f BLEconvF(FloatWert.f) ; Big-Little-Endian Konverter für Floatwerte
	Protected temp.f
	PokeB(@temp    , PeekB(@FloatWert + 3))
	PokeB(@temp + 1, PeekB(@FloatWert + 2))
	PokeB(@temp + 2, PeekB(@FloatWert + 1))
	PokeB(@temp + 3, PeekB(@FloatWert))
	ProcedureReturn temp
EndProcedure
;==================================================================================================
Procedure.s ChgAddExtension(File.s, NewExtension.s) ; Ändert die Dateiendung einer Datei oder fügt sie bei fehlen hinzu
	If GetExtensionPart(File)
		File = GetPathPart(File) + ReplaceString(GetFilePart(File), "." + GetExtensionPart(File), "." + NewExtension)
	Else
		File + "." + NewExtension
	EndIf
	ProcedureReturn File
EndProcedure
;==================================================================================================
;- Konfigurationsdatei
Procedure ReadINI() ; Konfigurationsdatei lesen
	OpenPreferences(ChgAddExtension(ProgramFilename(), "ini")) ; INI-Datei öffnen
	PreferenceGroup("Programmkonfiguration")
	Leseintervall = ReadPreferenceLong("LeseintervallinSekunden", 15)
	PreferenceGroup("IPAdressen")
	ExaminePreferenceKeys()
	While NextPreferenceKey()
		AddElement(IPListe())
		IPListe() = PreferenceKeyValue()
	Wend
	ClosePreferences()
EndProcedure
;==================================================================================================
Procedure SaveINI() ; Konfigurationsdatei erstellen
	If CreatePreferences(ChgAddExtension(ProgramFilename(), "ini")) ; INI-Datei erstellen
		PreferenceGroup("Info")
		WritePreferenceString("Programmname", PRGName$)
		WritePreferenceString("Version", Version$)
		PreferenceComment("")
		PreferenceGroup("Programmkonfiguration")
		WritePreferenceLong("LeseintervallinSekunden", 15)
		PreferenceComment("")
		PreferenceGroup("IPAdressen")
		WritePreferenceString("IP1", "0.0.0.0")
		ClosePreferences()
	EndIf
EndProcedure
;==================================================================================================
Procedure Open_frmHaupt() ; Hauptfenster
	If OpenWindow(#frmHaupt, 216, 0, 640, 480, PRGName$,  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
		WindowBounds(#frmHaupt, 640, 120, #PB_Ignore, #PB_Ignore)
		If CreateToolBar(#ToolBar_0, WindowID(#frmHaupt))
			ToolBarImageButton(#tlbResetMin, ImgRmin)
			ToolBarToolTip(#ToolBar_0, #tlbResetMin, "Reset Min-Werte")
			ToolBarImageButton(#tlbResetMax, ImgRmax)
			ToolBarToolTip(#ToolBar_0, #tlbResetMax, "Reset Max-Werte")
			ToolBarSeparator()
			ToolBarImageButton(#tlbInfo, ImgInfo)
			ToolBarToolTip(#ToolBar_0, #tlbInfo, "Info")
		EndIf
		If CreateStatusBar(#StatusBar_0, WindowID(#frmHaupt))
			AddStatusBarField(18)
			AddStatusBarField(170)
			AddStatusBarField(170)
			AddStatusBarField(#PB_Ignore)
		EndIf
		ListIconGadget(#ListIcon_0, 0, 0, 640, 480, "Messgrößen", 150, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_MultiSelect)
		ForEach IPListe()
			AddGadgetColumn(#ListIcon_0, ListIndex(IPListe()) + 1, IPListe(), 100)
		Next
	EndIf
EndProcedure
;==================================================================================================
Procedure Info()
	Protected Info$
	Info$ + PRGName$ + #TAB$ + #CRLF$
	Info$ + "Version: " + Version$ + "  -  (PB " +  Str(#PB_Compiler_Version) + ")" + #TAB$ + #CRLF$ + #CRLF$
	Info$ + "Erstellt am: " + FormatDate("%dd.%mm.%yyyy - %hh:%ii:%ss", #PB_Compiler_Date) + #TAB$ + #CRLF$ + #CRLF$
	Info$ + Copyright$ + #TAB$
	If MessageRequester("Über " + PRGName$, Info$ , #MB_ICONINFORMATION) : EndIf
EndProcedure
;==================================================================================================
Procedure FillList() ; Messgrössen Liste füllen
	AddElement(Messgroessen())
	Messgroessen() = "Spannung U L1-N"      ; Offset: 1
	AddElement(Messgroessen())
	Messgroessen() = "Spannung U L2-N"      ; Offset: 3
	AddElement(Messgroessen())
	Messgroessen() = "Spannung U L3-N"      ; Offset: 5
	AddElement(Messgroessen())
	Messgroessen() = "Strom L1"             ; Offset: 13
	AddElement(Messgroessen())
	Messgroessen() = "Strom L2"             ; Offset: 15
	AddElement(Messgroessen())
	Messgroessen() = "Strom L3"             ; Offset: 17
	AddElement(Messgroessen())
	Messgroessen() = "Scheinleistung L1"    ; Offset: 19
	AddElement(Messgroessen())
	Messgroessen() = "Scheinleistung L2"    ; Offset: 21
	AddElement(Messgroessen())
	Messgroessen() = "Scheinleistung L3"    ; Offset: 23
	AddElement(Messgroessen())
	Messgroessen() = "Wirkleistung L1"      ; Offset: 25
	AddElement(Messgroessen())
	Messgroessen() = "Wirkleistung L2"      ; Offset: 27
	AddElement(Messgroessen())
	Messgroessen() = "Wirkleistung L3"      ; Offset: 29
	AddElement(Messgroessen())
	Messgroessen() = "Blindleistung L1"     ; Offset: 31
	AddElement(Messgroessen())
	Messgroessen() = "Blindleistung L2"     ; Offset: 33
	AddElement(Messgroessen())
	Messgroessen() = "Blindleistung L3"     ; Offset: 35
	AddElement(Messgroessen())
	Messgroessen() = "Max. Strom L1"        ; Offset: 87
	AddElement(Messgroessen())
	Messgroessen() = "Max. Strom L2"        ; Offset: 89
	AddElement(Messgroessen())
	Messgroessen() = "Max. Strom L3"        ; Offset: 91
	AddElement(Messgroessen())
	Messgroessen() = "Min. Spannung U L1-N" ; Offset: 145
	AddElement(Messgroessen())
	Messgroessen() = "Min. Spannung U L2-N" ; Offset: 147
	AddElement(Messgroessen())
	Messgroessen() = "Min. Spannung U L3-N" ; Offset: 149
EndProcedure
;==================================================================================================
Procedure LeseRegister(ConnectionID, Funktionscode.b, Startregister.w, RegisterAnzahlWert.w)
	Protected i, Daten, TranferOK
	Protected Spalte = ListIndex(IPListe())
	Static TransactionIdentifier.w
	Static Zeile
	If Zeile > 20 : Zeile = 0 : EndIf
	While Not TranferOK
		TransactionIdentifier + 1
		; MBAP Header in Big-endian Format
		PokeW(*Anfrage + 0,  BLEconvW(TransactionIdentifier)) ;Transaction Identifier (wird mit der Antwort zurückgemeldet - Empfehlung: bei jedem Durchlauf inkrementieren)
		PokeW(*Anfrage + 2,  BLEconvW(0))                     ;Protocol Identifier (Modbus Protokoll => 0)
		PokeW(*Anfrage + 4,  BLEconvW(6))                     ;Length (Länge der Nachfolgenden Daten inkl. Unit Identifier)
		PokeB(*Anfrage + 6,  1)                               ;Unit Identifier (wird mit der Antwort zurückgemeldet)
		; PDU in Big-endian Format
		PokeB(*Anfrage + 7,  Funktionscode)                   ;Funktionscode
		PokeW(*Anfrage + 8,  BLEconvW(Startregister))         ;Startregister
		PokeW(*Anfrage + 10, BLEconvW(RegisterAnzahlWert))    ;Anzahl der zu lesenden Register
		If SendNetworkData(ConnectionID, *Anfrage, 12)
			While Not Daten
				If NetworkClientEvent(ConnectionID) = #PB_NetworkEvent_Data
					Daten = ReceiveNetworkData(ConnectionID, *Antwort, 300)
					If Daten And TransactionIdentifier = BLEconvW(PeekW(*Antwort))
						TranferOK = #True
						If Funktionscode = 4
							For i = 9 To Daten - 1 Step 4 ; ab dem zehnten Byte kommen die Werte
								Messwerte(Spalte, Zeile) = BLEconvF(PeekF(*Antwort + i))
								Zeile + 1
							Next
						EndIf
					EndIf
				EndIf
				Delay(1)
				
			Wend
			Daten = 0
		EndIf
	Wend
EndProcedure
;==================================================================================================
Procedure Lesen(z.i) ; alle Stationen abfragen (Hintergrundthread)
	Protected ConnectionID, i, Zeit, ZeitAkt, ZeitMax, Wartezeit
	Protected Temp$
	While Not Programmende
		Zeit = ElapsedMilliseconds()
		ForEach IPListe()
			StatusBarText(#StatusBar_0, 1, " Verbinden mit " + IPListe())
			StatusBarImage(#StatusBar_0, 0, ImgYellow)
			ConnectionID = OpenNetworkConnection(IPListe(), 502, #PB_Network_TCP)
			If ConnectionID
				Select Abfragecode
					Case 0 ; Auslesen der Messregister
						StatusBarText(#StatusBar_0, 1, " Lesen von " + IPListe())
						StatusBarImage(#StatusBar_0, 0, ImgYellow)
						LeseRegister(ConnectionID, 4,   1,  6)
						LeseRegister(ConnectionID, 4,  13, 24)
						LeseRegister(ConnectionID, 4,  87,  6)
						LeseRegister(ConnectionID, 4, 145,  6)
					Case 1 ; Reset Min-Werte
						StatusBarText(#StatusBar_0, 1, " Reset Min-Werte")
						StatusBarImage(#StatusBar_0, 0, ImgYellow)
						LeseRegister(ConnectionID, 6, 60003, 0)
					Case 2 ; Reset Max-Werte
						StatusBarText(#StatusBar_0, 1, " Reset Max-Werte")
						StatusBarImage(#StatusBar_0, 0, ImgYellow)
						LeseRegister(ConnectionID, 6, 60002, 0)
				EndSelect
				CloseNetworkConnection(ConnectionID)
			Else
				StatusBarText(#StatusBar_0, 1, " Server Fehler")
				StatusBarImage(#StatusBar_0, 0, ImgRed)
				ForEach Messgroessen()
					Messwerte(ListIndex(IPListe()), ListIndex(Messgroessen())) = 0
				Next
				Delay(500)
			EndIf
			Delay(10)
		Next
		Abfragecode = 0
		HideGadget(#ListIcon_0, #True)
		ClearGadgetItems(#ListIcon_0)
		ForEach Messgroessen()
			Temp$ = Messgroessen()
			ForEach IPListe()
				Temp$ + Chr(10) + StrF(Messwerte(ListIndex(IPListe()), ListIndex(Messgroessen())), 2)
			Next
			AddGadgetItem(#ListIcon_0, -1, Temp$)
		Next
		HideGadget(#ListIcon_0, #False)
		ZeitAkt = ElapsedMilliseconds() - Zeit
		If ZeitAkt > ZeitMax : ZeitMax = ZeitAkt : EndIf
		StatusBarText(#StatusBar_0, 2, " Aktuelle Lesezeit: " + Str(ZeitAkt) + " ms")
		StatusBarText(#StatusBar_0, 3, " Maximale Lesezeit: " + Str(ZeitMax) + " ms")
		StatusBarImage(#StatusBar_0, 0, ImgGreen)
		Wartezeit = (z - Date() % z) * 1000
		While Wartezeit
			If Programmende : Break : EndIf
			StatusBarText(#StatusBar_0, 1, " Neulesen in " + Str(Wartezeit / 1000) + " s")
			Delay(1000)
			Wartezeit - 1000
		Wend
	Wend
EndProcedure
;==================================================================================================
;- Hauptprogramm ----------------------------------------------------------------------------------
If FileSize(ChgAddExtension(ProgramFilename(), "ini")) = -1
	SaveINI()
	MessageRequester("Konfiguration erstellt.", "Das Programm hat keine gültige Konfigurationsdatei gefunden." + #CRLF$ + #CRLF$  + "Es wurde eine INI-Datei angelegt." + #CRLF$ + #CRLF$ + "Bitte überprüfen Sie die Einstellungen vor dem nächsten Programmstart." + #TAB$ + #CRLF$  + #CRLF$ + "Das Programm wird jetzt beendet.", #MB_ICONINFORMATION)
	End
EndIf
If Not InitNetwork()
	MessageRequester("Fehler", "Netzwerk kann nicht initialisiert werden!", #MB_ICONERROR)
	End
EndIf
ReadINI()
FillList()
Dim Messwerte.f(ListSize(IPListe()) - 1, ListSize(Messgroessen()) - 1)
Open_frmHaupt()
Define LeseThread.i = CreateThread(@Lesen(), Leseintervall)
Define.i Event, EventWindow, EventGadget, EventMenu, EventType ; Variablen Eventschleife
Define.i wb0, wh0, tb0, sb0, wb1, wh1, sb1 ; Variablen für SizeWindow
Repeat ;- Ereignisschleife des Programms
	Event       = WaitWindowEvent() ; Warten bis Ereignis im Fenster auftritt
	EventWindow = EventWindow()     ; ID des Fensters mit Ereignis
	EventGadget = EventGadget() 		; ID des Gadgetss mit Ereignis
	EventMenu   = EventMenu()       ; ID des Menüs/Toolbar/Shortcut mit Ereignis
	EventType   = EventType()       ; Ermitteln des Ereignistyps
	Select Event
		;==================================================================================================
		Case #PB_Event_Menu            ; ein Menü / Symbol wurde ausgewählt
			Select EventMenu
				Case #tlbResetMin
					If Not Abfragecode
						If MessageRequester(PRGName$, "Möchten Sie die Minimalwerte zurücksetzen?", #PB_MessageRequester_YesNo | #MB_ICONEXCLAMATION) = #PB_MessageRequester_Yes
							Abfragecode = 1
						EndIf
					EndIf
				Case #tlbResetMax
					If Not Abfragecode
						If MessageRequester(PRGName$, "Möchten Sie die Maximalwerte zurücksetzen?", #PB_MessageRequester_YesNo | #MB_ICONEXCLAMATION) = #PB_MessageRequester_Yes
							Abfragecode = 2
						EndIf
					EndIf
				Case #tlbInfo
					Info()
			EndSelect
			;==================================================================================================
		Case #PB_Event_CloseWindow    ; das Schließgadget vom Fenster wurde gedrückt
			Select EventWindow
				Case #frmHaupt
					If MessageRequester(PRGName$, "Möchten Sie " + PRGName$ + " beenden", #PB_MessageRequester_YesNo | #MB_ICONEXCLAMATION) = #PB_MessageRequester_Yes
						Programmende = #True
					EndIf
			EndSelect
			;==================================================================================================
		Case #PB_Event_SizeWindow     ; das Fenster wurde in der Größe verändert
			Select EventWindow
				Case #frmHaupt
					wb0 = WindowWidth(#frmHaupt)
					wh0 = WindowHeight(#frmHaupt)
					tb0 = ToolBarHeight(#ToolBar_0)
					sb0 = StatusBarHeight(#StatusBar_0)
					ResizeGadget(#ListIcon_0, #PB_Ignore, tb0 , wb0, wh0 - tb0 - sb0)
			EndSelect
			;==================================================================================================
		Case #PB_Event_ActivateWindow ; das Fenster wurde aktiviert (hat den Fokus erhalten)
			Select EventWindow
				Case #frmHaupt
					SetActiveGadget(#ListIcon_0)
			EndSelect
			;==================================================================================================
	EndSelect
Until Programmende
; Abschlussarbeiten
StatusBarText(#StatusBar_0, 1, " Beenden...")
StatusBarImage(#StatusBar_0, 0, ImgRed)
WaitThread(LeseThread, 10000)
End
;
PB 5.7x (x64), LinuxMint 18.3 - Xfce (x64)
Einsteigerbuch: PureBasic - Eine Einführung in die Computer Programmierung
						Einsteigerbuch: PureBasic - Eine Einführung in die Computer Programmierung
Re: RS 485 Modbus Kommunikation
Hi,
ist da keine Port Angabe nötig?
Edit ist Modbus TCP, damit immer 502, steht auch im Code, muß angegeben werden?
Gruß Helmut
			
			
									
									
						ist da keine Port Angabe nötig?
Edit ist Modbus TCP, damit immer 502, steht auch im Code, muß angegeben werden?
Gruß Helmut