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
Hygge
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