TCP/IP ASCII Kommunikation

basstscho

Level-1
Beiträge
40
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich (Grundlagen in der SPS-Programmierung) beschäftige mich gerade damit eine Komponente an eine SPS S7-300 anzubinden, die ausschließlich per ASCII-String über TCP/IP-Kommunizieren kann.
Hierbei muss von der SPS eine Verbindung zum Port 4444 der Komponente aufgebaut werden und dann eine Anfrage in Form eine ASCII-Strings gesendet werden (Trennzeichen: - ; Beispiel: 0.0 2.2 2.3 3.3-). Für jede Anfrage bekommt man eine Antwort auf einem anderen Port (5555) in dem selben Format zurück.
Zur Kommunikation habe ich mir schon: http://support.automation.siemens.c...lib.csinfo&lang=de&objid=29737950&caller=view durchgelesen. So wie ich das daraus lesen, benötige ich somit einmal eine aktive (senden der Anfrage) und eine passive (empfangen der Antwort) Verbindung. Soweit richtig?

Meine Kernfrage beschäftigt sich nun mit dem Zerlegen der ASCII-Antwort-Zeichenkette. Die Antwort kann unterschiedlich viele Zeichen haben, endete aber immer mit dem selben Trennzeichen und hat die gleiche Anzahl an Zahlenwerten - Trennzeichen zwischen den Zahlenwerten ist das Leerzeichen, wie z.B.:
0 2.1 2.22 1.1-
0.1 2.111 2.2 3.3-

Wie kann ich damit am besten Umgehen und auf einzelne Zahlenwerte zugreifen? Mein theoretisches Vorgehen wäre:
- Sicherstellen, dass ich eine gesamte Antwort vorliegt (sprich das Endzeichen am Ende des Strings ist und die Anzahl an Zahlenwerten stimmt).
- String zerlegen und die Zahlenwerte in einzelne Strings überführen.

Mit welchen FBs mache ich das am besten und Ressourcensparendsten? Mittels diverese Programmiersprachen habe ich das schon öfters gemacht, kenne mich aber noch nicht sonderlich gut mit allen FB der SPS ab. Daher würde ich diese gerne vorab Abklären, bevor ich mich dazu entschließe, dass alles auf der SPS S7-300 zu implementieren.

Ich danke euch schonmal ganz herzlich für eure Hilfe,
Johannes
 
Mit dem S-Beispiel aus deinem Link dürfte die Kommunikation laufen, du brauchst dafür keine Verbindung in NetPro zu projektieren.

Zu deiner "Kernfrage":
Ich würde auf die FB´s verzichten, weil du wohl stets unterschiedliche Längen empfängst. Das wird zu umständlich.

Wenn der NDR vom T_RCV dir meldet, dass neue Daten empfangen wurden (Empfang fertig), kopierst du dir den Empfang-String Zeichen für Zeichen in einen anderen Datenbereich.
Vor dem Kopieren jedes Zeichens prüfst du es, ob es ein Trennzeichen ist.
Wenn dann ein Trennzeichen kommst, lässt du es aus und kopierst das folgende Zeichen in einen anderen Datenbereich.
Natürlich musst du neben der Prüfung auf Trennzeichen auch die Prüfung auf Endezeichen durchführen, beim Endezeichen brichst du dann ab.

Letztendlich hast du dann mehrere Datenbereiche, die die einzelnen Zahlenwerte enthalten und kannst diese jede für sich auswerten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
-> Ja

Vorab:
Der Bibliotheksbaustein (FC39 STRNG_R) wandelt nur ein gewisses Format.
Alternativ besorgst du dir hier:http://support.automation.siemens.com/WW/view/de/23533568 den FC104 ("String_R").
Der macht fast was du willst, braucht allerdings ein führendes +/-.

Davon ausgehend es sind immer Gleitpunktzahlen, würde ich:
  1. Einmal über den Sting laufen und die Positionen der Leerzeichen abspeichern
  2. Den FC 104 - für x Elemente - jeweils mit der Differenz der Positionen an LEN aufrufen
Die ersten beiden Bytes im String halten die maximale und aktuelle Länge.
Du legst also am RECV erst ab Byte 2 an und kopierst die empfangene Länge nach Byte 1.

Die variable Länge wird vermutlich auch noch ein Problem (am RECV).

Grüße
 
... Die ersten beiden Bytes im String halten die maximale und aktuelle Länge.
Du legst also am RECV erst ab Byte 2 an und kopierst die empfangene Länge nach Byte 1.

Die variable Länge wird vermutlich auch noch ein Problem (am RECV).

ja, deswegen :rolleyes:

und ich denke nicht, dass der ASCII-String mit den beiden S7-Headerbytes empfangen wird ;)
 
Da du unterschieldiche längen empfangen willst, und in deinem telegramm kein Kopf mit der länge existiert, denke ich musst du die t_send/t_recieve bausteine verwenden, da diese telegramme ohne bestimmte längen können. Soweit Ich weiss brauchst du dann aber eine PN CPU.

Oder du nimmst die normalen send_reciev bausteine, musst dann aber byteweise empfangen...

Dann würde ich den empfangen string byteweise durchlaufen und parsen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe für das Projekt eine gebrauchte 319F-3 PN/DP zur verfügung. Also kann ich wohl zwischen send_recieve und t_recieve auswählen. Was geht denn nun schneller? Direkt Byteweise empfangen oder den gesamten String zerlegen? Wie läuft das in der CPU ab? Wird während jedem Zyklus nur einmal empfangen? Oder kann ich sowas in einen extra "Thread" auslagern (ich mache sons ziemlich viel mit C++)?

Besten Dank für eure Hilfe,
Johannes
 
Wie das abläuft, wird dir außer den Bausteinschreibern keiner sagen können.
Die Idee mit dem Thread ist zwar nett, aber sowas gibt es nicht.

Wovon du ausgehen kannst:
FB 64 "TRCV" is an asynchronously functioning FB, which means that its job processing extends over several FB calls.

Den Baustein musst du sowieso verwende, warum also nicht gleich im AdHoc Modus den ganzen String lesen.
Die byteweise Geschichte gilt nur für den AG_Recv der CPs, weil er das eben nicht kann. (Korrigiert mich, wenn ich falsch liege)

Weil ich gerade gebraucht lese, es gibt Einschränkungen für die lokalen Ports:
http://support.automation.siemens.com/WW/view/de/44240604 -> S461
 
Jetzt bin ich etwas erstaunt.
Ich hatte den Eindruck, mit dem S-Beispiel aus deinem Eröffnungs-Beitrag läuft die Kommunikation bereits und deine "Kernfrage" bezieht sich auf das Zerlegen des ASCII-Strings ?
Offenbar hast du aber noch mit beiden Aufgaben ein Problem ?

Also zunächst einmal zu deinen letzten Fragen:

Hallo zusammen,

ich habe für das Projekt eine gebrauchte 319F-3 PN/DP zur verfügung. Also kann ich wohl zwischen send_recieve und t_recieve auswählen. Was geht denn nun schneller? Direkt Byteweise empfangen oder den gesamten String zerlegen? Wie läuft das in der CPU ab? Wird während jedem Zyklus nur einmal empfangen? Oder kann ich sowas in einen extra "Thread" auslagern (ich mache sons ziemlich viel mit C++)?

Besten Dank für eure Hilfe,
Johannes

Du hast eine PN-CPU und damit keine Wahl, also nimm dein S-Beispiel aus deinem eigenen Beitrag #1, um den ASCII-String zu empfangen !

Und nein, es wird nicht während eines jeden Zyklus empfangen, mit Aufruf des RCV-Bausteins meldet der sich mit "NDR", wenn die gesamte Länge des ASCII-Strings empfangen und im Empfangspuffer abgelegt wurde. Dies kann sogar mehrere Zyklen dauern.

Und der empfangene ASCII-String wird ENTWEDER wie in Beitrag #2:

Wenn der NDR vom T_RCV dir meldet, dass neue Daten empfangen wurden (Empfang fertig), kopierst du dir den Empfang-String Zeichen für Zeichen in einen anderen Datenbereich.
Vor dem Kopieren jedes Zeichens prüfst du es, ob es ein Trennzeichen ist.
Wenn dann ein Trennzeichen kommst, lässt du es aus und kopierst das folgende Zeichen in einen anderen Datenbereich.
Natürlich musst du neben der Prüfung auf Trennzeichen auch die Prüfung auf Endezeichen durchführen, beim Endezeichen brichst du dann ab.

Letztendlich hast du dann mehrere Datenbereiche, die die einzelnen Zahlenwerte enthalten und kannst diese jede für sich auswerten.

ODER wie im Beitrag #5 vom Jochen (mit anderen Worten) beschrieben entsprechend ausgewertet.

Da du unterschieldiche längen empfangen willst, und in deinem telegramm kein Kopf mit der länge existiert, denke ich musst du die t_send/t_recieve bausteine verwenden, da diese telegramme ohne bestimmte längen können. Soweit Ich weiss brauchst du dann aber eine PN CPU.

Oder du nimmst die normalen send_reciev bausteine, musst dann aber byteweise empfangen...

Dann würde ich den empfangen string byteweise durchlaufen und parsen.
 
Zurück
Oben