TIA Modbus TCP MB-Client mehrfach in einem FB aufgerufen

ChristianVogel

Level-2
Beiträge
473
Reaktionspunkte
69
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

kleines Problem, bei dem ich scheitere: Thema Elektromobilität, Ladesäule, Ladegerät => Ich habe die Aufgabe aus Ladegeräten, per Modbus TCP, Daten auszulesen. Die Ladegeräte sind modular aufgebaut, daher mein „Wunsch“ nach einem einigermaßen flexiblen FB-Baustein, der je nach „Eingangsbeschaltung“ seine Funktionen ausführt.

Modulares Ladegerät heißt: Es gibt EIN Ladegerät, was mit bis zu VIER Ladeports ausgebaut werden kann, d.h. EIN Ladegerät hat EINE IP-Adresse, die Datenlängen variiert je nach Ausbaustufe. Die Register sind bei Ladeport 1 bis 4 identisch, sie sind eben vorhanden, wenn das Modul gesteckt ist, nicht vorhanden, wenn das Modul fehlt.

Die Register sind Holding-Register,
Ladeport 1, Register 1000…1100, ich lese also aus 41000, LEN=111
Ladeport 2, Register 2000…2100, ich lese also aus 42000, LEN=111
Ladeport 3, Register 3000…3100, ich lese also aus 43000, LEN=111
Ladeport 4, Register 4000…4100, ich lese also aus 44000, LEN=111

Mein Gedanke und jetziger Stand ist der: Ich brauche von diesen 111 WORD pro Ladeport nur je 16 WORD, da ich aber keine Lust habe alles zusammenzustückeln, hätte ich gerne diese 111 WORD auf einen Schwung ausgelesen, in einem „ARRAY of WORD“ abgelegt und mir die erforderlichen Daten rausgezogen und verarbeitet.

Bei einem Ladegerät mit einem Port lese ich mit einem MB-Client die Register 41000 aus, den Rest nicht,
Bei einem Ladegerät mit zwei Ports lese ich mit einem MB-Client die Register 41000 aus, dann die 42000, den Rest nicht,
usw.

So habe ich den Kopf deklariert:
1777449870670.png

Die REQ-Ansteuerung übernimmt eine kleine Schrittkette, die von 1-5 durchzählt...
1777449956582.png
1777449983877.png
1777450005964.png
1777450024837.png

so... wie ihr sehen könnt, bekomme ich beim ersten Baustein den Status 16#7004, da wurde also eine Verbindung aufgebaut, die restlichen Bausteine liefern mit 16#80A3 als Status, was auf ein Verbindungsproblem hindeutet. Aber dieses Ladegerät hat alle 4 Slots bestückt und diese funktionieren auch.

Wo habe ich hier einen Denkfehler/Programmfehler?

Info: Ich habe ja hier alle MB-Clients mit dem selben "TCON_IP_V4" im Kopf beschaltet, das ist doch alles die gleich Verbindung, oder? oder brauche ich hier ebenfalls für jeden Aufruf eine seperate Beschreibung? Bisher hätte ich gerne die Beschreibung der IP-Adresse über die Bausteinanschlüsse definiert...

1777450679694.png

Jemand eine Idee???
gleich noch ein paar konkrete Fragen zum Baustein selbst:
- Sollte der Status nicht verschwinden, wenn der Baustein ein neues REQ bekommt?
- Sollten die Ausgänge, zumindest DONE und ERROR beim neuen Start ebenfalls kurz den Status "False"
annehmen, damit ich mit einer Flanke einen neuen Status erkennen und melden kann?
(wäre für die Weiterschaltung der Schrittkette wichtig...)

Habe grade das TIA18 in Verwendung, PLC ist eine ET200SP CPU1510.

bin ich mal gespannt was ich hier verbockt habe...

Soweit vielen Dank,
Gruß Christian
 
wenn das das gleiche Gerät ist, wo Du verschiedene Register abfragen willst, musst Du bei den ganzen MB_Clients den selben IDB hernehmen und mit Deinem INT-Vergleich den EN freigeben! Den INT erst hochzählen, wenn der Done gekommen (oder nen Error oder sonstwas, jedenfalls nicht zyklisch da der ganze Aufruf mehr als einen Zyklus dauert)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hast du mal versucht die Register per Modbus Poll oder ähnlichem Modbusclient per PC zu holen?

Vermutlich baut der nächste Modbus Baustein auf einer schon aufgebauten Verbindung auf, das geht nicht.
Wenn du das so machst, müsstest du verschiedene VerbindungsIDs verwenden (dann muss der Modbus server aber auch 4 Verbindungen gleichzeitig vertragen).
Sinnvoller wäre es aber den Modbus Client mit einer Instanz aufzurufen und die Adressen nach einem Done neu zu setzen und den Request auszulösen. Das Resultat dann entsprechend einzusortieren.
 
Funktioniert das Lesen bei dem ersten?
Wenn ja kannst du einfach auf das Done warten, die Werte von der PTR Variablen für den ersten wegspeichern, die Adresse auf den 2ten ändern und neu triggern. Also nur mit 1 Client arbeiten.
 
wenn das das gleiche Gerät ist, wo Du verschiedene Register abfragen willst, musst Du bei den ganzen MB_Clients den selben IDB hernehmen und mit Deinem INT-Vergleich den EN freigeben! Den INT erst hochzählen, wenn der Done gekommen (oder nen Error oder sonstwas, jedenfalls nicht zyklisch da der ganze Aufruf mehr als einen Zyklus dauert)
- Nur EIN Instanz-DB? ok.... probiere ich.
- Freigabe mit EN kann ich testen, der REQ, reicht da eine positive Flanke, oder kann EN und REQ gleich sein?
- Bei DONE oder ERROR, addiere ich aktuell +1 beim "#MB_Client_REQ_Num"

wenn das das gleiche Gerät ist, wo Du verschiedene Register abfragen willst, musst Du bei den ganzen MB_Clients den selben IDB hernehmen und mit Deinem INT-Vergleich den EN freigeben! Den INT erst hochzählen, wenn der Done gekommen (oder nen Error oder sonstwas, jedenfalls nicht zyklisch da der ganze Aufruf mehr als einen Zyklus dauert)
...probiere ich mal, EIN IDB wäre ja schon der zweite vorschlag...

Funktioniert das Lesen bei dem ersten?
Wenn ja kannst du einfach auf das Done warten, die Werte von der PTR Variablen für den ersten wegspeichern, die Adresse auf den 2ten ändern und neu triggern. Also nur mit 1 Client arbeiten.
- naja, also beim Ersten erhalte ich den Status 16#7004, was ja einem Verbindungsaufbau entsprechen würde.
- Wenn der erste Richtig arbeitet wäre ein Mehrfachaufruf denkbar, würde aber meiner aktuellen Vorgehensweise widersprechen, ich behalte das aber mal im Hinterkopf.... da müsste ich dann eben die Register und den Zielbereich tauschen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
- Nur EIN Instanz-DB? ok.... probiere ich.
(y)
- Freigabe mit EN kann ich testen, der REQ, reicht da eine positive Flanke, oder kann EN und REQ gleich sein?
Theoretisch solltest Du EN und REQ gleich beschalten können.
- Bei DONE oder ERROR, addiere ich aktuell +1 beim "#MB_Client_REQ_Num"
würd da noch nen Hosenträger bauen, falls 10s weder Done noch Error kommt, sowas solls geben... und falls 60s nix passiert vielleicht mal Disconnecten
 
oooookkkk.... Also:

- Ich habe meine Schrittkette 0...5 etwas optimiert, diese läuft jetzt sauber durch
- Beim Erreichen von 5 wird das ganze auf 0 gehauen und beginnt von vorne.
- EIN Instanz-DB reicht anscheinend, läuft. (Widerspricht doch eigentlich der Bezeichnung "INSTANZ-DB", oder?) Egal, läuft.
- EN habe ich nicht belegt, habe es über den REQ gelöst, der sich am Ende "selbst löscht"

1777463333724.png

ich habe aber noch ein problem: Nach jedem Aktuallisieren des Bausteins, hat es mir diese auf Störung 80A3, kann ich denn diese Baustein auch resetten, ohne die Steuerung auf Stop/Start zu schalten? Das läuft dann über "Disconnect"? aber nur am entsprechenden Netzwerk, oder über die gesammte Verbindung?



An einer Stelle habe ich mir auch zu viel Gedanken gemacht, nehme ich an: Was mache ich denn beim "MB_Client_Connect / TCON_IP_v4" mit der Variable "ID / CONN_OUC"??? Lege ich dann für jede Verbindung zu einem Ladegerät dann eine seperate Verbindung an, oder bleiebn diese alle auf "1"? Die Funktion und Erklärung der Hilfe erschließt sich mir da nicht ganz...

Die Hilfe sagt "Referenz auf diese Verbindung (Wertebereich: 1 bis 4095). Über den Parameter wird eine Verbindung innerhalb der CPU eindeutig identifiziert. Jede einzelne Instanz der Anweisung "MB_CLIENT" muss eine eindeutige ID verwenden."

--> d.h. jedes Ladegerät was von einem FB ausgelesen wird bekommt dann als Verbindung eine Nummer +1, d.h. den auf einen Bausteineingang zu legen, war schonmal kein Fehler?
 
An einer Stelle habe ich mir auch zu viel Gedanken gemacht, nehme ich an: Was mache ich denn beim "MB_Client_Connect / TCON_IP_v4" mit der Variable "ID / CONN_OUC"??? Lege ich dann für jede Verbindung zu einem Ladegerät dann eine seperate Verbindung an, oder bleiebn diese alle auf "1"? Die Funktion und Erklärung der Hilfe erschließt sich mir da nicht ganz...
das ist die Verbindungs-ID auf deiner lokalen CPU für die OUC... Die muss eindeutig sein, es darf keine andere OUC auf der CPU geben mit der selben ID, also z.B. LSNTP-Server, TSEND/TRCV usw...

also neue Verbindung zu anderem Netzwerkteilnehmer mit anderer IP -> neue eindeutige ID
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja genau, Pro Serververbindung, also bei dir pro Ladegerät, braucht es eine eindeutige Verbindungs-ID und eine zugehörigen MB_Client Instanz.
Wieviele Ladegeräte hast du denn? Es gibt hier eine maximale Anzahl an Verbindungen!

Dass du noch immer 80A3 bekommts ist komisch, wohl durch das Switchen der Client-Bausteine?
In der Hilfe zu Modbus finde ich den Fehler nicht aber im TCP heißt der "Es wird versucht, eine bestehende Verbindung erneut aufzubauen".
Ich würde trotzdem empfehlen die Adressen zu switchen, nicht die Clients, dann erübrigt sich der Fehler wahrscheinlich.
 
- EIN Instanz-DB reicht anscheinend, läuft. (Widerspricht doch eigentlich der Bezeichnung "INSTANZ-DB", oder?) Egal, läuft.
Das widerspricht sich überhaupt nicht.
InstanzDB bezieht sich auf die Instanz von Bausteinen.
Was dir aber in die Suppe pisst, ist die verwendung derselben Verbindung für mehrere Instanzen.
Du könntest mehrere Instanzen verwenden, wenn jede Instanz ihre eigene Verbindung bekommt. Das belegt aber Verbindungsressourcen die du vielleicht sparen möchtest (vor allem auf der Gegenseite die man eher weniger im Griff hat)

- EN habe ich nicht belegt, habe es über den REQ gelöst, der sich am Ende "selbst löscht"
EN ist nur was für FUP. IMHO sollte das für komplexere Baustein immer auf true sein.
REQ ist das was du verwenden solltest, das ist genau dafür gedacht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
- EIN Instanz-DB reicht anscheinend, läuft. (Widerspricht doch eigentlich der Bezeichnung "INSTANZ-DB", oder?) Egal, läuft.
Dadurch dass Du nur einen Aufruf gleichzeitig mit EN freigibst, widerspricht das nicht der Bezeichnung. Im Endefekt ist das nichts anderes als wenn Du an einem Bausteinaufruf die Eingangsparameter umschaltest...
So wie Du das jetzt machst, alle 5 EN freizugeben ist falsch...
 
Was dir aber in die Suppe pisst, ist die verwendung derselben Verbindung für mehrere Instanzen.
Du könntest mehrere Instanzen verwenden, wenn jede Instanz ihre eigene Verbindung bekommt. Das belegt aber Verbindungsressourcen die du vielleicht sparen möchtest (vor allem auf der Gegenseite die man eher weniger im Griff hat)
stellt sich halt die Frage, ob die Gegenstelle 5 Verbindungen aufbauen kann... Da musst das Handbuch der Gegenstelle lesen.

Sonst bräuchte man garkeine Schrittkette sondern würde einfach 5 Aufrufe machen, an der REQ nen Taktmerker drann und gleichzeitig 5 Verbindunen zum selben Modbusserver aufbauen und parallel lesen...
 
stellt sich halt die Frage, ob die Gegenstelle 5 Verbindungen aufbauen kann... Da musst das Handbuch der Gegenstelle lesen.

Sonst bräuchte man garkeine Schrittkette sondern würde einfach 5 Aufrufe machen, an der REQ nen Taktmerker drann und gleichzeitig 5 Verbindunen zum selben Modbusserver aufbauen und parallel lesen...
Das meinte ich mit der Gegenstelle. Es ist üblicherweise keine gute Idee mehrere Verbindungen zu ein und derselben Gegenstelle aufzubauen und dann zu halten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
(y)

Theoretisch solltest Du EN und REQ gleich beschalten können.

würd da noch nen Hosenträger bauen, falls 10s weder Done noch Error kommt, sowas solls geben... und falls 60s nix passiert vielleicht mal Disconnecten
NÖ: Mit EN UND REQ funktioniert das ganze nicht... habe nur den REQ verwendet, der mit einer Flanke einen Merker setzt. Der MB-Client löscht sich dann selbst und mit Done/Error setzte ich meinen Schrittmerker +1 für den nächsten Baustein
also neue Verbindung zu anderem Netzwerkteilnehmer mit anderer IP -> neue eindeutige ID
geht klar....
Das widerspricht sich überhaupt nicht.
InstanzDB bezieht sich auf die Instanz von Bausteinen.
Was dir aber in die Suppe pisst, ist die verwendung derselben Verbindung für mehrere Instanzen.
Du könntest mehrere Instanzen verwenden, wenn jede Instanz ihre eigene Verbindung bekommt. Das belegt aber Verbindungsressourcen die du vielleicht sparen möchtest (vor allem auf der Gegenseite die man eher weniger im Griff hat)


EN ist nur was für FUP. IMHO sollte das für komplexere Baustein immer auf true sein.
REQ ist das was du verwenden solltest, das ist genau dafür gedacht.


Also aktuell habe ich 7 Ladegeräte mit je 4 Ports. nach jetzigem Stand scheint das Auslesen mit EINER Verbindungs-ID zu funktionieren.
--> Also 7 Ladegeräte --> 7 Server-Kommunikationspartner mit je 1 IP-Adresse

Aktuell in AUssicht ein Projekt mit 22 Ladegeräten, demnach 22 Verbindungen...
 
äte mit je 4 Ports. nach jetzigem Stand scheint das Auslesen mit EINER Verbindungs-ID zu funktionieren.
--> Also 7 Ladegeräte --> 7 Server-Kommunikationspartner mit je 1 IP-Adresse

Aktuell in AUssicht ein Projekt mit 22 Ladegeräten, demnach 22 Verbindungen...
Du kannst natürlich die Verbindung abbauen die IP wechseln und dieselbe VerbindungsID mit einer neuen IP aufbauen. Das geht schon.
Aber das muss wirklich akkurat programmiert werden, sonst hast du keine Kontrolle woher die Daten kommen.
IMHO macht so ein Vorgehen keinen Sinn.
Und ehrlichgesagt zweifle ich daran das du verschiedene IPs mit derselben VerbindungsID connecten kannst, mit dem Wissen das du zur Zeit hast.
Das ist nicht abwertend gemeint.
 
Zuletzt bearbeitet:
Dann musst du sowieso die Verbindungen durchschalten, in der ET200SP hast du max 10 Verbindungen, da zählen aber auch HMI bzw. PG dazu!
wie kommst Du da drauf? 1500er haben normalerweise deutlich mehr, auch wenn ich jetzt nicht im Kopf habe, wieviele.

Aber zum Thema, es gibt 7 Teilnehmer mit eigener IP, von jedem sollen 4 mal 111 Register gelesen werden?

Irgendwie geht hier einiges durcheinander.

Auf jeden Fall erstmal 7 MB_Clients hernehmen mit jeweils eigenem unterschiedlichem IDB und eigener Verbindungs ID. Diese 7 Clients können parallel laufen.

Die nächste Frage, wie liest man pro Client jetzt 4 mal, das gehnt nicht parallel, also entweder den Eingang mit dem Modbusregister umschalten oder jeweils 4 Clients hernehmen mit dem selben IDB wovon immer nur einer mit EN aktiv ist...

PS ne 1510SP kann 88 Verbindungen über die integrierte Schnittstelle + 32 über nen zusätzlichen CP. 10 sind diese reservierten...
 
Zuletzt bearbeitet:
Ist doch eine schöne Aufgabe, 22 IP's durchrattern und bei jedem die 4x111 Words rausholen. Dann gleich in ein Array[0..21, 0..3, 0..110] rein (y)
Natürlich. Rein von der Entwicklung. Aber es dürfte wenig performant sein und technisch gibt es keinen Grund dafür. Denn Verbindungs auf und Abbau dauert ja auch seine Zeit. Der Mb Modbus mach es einem supereinfach die Verbindung aufzubauen und zu halten. Dann muss man sich nur noch um die Register und coiladressen kümmern.
Ausserdem sieht eine stehende Verbindung n der Verbindungsübersicht besser aus als eine die ständig wieder abgebaut wird.
Das hat man früher gemacht als die Verbindungsressourcen arg begrenzt waren. Heute mache ich das nur noch wenn die Datenmenge Geld kostet (IoT), da stehende Verbindungen durch die SPS überwacht werden und sehr viel Traffic erzeugen.

Ich denke jetzt dürfte aber für den OP klarer geworden sein worin der Unterschied zwischen
  • Bausteininstanz
  • Verbindungsinstanz
  • ModbusID (das kann bei solchen Modbus TCP objekten ja doch auch noch eine Rolle spielen.
  • modbusadresse ist.
 
Zurück
Oben