TCP/IP Telegrammaustausch mit PC variable Telegrammlänge

Zuviel Werbung?
-> Hier kostenlos registrieren
Eine Idee hätte ich noch:

Empfange das Telegramm in deine 40Byte. Dann suchst du in den 40Byte nach dem Startzeichen von dem Telegramm und schaufelst es Byte für Byte dahin wo du es brauchst bzw. weiter auswerten willst. Dann bügelst du die 40 Byte mit Nullen und kannst ein neues Telegramm empfangen und auswerten ...
 
Nur eine Frage am Rande: Die Siemens füllt den Puffer nicht von vorne, wenn ich sage ich möchte 100 Zeichen empfangen und bekommen nur 50? Stehen die dann wirklich irgendwo in diesem Puffer?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Grubba,


wieso nicht funktioniert hätte?

Das könnte doch funktionieren, nur 1 Byte als Speicher anzugeben und dann Byteweise das Telegramm zu empfangen bis ich den Telegrammabschluss erhalten habe oder?!
 
Hallo Grubba,


wieso nicht funktioniert hätte?

Das könnte doch funktionieren, nur 1 Byte als Speicher anzugeben und dann Byteweise das Telegramm zu empfangen bis ich den Telegrammabschluss erhalten habe oder?!
Das geht minimal auf den Datendurchsatz. Bei einer Zykluszeit von 10 ms und imer entsprechendem Flankenwechsel kommt man so doch schon auf berauschende 50 Bytes/s.
 
Hatte noch im Hinterkopf, dass man die Empfangsdatenlänge und die Länge des Empfangsdatenfach getrennt vorgeben kann, aber dem ist ja nicht so.

Trägst Du nun 1 Byte als Empfangspuffer ein und der Partner sendet z.B. 10 Bytes, wird der FB 10 Zyklen lang NDR True liefern, und bei jedem Aufruf 1 Byte abholen. Dabei bügelt er aber jedesmal das erste Byte im Empfangs-DB mit dem aktuellen Empfangsbyte über.

Deshalb wirds so wohl nicht gehen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So, auf ein letztes...

Habe überlesen, das Du ja eine Endekennung des Telegramms bekommst. Wenn Du jetzt wirklich immer nur 1 Byte ausliest, könnte es so evtl. doch so gehen:

- Ziel DB anlegen, mit genug Bytes für maximales Telegramm
- AnyPointer basteln, der nach jedem NDR die Zieladresse in Deinem Ziel-DB um 1 erhöht, (aber immer noch 1 Byte gross)
- Nach Empfang der Endekennung Pointer wieder auf 1. Byte im Ziel-DB zurücksetzen.

Ist ähnlich wie der letzte Vorschlag von Lars, dass Problem sehe ich darin, das der Siemens FB die aktuellen Empfangsdaten da ablegt, wo die alten Empfangsdaten aufhören. Wenn die Sende und Empfangslänge übereinstimmen - wunderbar. Ansonsten gibts immer einen Versatz von Empfang zu Empfang. Bei Empfangslänge von 1 hast Du dieses Problem halt nicht.
 
Irgendwo in den tiefen des Siemens-Supportes habe ich mal was über genau dieses Problem gelesen. Dort wurde auch ein Lösungsansatz incl. Programmbaustein vorgestellt.

Hast du da schon mal gesucht ?
 
Nein noch nicht... hast du zufällig noch die Beitrags-ID?

Wenn's da wirklich was von Siemens gäbe, würde ich ja direkt von

meinem Glauben abfallen ;-)
 
Weiß es jetzt zwar nicht genau (und kanns jetzt auch gerade nicht testen), aber ich denke das NDR erst dann kommt, wenn der Empfangspuffer komplett gefüllt ist. Lege ich also einen Puffer von 100 Byte an, würde NDR erst dann True werden, wenn mind. 100 Byte empfangen worden sind.

Hallo Grubba,
ganz genauso ist es. Der CP sammelt erst, nach Erreichen der 100 Byte (obiges Beispiel) kommt das NDR.

Achtung! Jetzt kommt ein neuer Aspekt:
Der CP empfängt auch noch Daten und puffert diese zwischen, wenn die CPU in Stop ist! Nach CPU Anlauf können also unschöne Effekte passieren! Dieses ist mir zumindest bei einer S7-400 schon einmal passiert.

Zur Problemlösung:
Ich würde auch ein AG_Receive mit LEN = 1 Byte machen und einen eigenen Puffer im DB füllen. Ist zwar der Nutzdatenanteil kleiner, aber was soll's.

Gruß
Flinn
 
Hallo Flinn,


danke mal für deinen Post.

Aber wie kann man den Puffer des AG_RECV selber kreieren?

Wie würdest du das ganze Progammtechnisch aufbauen?


Danke schon mal für deine Hilfe!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So, auf ein letztes...

Habe überlesen, das Du ja eine Endekennung des Telegramms bekommst. Wenn Du jetzt wirklich immer nur 1 Byte ausliest, könnte es so evtl. doch so gehen:

- Ziel DB anlegen, mit genug Bytes für maximales Telegramm
- AnyPointer basteln, der nach jedem NDR die Zieladresse in Deinem Ziel-DB um 1 erhöht, (aber immer noch 1 Byte gross)
- Nach Empfang der Endekennung Pointer wieder auf 1. Byte im Ziel-DB zurücksetzen.

Ist ähnlich wie der letzte Vorschlag von Lars, dass Problem sehe ich darin, das der Siemens FB die aktuellen Empfangsdaten da ablegt, wo die alten Empfangsdaten aufhören. Wenn die Sende und Empfangslänge übereinstimmen - wunderbar. Ansonsten gibts immer einen Versatz von Empfang zu Empfang. Bei Empfangslänge von 1 hast Du dieses Problem halt nicht.

Hi 3DA,
ich würde das so machen, wie Grubba schon angedacht hat, siehe oben.
Mit jedem NDR das empfangene Byte in ein DB kopieren, hierbei die DBB-Ziel-Adresse jeweils um ein Byte inkrementieren. Anschließend mit einer Schleife die Anfangskennung suchen (durch byteweisen Vergleich der Headerdaten). Wenn Anfangskennung gefunden, Anfangsposition merken. Jetzt Endekennung suchen. Wenn gefunden, dann Endeposition merken. Dann Anypointer zusammenbauen (mit Länge = Endeadresse - Anfangsadresse) und Quelldaten auf einen Arbeits-DB kopieren und weiterverarbeiten. Jetzt Pointer wieder auf Byteadresse Null setzen.

Viel geschrieben, ist aber im Prinzip genau das, was Grubba meinte.

Sendet das PC-Programm eigentlich zyklisch in gewissen Zeitabständen?
Was soll bei ungültigen Telegrammen passieren? Verwerfen?
Quittierst du Telegramme zurück? Dann könnte der PC nochmals senden.

Gruß
Flinn
 
Hallo,


also der Ansatz mit dem Byteweise auslesen scheint sehr gut zu sein.

Hab das mal so probiert. Mein Problem ist jetzt nur, bei RECV

P#DB6.DBX2.0 BYTE 8 funktioniert das wunderbar. Aber wenn ich dort nur

1 Byte angebe, geht der AG_RECV Baustein gleich auf ERROR=1.

Fehlercode=16#8184. und das PC programm kann auch garnicht mehr

verbinden.

Noch ne Frage: Wie würde ihr den Any-Pointer programmieren, um das

aus dem Empfangs- in einen ArbeitsDB zu kopieren? Kenn mich leider

mit AnyPointern nicht so recht aus...

Noch zum PC Programm:

Es schickt ca. 7 verschiedene Telegramme mit teilweise verschiedenen

Längen. Header sind aber im 8 Zeichen. Und die Telegramme mit gleichem

Header sind auch immer gleich lang bzw. weiß ich den Header, weiß

ich auch die Länge des Telegramms. Würde das die Sache vereinfachen?


Danke mal im Voraus...


Gruß
 
bzw. Fehlermeldung 16#80b1 wenn ein Telegramm vom PC kommt.

Dieses Phänomen ist erst weg, wenn ich min. 8 Byte RECV angebe.

Weiß jemand warum das so ist/sein kann?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hab gerade noch mal bei Siemens nachgesehen. Da steht, das nicht alle CPs das Byteweise abholen aus dem Empfangspuffer erlauben. Evtl. hast Du so ein Teil erwischt:confused:

Es schickt ca. 7 verschiedene Telegramme mit teilweise verschiedenen
Längen. Header sind aber im 8 Zeichen. Und die Telegramme mit gleichem
Header sind auch immer gleich lang bzw. weiß ich den Header, weiß
ich auch die Länge des Telegramms. Würde das die Sache vereinfachen?

Na logisch !

Die Länge Deines Headers ist ja anscheinend immer 8 Byte lang. Den holst Du Dir mit einem Empfangsauftrag ab. (ab 8 Bytes scheint das mit Deinem CP ja zu funktionieren)
Daraus ermittelst Du dann die Länge des Telegramms. Dann rufst Du noch einmal den Receive-FB auf und trägst als die Empfangslänge die Restlänge des Telegramms ein (Den Header hast Du ja schon abgeholt) Dieser Auftrag holt dann den Rest des Telegramms ab. Fertig :)
 
Hallo Grubba,


hab das mal so probiert, mit den 2 AG_RECV Bausteinen. Bringt er aber immer Fehlermeldung. Wie du schon gesagt hast, kann es sein, dass das nicht mit jedem CP geht?

Hab ne 343-1 Lean --> also die Sparversion quasi...


Weiß jemand ob das mit der Karte überhaupt geht?

Weil wenn ich ein 27 Byte Telegramm zur SPS schicke und mit dem ersten AG_RECV nur 8 Byte abfrage, geht dieses direkt auf Fehler und speichert die 8 Bytes auch nicht in den angegebenen Datenbereich?!


Grüße
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja richtig. Aber da hatte ich nur 1 AG_RECV verwendet, der die Daten dann im 8 Byte Rhytmus abgeholt hat.

Jetzt mit dem 2ten AG_RECV holt der erste vom Telgramm garnichts mehr ab, obwohl der 2te noch garnicht aktiv geschaltet ist.(habe die 2 AG_RECV gegeneinander verriegelt)

Hab sonst aber auch nichts verändert.

An was könnte das liegen? Die ID und LADDR etc. müssen ja bei den beiden AG_RECV gleich sein oder? Habe lediglich die Parameter RECV ERROR STATUS und LEN mit anderen Variablen gefüttert?!
 
Versuchs mal mit einem AG_RECV und mach die LEN Variablel. Vielleicht paßt bei der Verriegelung etwas nicht und in deinem Fall müßte es eigentlich auch mit einem AG_RECV funktionieren.

PS: Ich denke, bei dem Umschalten zwischen 2 Bausteinen, muß man sehr vorsichtig zu werke gehen. NDR ist einen Zyklus da. Umschalten darf man wahrscheinlich erst, wenn der Baustein, sein NDR auch wieder zurückgesetzt hat, also frühestens einen Zyklus später.
 
Zuletzt bearbeitet:
Noch ne Frage am Rande...

wenn ich anstatt eines CP-343-1 Lean eine CPU315-2PN/DP einsetze und mit TSEND bzw. TRECV arbeite, würde das das empfangen von variablen Telegrammlängen vielleicht vereinfachen?

Habe leider mit TSEND/TRECV null Erfahrung.

Kann da jemand mehr dazu sagen?
 
Zurück
Oben