Step 7 Siemens Step 7 Simatic Manager (Classic) String CONCAT geht nicht

Burkhard

Level-2
Beiträge
161
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebe Siemens S7 Classic Experten,

ich habe im OB1 ein Netzwerk2 und dort rufe ich den FC2 (CONCAT) auf.

1687164358870.png

Wie ihr seht habe ich einen DB1001 mit den Strings sString1 und sString2.
Das Ergebnis wird in einem DB1002 mit dem String sOutput geschrieben.

1687164766853.png

Aber komischerweise klappt das nicht wie gewünscht. Der sOutput String bleibt leer. So als ob das CONCAT gar nicht funktioniert.

Verstehe ich nicht.

Vielen Dank für eure liebe Hilfe. Ich weiß echt nicht weiter. Man versteht die Welt nicht mehr :-(
 
Aber komischerweise klappt das nicht wie gewünscht.
Schaue dir mal an, wie der Datentyp "STRING" aufgebaut ist ( vor allem maximale/aktuelle Länge ):
Quelle: Aufbau einer STRING-Variablen
Aufbau einer STRING-Variablen


Einführung​


Eine Variable mit Datentyp STRING (Zeichenkette) ist maximal 256 Zeichen lang mit 254 Bytes Nettodaten. Sie beginnt in einem nicht optimierten Baustein an einer Wortgrenze (an einem Byte mit gerader Adresse). In einem optimierten Baustein kann sie an jeder Byte-Grenze beginnen.


Beim Anlegen der Variablen wird deren maximale Länge festgelegt. Bei der Vorbelegung bzw. beim Bearbeiten der Zeichenkette wird die aktuelle Länge (die tatsächlich benutzte Länge der Zeichenkette = Anzahl der gültigen Zeichen) eingetragen. Im ersten Byte der Zeichenkette steht die maximale Länge. Im zweiten Byte steht die aktuelle Länge. Danach folgen die Zeichen kodiert nach der im Windows eingestellten Codepage.


Aufbau einer STRING-Variablen:


 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du meinst ich muss das selber dort eintrage, das geht nicht automatisch?
Das sollte automatisch gehen. Aber der ZielString sollte schon lang genug sein, um String1 und String2 aneinander gereiht aufnehmen zu können (s. Marios Beitrag #2).
 
Bei dem ausgegebenen String ja, aber die Info´s fehlen ja (anscheinend) an den beiden Quellstrings.
Ich verstehe. Das muss ich also eigenständig und manuell im Quelltext selber machen. Es reicht nicht einen String mit Zeichen zu befüllen und zu glauben der Simatic Manager managed im Hintergrund die Einträge für die tatsächliche Länge?

Das ist ja ein Ding. Hätte ich nicht gedacht. Aber gut, dann mache ich das eben so.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es reicht nicht einen String mit Zeichen zu befüllen und zu glauben der Simatic Manager managed im Hintergrund die Einträge für die tatsächliche Länge?
Wenn du die von Hand per Variablentabelle befüllst, passiert da bei der Länge gar nichts.
 
Das sollte automatisch gehen. Aber der ZielString sollte schon lang genug sein, um String1 und String2 aneinander gereiht aufnehmen zu können.
Alle meine Strings haben die maximale Länge von 254.

1687166626178.png

Nutzen tue ich davon aber nur EIN Zeichen.

sString1: 2
sString2: A

Ergebnis sollte sein

sOutput: 2A

Ich dachte die aktuellen Längen vom Eingangs-String, werden vom Simatic Manager im Hintergrund gemanaged.
 
Wenn man 2 leere Strings (Strings mit der aktuellen Länge 0) mit CONCAT verkettet, dann kommt logischerweise ein leerer String mit der Länge 0 raus.

Das Problem ist, daß den CONCAT-Eingangsstrings erstmal ein Inhalt zugewiesen werden muß und die STRING-Headerbytes auf die korrekte Länge gesetzt werden müssen. Am einfachsten gibt man den Strings bei der Deklaration im DB einen Anfangswert (ungleich '', z.B. 'ABC') und initialisiert den String mit dem Anfangswert.

Leider gibt es in KOP/FUP keine Funktion, mit der man eine Stringkonstante (z.B. 'ABC') an eine Stringvariable zuweisen kann. Und man kann die STRING-Headerbytes nicht symbolisch adressieren. Man kann nur den einzelnen Zeichen in einem String mit MOVE etwas zuweisen, und muß die benötigten Längeninformationen mit MOVE in die Speicheradressen des STRING-Headers schreiben (geht nicht symbolisch). In KOP/FUP ist es am einfachsten, wenn man Template-Strings der benötigten Längen in DB deklariert und initialisiert (da werden die STRING-Header-Bytes korrekt initialisiert) und im Programm dann den einzelnen String-Zeichen die gewünschten Werte zuweist (bei Bedarf vorher den Template-String auf den Arbeits-String umkopieren).

In SCL kann man Stringkonstanten direkt an Stringvariablen zuweisen:
Code:
"DB1001".sString1 := 'ABC';
Wenn sString1 im "DB1001" an Adresse 2.0 deklariert ist, dann übersetzt der SCL-Compiler das zu:
Code:
      L     W#16#FE03     // 16#FE = 254 = max Länge, 3 = akt. Länge
      T     DB1001.DBW 2  // Stringheader von "DB1001".sString1
      L     B#16#41       // 'A'
      T     DBB 4         // sString1[1]
      L     B#16#42       // 'B'
      T     DBB 5         // sString1[2]
      L     B#16#43       // 'C'
      T     DBB 6         // sString1[3]

Das kann man in KOP/FUP so schreiben (leider nicht vollsymbolisch):
Code:
W#16#FE03 -| MOVE |-DB1001.DBW 2

       'A'-| MOVE |-"DB1001".sString1[1]

       'B'-| MOVE |-"DB1001".sString1[2]

       'C'-| MOVE |-"DB1001".sString1[3]
oder in AWL:
Code:
      L     W#16#FE03
      T     DB1001.DBW 2
      L     'A'
      T     "DB1001".sString1[1]
      L     'B'
      T     "DB1001".sString1[2]
      L     'C'
      T     "DB1001".sString1[3]
oder in einen String in TEMP, registerindirekt adressiert und deshalb innerhalb TEMP verschiebbar:
Code:
TEMP: irgendwas : BOOL;
      tmpString : STRING[8];

// Netzwerk
      LAR1  P##tmpString
      L     W#16#0803
      T     LW [AR1,P#0.0]
      L     'A'
      T     LB [AR1,P#2.0]
      L     'B'
      T     LB [AR1,P#3.0]
      L     'C'
      T     LB [AR1,P#4.0]

Harald
 
Zurück
Oben