CP340 RS232 - Variable Stringlänge auswerten und verarbeiten (P_RCV)

poppycock

Level-1
Beiträge
253
Reaktionspunkte
21
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich möchte die Funktion eines CP340 RS232 kennen lernen und benutze zum Einstieg das Projekt Einlesen von drei Längenmaßen (Strings) in den CP340 über ein ASCII-Protokoll von der Siemens-Homepage: http://support.automation.siemens.com/WW/view/de/8797119
Die Funktion des Programms ist im aufgeführten Link wunderbar beschrieben, deshalb gehe ich nun auch nicht weiter darauf ein. :rolleyes:

Soweit klappt das Programm so wie es soll (ist ja schließlich auch Payware), aber die statischen Stringlängen von Länge, Breite und Dicke möchte ich gerne variabel gestalten.

Die statischen Daten von der Siemens-Homepage:
"L2000,B701,D205" (Länge = 2000mm, Breite = 701mm, Dicke = 205mm)

Ein Auszug aus dem SPS-Programm:
CALL FC26
[...]
L := 4 (Länge des Strings)
P := 2 (ab welcher String-Position der String gelesen wird)
[...]

Erklärung zum Auszug:
Der String
L2000,B701,D205 wird ab Position 2 mit der Länge von 4 Zeichen gelesen. Gefiltert kommt nun 2000 heraus.
Bekomme ich statt 2000 einen drei- bzw. fünfstelligen Wert, so stimmt die Angabe L:=4 nicht mehr und P wird auch verschoben.

Es geht mir im Grunde nur um L und P, denn beide Angaben werden bei meinem Vorhaben variabel, und da passt am Ende nichts mehr, wenn ich so den FC26 weiter verwende...
Das SPS-Programm sollte in AWL bleiben und nicht in Richtung SCL driften.

Brauche ich einen anderen FC?
Jedenfalls brauche ich eine andere Auswertung, aber welche und wie?

Gruß,
poppycock
 
Hallo,
du must dir einen "Interpreter" basteln.
Du scannst den String (Zeichen für Zeichen) nach dem "L". Das Zeichen danach (Position von L +1) ist dein erstes Werte-Byte. Den Index merken. Nun suchst du nach dem ersten "," ab "L". Das Ende deiner L-Variablen ist nun Position von "," -1. Diesen Wert auch merken. Die Länge deines ersten Wertes ergibt sich nun aus den gemerkten Positionen. Den Wert kannst du nun mid der MID-Funktion aus der Bibliothek ausschneiden und mit der STRING_I-Funktion (auch aus der Bibliothek) in eine Zahl umwandeln. Die Nummern der beiden FC's weiss ich gerade nicht, aber die Namen passen und dann solltest du sie finden.
Genauso verfährst du mit den weiteren Angaben - Suche nach "B" und dann nach Komma - Suche nach "D" und dann bis Ende.

Das wäre auch in AWL zu lösen - schöner ginge es allerdings in SCL (dann kann man es besser lesen und verstehen was das soll) aber SCL kam ja für dich nicht in Frage ...:???:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry Laffer,

okay, hab's mir schon gedacht, dass es nicht anders geht.
Dann muss ich mir Gedanken machen, wie ich der SPS mitteile, dass diese den String nach definierten Zeichen absuchen soll. Ohweh...
In SCL wäre es sicherlich einfacher, aber auf der Arbeit wird nichts mit SCL programmiert, dort klammert man sich noch total an AWL/KOP/FUP.

Außerdem ist es total interessant, dass die von dir angesprochenen FC's für dieses Projekt schon von Siemens verwendet werden! :)
MID = FC26 (String zwischen L und P aufbereiten)
STRNG_I = FC38 (String nach INT umwandeln)

Also müsste ich nur eine Funktion erstellen, die mir die Länge eines Stringteils ermittelt (ab P mit der Länge L) und diese dann in die Funktion
Code:
CALL FC26
[...]
L := 4 (Länge des Strings)
P := 2 (ab welcher String-Position der String gelesen wird)
[...]
an die Stelle P und L dynamisch einfügt.

Ist das so schwierig oder sehe ich den Wald vor lauter Bäumen nicht mehr?
Theoretisch ist es klar und ich wüsste, wie ich das mittels if/then/else lösen könnte, aber solche Funktionen in AWL erstellen, wow, da steckt noch 'was quer bei mir! :ROFLMAO:

Gruß,
poppycock
 
Hallo,
es gibt auch noch eine Funktion "FIND" (FC11). Diese sucht dir die Position eines Zeichens oder einer Zeichenkette in einem String. Hatte ich eben glatt vergessen. Damit hast du den Baukasten eigentlich zusammen.

Du suchst jetzt mit FIND nach dem 1. Komma. Jetzt hast du den 1.Teilstring. Für die weitere Suche schneidest du mit RIGHT (FC32) den Rest ab und wertest den im Weiteren aus. Wie hatte ich ja beschrieben.
Ich würde mir jetzt einen DB bauen, der die Teil-Ergebnisse aufnehmen kann und von dem du die Teil-Ergebnisse umwandeln kannst. Das sollte jetzt eigentlich nicht mehr so schwierig sein ...;)
 
Hallo,

mit dem FC11 "FIND" habe ich gerade einen Erfolg gehabt, d.h. es wird das erste Komma gefunden und als Ausgabe bekomme ich die Stelle.
Spiele nun mit dem Baustein FC26 "MID" rum, oder ist der FC32 "RIGHT" besser geeignet? Außerdem muss ich den restlichen String noch weiter durchsuchen!
Am besten schreibe ich mir den Ablauf auf einen Zettel, denn sonst wird es doch ziemlich unübersichtlich! ;)
Kann Siemens nicht mal ein besseres String-Handling einpflegen?

BTW: Ich benuze in den Strings keine Buchstaben mehr, soll heißen: aus L2000,B701,D205 ist 2000,701,205 geworden.

Gruß,
poppycock
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kann Siemens nicht mal ein besseres String-Handling einpflegen?

Ist halt nicht wirklich eine Hochsprache ...
Aber ich hatte ja auch erwähnt, dass es mit SCL leichter sein würde - ich weiss, dass hatten wir schon ...

Zu deiner Frage:
ich würde mir nach erfolgten FIND mit der Funktion RIGHT den Reststring ausschneiden (Länge absolut - Position FIND). In diesem neuen String kannst du dann wieder mit FIND das Komma suchen.
Deinen erster Wert kannst du mit LEFT isolieren (bis Position FIND -1) und das dann mit STRING_I (oder STRING_D für DINT) umwandeln zu einer Zahl.
Von dem Teilstring verfährst du wie gehabt ...

Ich denke, du hast es jetzt schon fast geschafft ...:-D
 
ich würde mir nach erfolgten FIND mit der Funktion RIGHT den Reststring ausschneiden (Länge absolut - Position FIND). In diesem neuen String kannst du dann wieder mit FIND das Komma suchen.
Deinen erster Wert kannst du mit LEFT isolieren (bis Position FIND -1) und das dann mit STRING_I (oder STRING_D für DINT) umwandeln zu einer Zahl.
Von dem Teilstring verfährst du wie gehabt ...

Vielen Dank für den Gedankenanstoß!
Ich habe deinen Vorschlag umgesetzt, musste aber leider feststellen, dass ich die "Länge absolut" nicht bekomme, sonst aber alles funktionieren sollte.

Die CP340-Parameter werden folgendermaßen aufgerufen:
CALL "P_RCV" , "InstanzDB2"
EN_R :=M2.0
R :=M0.1
LADDR :=300
DB_NO :=19
DBB_NO:=2
NDR :=M0.0
ERROR :=M0.2
LEN :=MW28
STATUS:=MW30

...hier stehen die Anweisungen drin...

Wenn neue Daten eingehen, wird das so erfasst:
UN M 0.0
SPB JUMP
L MW28
T DB19.DBB 1
JUMP: nop0

Die Daten werden via RS232 übertragen, die SPS arbeitet mit den Daten, aber die LEN-Angabe, also MW28 ist immer Null.
Da frage ich mich: Warum?

Gruß,
poppycock
 
Also ich hab das gerade mit einem Matrix-Scanner, extern getriggert wird, ausprobiert.
Wenn NDR True wird kopiere ich Len in ein MW und da steht auch tatsächlich die Länge der empfangenen Daten richtig drin.

Code:
CALL  "P_RCV" , "IDB Scanner"
       EN_R  :="Empfang_Ein"
       R     :="Reset"
       LADDR :=256
       DB_NO :=100
       DBB_NO:=10
       NDR   :="Neue Daten empfangen"
       ERROR :="Error"
       LEN   :=DB100.DBW0
       STATUS:=MW102

      UN    "Neue Daten empfangen"
      SPB   NIX

      L     DB100.DBW    0
      T     MW   104

NIX:  NOP   0
Das sieht eigentlich aus wie bei dir.

Zu Beachten ist, daß Len tatsächlich sofort wieder 0 ist, ich kann im Status gar nicht sehen, daß es sich überhaupt ändert. MW104 enthält hingegen die Länge, bis ich einen neuen Code scanne. Sie dir also mal DB19.DBB 1 an, was steht denn darin?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ralle!

Sieh dir also mal DB19.DBB 1 an, was steht denn darin?
Im DB19.DBB 1 stand statisch eine 52 drin! In der SPS läuft nur die RS232-Sache, andere Programmteile sind nicht drauf!
Habe also das Projekt neu erstellt, aber das hat nur teilweise etwas gebracht!
Die Länge wird zwar jetzt gespeichert, aber ich habe festgestellt, dass im DB19.DBB 1 ein Zeichen mehr steht als der String lang ist. Sende ich fünf Zeichen, wird im DB19.DBB 1 eine sechs angezeigt. Ist das normal? Ich sende mit meinem PC einen Teststring an den CP340. Übertragungsprotokoll: ASCII, 9600,8,E,1
Kann es sein, dass das letzte Zeichen das Stopbit ist?
Habe jedenfalls vom MW28 eine 1 abgezogen, und nun bekomme ich die Stringlänge.

Gruß,
poppycock
 
Das hab ich noch nicht überprüft, ich bekomme einen Scancode und habe testweise einen Briefmarkencode auf einem alten Brief genommen. Von dem kenn ich die Länge ja nicht :ROFLMAO:. Aber, wenn das immer so sein sollte, geht es ja mit dem Abzug von 1, ich werde das bei Gelegenheit mal ansehen.
 
Hallo Ralle,

ich habe gerade überprüft, warum bei einer Stringlänge von fünf Zeichen im DB19.DBB1 sechs Zeichen eingetragen werden:
Es ist das <CR>-Zeichen, welches vom PC mit übertragen wird und ich als Endzeichen für die Datenübertragung im CP340 parametriert habe.

Gruß,
poppycock
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es funktioniert!

Hallo,

das Programm funktioniert nun und möchte kurz erwähnen, woran es lag!

Die Daten werden via RS232 übertragen, die SPS arbeitet mit den Daten, aber die LEN-Angabe, also MW28 ist immer Null.
Da frage ich mich: Warum?

Ich speicherte die tatsächliche Stringlänge zwar richtig ab, aber im Programmcode zur weiterführenden Bearbeitung des Strings hatte ich noch das MW28 stehen gehabt.
Ein Austausch mit DB19.DBB1 (gespeicherte tatsächliche Stringlänge) führte zum Erfolg!
Grund:

Zu beachten ist, daß LEN tatsächlich sofort wieder 0 ist.

Vielen Dank an Larry Laffer, Ralle und den "echten" sps-concept!

Teil 1 des "Projektes" ist jetzt abgeschlossen! :ROFLMAO:

Gruß,
poppycock
 
Zurück
Oben