TIA TCP Kommunikation zu Laser

plc_typ

Level-2
Beiträge
215
Reaktionspunkte
30
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe momentan mit der Kommunikation zu einem KBA Laser zu tun, die noch etwas Probleme macht.

CPU: 1214C
TIA Portal V13 Updt. 4

Folgendes soll gemacht werden, an den Laser soll ein Zähler geschickt werden, ist kein Sendeauftrag
Aktiv wird der Aktuelle Zähler stand gelesen. Dafür gibt es 2 Telegramme die ich Verschicke, eines zum
Zähler schreiben (SPS sendet 17 Byte, Laser antwortet 9 Byte), eines zum Zähler lesen (SPS sendet 9 Byte, Laser antwortet 17 Byte).

Die Kommunikation Wird über TCON, TSEND, TRCV und TDISCON. An den LEN eingängen stehen nullen damit
die Bausteine mit der Variablen Telegrammlänge klar kommen.

Die Ganze Kommunikation hatte soweit auch schon mal funktioniert, nur bekomme ich nun aus irgend einem
Grund die Antwort Telegramm in 17 Byte länge (Laser sendet Zähler) rotiert. Soll heißen, normal sollte die Antwort so aussehen:

|0x02|0x0E|0x92 0x00|0x03 0x00 0x00 0x00|0x00 0x00 0x00 0x00|0x00 0x00 0x00|0x00|0x03|


Stattdessen bekomme ich aber:
|0x00 0x00|0x00 0x00 0x00|0x00|0x03|0x02|0x0E|0x92 0x00|0x03 0x00 0x00 0x00|0x00 0x00|


Bei der 9 Byte Antwort rotieren die Bytes permanent durch den bereich.


Ich bin Ratlos warum ich auf einmal dieses verhalten habe. Hatte schon mal jemand so ein verhalten bei einer Kommunmikation?



Gruß

Florian
 
Es sieht so aus als wenn dein Eingabepuffer ein Ringpuffer ist - was bei serieller Kommunikation schon sinnvoll ist

Ist dir klar das deine serielle Schnittstelle nicht immer alle Daten am Stück sendet - also nicht immer einer 17 Byte Block - sondern auch mal problemlos kleinere Happen mit 1-n Bytes
bis deine 17 Bytes voll sind? geht du damit richtig um?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das die Daten nicht am Stück kommen können war mir nicht bewusst.

Das 17 Byte Telegramm- Problem habe ich auch gelöst, ich suche in einer schleife den Telegramm Anfang und kopiere die Bereiche dann in der richtigen Reihenfolge um.
Bei dem 9 Byte Block bin ich allerdings ratlos.

Gruß
 
Zuletzt bearbeitet:
sollte es ein Ringpuffer sein muss du irgendwo eine Anfang/Ende Kennung bekommen - die der Anfang oder das Ende deines Arrays kann auch dazwischen sein also z.B. von [15-2] also [15,16,17,0,1,2] usw.

Beispiel:

Code:
|0x00 0x00|0x00 0x00 0x00|0x00|0x03|0x02|0x0E|0x92 0x00|0x03 0x00 0x00 0x00|0x00 0x00|
                               ENDE ANFANG -> laeuft so bis ENDE durch


kannst du mal die Protokoll-Doku fuer die 9 und 17 bytes hier einstellen - oder die relevanten Teile?
häng dich mal mit http://www.hw-group.com/products/hercules/index_en.html (Freeware RS232-Tool) an den Laser und kommunizier mal von Hand - nur
damit sicher ist das alles funktioniert
 
Zuletzt bearbeitet:
Ok, habe die Kommunikation nun in Betrieb.

Ich warte bei den Rotierenden Bytes darauf bis sie in der richtigen Reihenfolge sind, dann kopiere ich sie um. Das Tool hat mir auch geholfen um die Kommunikation zu
testen, sehr Hilfreich!
Ich verstehe nur nicht warum dieses verhalten anfangs nicht da war. als ich mit der Kommunikation begann waren die Telegramme Fix, dann ging es los mit sporadischen
ausfällen.

Danke für die Hilfe!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok, habe die Kommunikation nun in Betrieb.
Ich warte bei den Rotierenden Bytes darauf bis sie in der richtigen Reihenfolge sind, dann kopiere ich sie um

Hört sich aber stark nach Bastellösung an - so schwer ist serielle Kommunikation aber nicht d.h. du machst irgendwas falsch oder verarbeitest einfach falsch
- und korrigierst das dann bis es wieder richtig ist - das kann dir später im Betrieb trotzdem in die Suppe spucken (Laser wieder mal ausgefallen usw. - alle paar Wochen)

Ich verstehe nur nicht warum dieses verhalten anfangs nicht da war

Kabel, PC, SPS gewechselt?, andere Schnittstellen-Einstellungen? kann alles dazu führen das du eher die wahre Natur der seriellen Kommunikation sehen kannst

der Puffer muss einfach gross genug sein z.B. 100 Bytes oder so - dann gibt auch nicht so schnell einen Ring
im Normalfall wartest du bis du die vollen 9, oder 17 Bytes empfangen hast - oder auf eine Ende-Kennung (falls im Prokotoll vorhanden) - das wars
 
Wie könnte ich es denn besser lösen?
Momentan Schreibt mein TRCV auf einen 17 Byte langen Array, da das längste Telegramm welches ich erwarte eben die 17 Byte hat.

In diesem Puffer Check ich dann nach Anfangs- (0x02) Endkennung (0x03) und der Auftragskennung (0x92), wenn all diese Bytes an der richtigen stelle
sind kopiere ich die Daten in einen Puffer und setze ein Bit das sie Gültig sind.
 
soweit ich weiss heisst LEN=0 das er sofort beim Empfang von Daten zurueck kommt - mit RCV_LEN steht dann die wirklich gelesene Laenge (die <=17 sein kann) - wenn die noch nicht bei 17 ist muss du weiter auf Daten warten
bei jedem Receive-Aufruf wird (soweit ich weiss) wieder bei 0 in den Puffer geschrieben d.h. folgendes kann passieren

du Fragst den Laser und wartest dabei auf Antwort

1. Receive:

0x02 0x0E 0x92 0x00 0x03 0x00

2. Receive:


0x00 0x00 0x00 0x00 0x00 0x00 0x00

3. Receive:


0x00 0x00 0x00 0x03

jetzt haben wie die 17 Bytes zusammen - es koennen auch mehr oder weniger Pakete sein (völlig Random)

da ich deinen Ablauf nicht kennen und du auch keine Doku von dem Protokoll hier einstellst kann ich nur vermuten das du dir deinen Puffer ueberschreibst

du koenntest deine LEN auch einfach auf 17 Stellen - du weisst ja welchen Befehl du an den Laser gesendet hast - und damit auch wie lange die Antwort wird oder (ohne Doku kann ichs aber nicht genau sagen)
 
wenn jemand was schreibt musst du den Inhalt bestätigen (weil schon getestet) oder sagen das er unverständlich ist - aber einfach nur auf Teile zu reagieren bringt nicht wirklich viel

Überschreibst du dir deinen Puffer - wenn keine Ahnung dann musst du es testen

bringt es was die LEN auf 17 zu stellen? - nur Testweise
 
Zuletzt bearbeitet:
wenn jemand was schreibt musst du den Inhalt bestätigen (weil schon getestet) oder sagen das er unverständlich ist - aber einfach nur auf Teile zu reagieren bringt nicht wirklich viel

Überschreibst du dir deinen Puffer - wenn keine Ahnung dann musst du es testen

bringt es was die LEN auf 17 zu stellen? - nur Testweise


Ich verstehe nicht ganz was Du damit meinst, sorry.

Aus deiner vorigen Nachricht deute ich aber dass es helfen könnte die LEN Variabel zu machen, also die erwartete länge angeben. Somit sollten
die Daten erst in meinen Puffer geschrieben werden wenn auch die volle länge eingegangen ist?


Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe nicht ganz was Du damit meinst, sorry.

Tip1:
deine Datenpakete können Sonnenstandabhängig über TCP/IP zerhackt werden (ist dir ja klar) - d.h. mit deinem TRCV.LEN=0 kann es notwendig sein x mal Receive aufzurufen - bis eben deine erwartete Paketgroesse
erreicht ist - (btw: die steht immer im 2. Byte + 1) - bei jedem Receive-Auruf überschreibst du deinen Puffer vom Anfang - ist das so bei dir? oder machst du dein Receive irgendwie anders?

Tip2:
wenn du deine LEN mal fest auf 9 oder 17 einstellst macht die SPS das warten für dich - damit koenntest du einfach testen ob es ein Problem mit deinem Puffer gibt

normalerweise geht beides - fuer mehr Flexibilität würde ich den LEN=0 Weg wählen (aber eben korrigiert) - Tip2 könnte die einfache Lösung sein
 
Ich habe nun abhängig von meiner Anfrage an den Laser die LEN des TRCV angepasst, die Daten beider Telegramme sind nun fest, sie springen nicht mehr willkürlich
im Empfangspuffer umher. Rotiert sind beide Telegramme weiterhin in meinem Empfangspuffer, aber das ist das kleinere Problem.

Ich denke mit dieser Lösung kann ich leben :p .
 
sie springen nicht mehr willkürlich
im Empfangspuffer umher. Rotiert sind beide Telegramme weiterhin in meinem Empfangspuffer, aber das ist das kleinere Problem.

Rotiert? verstehe ich einfach nicht - da sollte einfach nichts rotieren, Frage: passiert das auch wenn dein Empfangspuffer 100 Bytes gross ist?

Mich würde es stören wenn ein TCP/IP-Client wie Herules es richtig zeigt und mein SPS-Puffer ist verdreht - da ist definitiv was an deiner Verarbeitung faul
- aber möglicherweise brauchst du eben noch ein paar Projekte mit TCP/IP-Anbindung bis dich das auch genug stört :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es gibt bei Siemens 2 unterschiedliche Varianten beim TCP/IP.

1. Es wird ein fester Buffer verwendet (RCV-Len wird > 0 angegeben am Baustein), die eingehenden Daten werden immer an das Ende der letzen empfangenen Daten angehängt. Ist das Ende des Buffer erreicht, geht es vorne weiter.

2. Es wird zwar auch ein fester Buffer verwendet, die Daten werden aber immer vorn in den Buffer geschrieben. RCV-Len wird = 0 angegeben am Baustein)

Zerhackte Telegramme hab ich noch nie erlebt, aber vielleicht waren meine einfach nur zu kurz.
Ich weiß leider nicht genau, welche SPS genau Variante 2 können. Lösungen mit dem rotierenden Buffer gehen eigentlich nur richtig, wenn man eine Endekennung hat und so die Daten selbst wieder korrekt zusammenfügen kann.
Mich würde sehr überraschen, wenn die neuen SPS von Siemens nicht Variante 2 können, aber obwohl ...
 
1. Es wird ein fester Buffer verwendet (RCV-Len wird > 0 angegeben am Baustein), die eingehenden Daten werden immer an das Ende der letzen empfangenen Daten angehängt. Ist das Ende des Buffer erreicht, geht es vorne weiter.
2. Es wird zwar auch ein fester Buffer verwendet, die Daten werden aber immer vorn in den Buffer geschrieben. RCV-Len wird = 0 angegeben am Baustein)

hört sich ja genau nach seinen Problemen an

Lösungen mit dem rotierenden Buffer gehen eigentlich nur richtig, wenn man eine Endekennung hat und so die Daten selbst wieder korrekt zusammenfügen kann.

sein Protokoll hat einen Längenangabe im Kopf drinn - und eine Pseudo-Ende-Kennung danach (die aber nur 1 byte lang ist und nicht 100% von Inhalt unterscheidbar ist) - mehr gibt- oder braucht man nicht um es richtig zu machen
es ist eben einfach falsch einen TCP/IP, RS232-Stream wie eine Bus-Kommunikation zu programmieren -

1. man lernt es falsch und wendet diese Falschwissen immer wieder an
2. bei größeren Protokollen oder schlechten Leitungen kommt es plötzlich zu falscher Protokollverarbeitung oder scheinbar "unlösbaren" Problemen in der Verarbeitung

daher wird bei TCP/IP meist mit Länge im Kopf gearbeitet - so wie auch bei seinem Protkoll, dann muss man einfach so lange warten bis diese Länge gelesen wurde und dann
das Protkoll verarbeiten ala:

Daten lesen bis mind. Kopf.Groesse empfangen wurde
Daten lesen bis Kopf.Groesse erfuellt
---> Inhalt auslesen, verarbeiten
(wenn das 1. Paket schon gross genug ist kann es auch sein das kein weiteres warten mehr notwendig ist)

aber wie so vieles wird ja oft nur nach dem scheint-zu-funktionieren Prinzip programmiert
 
Zuletzt bearbeitet:
Da mir die Sache auch keine Ruhe lässt habe ich noch ein bisschen getestet. Ich habe nun die LEN bei dem TRCV auf 0 gestellt, und einen Puffer von 100 Byte dran gehangen.
Somit schiebt mir der Empfangsbaustein die Pakete in meinen Empfangspuffer (wie im Schieberegister).
Nun habe ich mein Programm so angepasst dass ich in einer Schleife nach meinen Anfangsbyte, Endbyte, Auftragsbyte und Längenbyte suche. Wenn diese alle an der richtigen
Stelle sind nehme ich den Schleifenzähler als Offset für einen Poke block.

So weit so gut, das Problem nun ist dass mir der RCV LEN als empfangene Länge immer 100 angibt. Komisch dabei ist dass wenn ich es Online Beobachte an dem Baustein immer
17 steht, auch wenn ich in den IDB des RCV schaue, steht dort immer 17. Verschalte ich den wert allerdings auf meinen Baustein in dem die Laser Kommunikation abgehandelt wird
steht dort eine 100. Habe es schon mit Merkerworten usw. versucht, immer das gleiche.

Hat jemand eine Idee wie ich mir die Tatsächliche empfangene länge anzeigen lassen kann? Momentan scheint er ja immer die Größe des Puffers zu zeigen.


Hier noch mein Code zum Suchen nach dem Datensatz
Code:
//Daten empfangen und auf Richtigkeit prüfe 
IF #len_rcv = 17 AND NOT #Sende_Zähler THEN
    FOR #Schleife := 0 TO 16 DO
        IF #Buffer_rcv[#Schleife] = 16#02 AND
            #Buffer_rcv[#Schleife + 1] = 16#0E AND
            #Buffer_rcv[#Schleife + 2] = 16#92 AND
            #Buffer_rcv[#Schleife + 16] = 16#03 THEN
            #Schleife := #Schleife + 30;
            #Data_Ready := true;
            EXIT;
        END_IF;
    END_FOR;
END_IF;
           
           
IF #Data_Ready THEN 
    POKE_BLK(area_src := 16#84,
           dbNumber_src := 17,
           byteOffset_src := #Schleife,
           area_dest := 16#84,
           dbNumber_dest := 17,
           byteOffset_dest := 140,
           count := 17);
    #rec_dat_valid := true;
  ELSE
    #rec_dat_valid := false;
  END_IF;
END_IF;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe heute noch ein wenig mit dem Empfangsbaustein getestet. Ich habe nun unter dem TRCV ein Move block eingefügt, mit dem NDR des RCV als
Move freigabe, damit verschiebe ich meine Empfangslänge in einen Remanenten Speicher. Jetzt kommts!
Wenn ich mir diesen Wert z.B. in einer Beobachtungsliste anschaue hat er immer 100 (die länge meines Empfangspuffer). Sobald ich aber bei dem
Baustein in dem der RCV abgearbeitet wird online gehe und mir den Move befehl anschaue wird der Wert 17 (Tatsächliche Telegrammlänge)!

Wie zum Geier ist denn sowas möglich?


17 Byte (Online auf Baustein)
17.png


100 Byte (Offline auf Baustein)
100.png
 
Zuletzt bearbeitet:
Zurück
Oben