MID Funktion beginnt an falscher Stelle

Alpini

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

mein erster Beitrag, und gleich ein Problem mit einer verflixten String-Funktion :D

Ich versuche aus einer String Variable, die in einem Datenbaustein liegt, mit der MID Funktion zwei Zeichen zu extrahieren. Der String hat folgenden Aufbau:

"<01BOX000001>"

aus dem String brauche ich das 2. und 3. Zeichen, also die "01". Als "P" Parameter habe ich der MID Funktion 2 und als "L" Parameter ebenfalls die 2 übergeben. Als Rückgebewert kommt so allerdings der String "BO", die Ausgabe ist also um 2 Zeichen nach rechts verschoben. Ich vermute, dass das irgendwie mit den ersten zwei String-Bytes Max.-Länge und Akt.-Länge zusammenhängt, nur die Vermutung allein hilft mir irgendwie nicht mehr weiter.

In den DB gelangt der String, nachdem er von einem CP340 "FB P_RCF" empfangen wird. Gibt es eine Möglichkeit Strings direkt zu beobachten? Da ich noch etwas grün bin, habe ich mir beholfen mit Blockmove den String in ein Char-Array zu kopieren :ROFLMAO: Im Char-Array sieht aber alles bestens aus.

Viele Grüße vom Alpini
 
Du holst mit deinem Parametern ab dem 2. Zeichen 2 Zeichen. Und nicht vergessen bei 0 anfangen zu zählen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In Step 7 beginnt ein String grundsätzlich mit den Kopf-Parametern Gesamt-Länge und tatsächliche Länge (oder umgekehrt - kann ich jetzt gerade nicht nachsehen). Diese beiden Informationen stehen üblicherweise auf Byte-Position 0 und 1. Deine Nutzdaten des Strings beginnen ab Byte 2. Das ist auch der Ansatz für die MID-Funktion.
Fazit:
Ich nehme an, dass die Daten falsch in den String übertragen worden sind, bzw. du den Schreib-Pointer bei der Receive-Funktion falsch gesetzt hast. Das müßtests du kontrollieren und korrigieren ...

Gruß
LL
 
Ich habe es gerade mal probiert. Wenn ich den String mit den Parametern P=2 und L=2 einlese, dann bekomme ich "01" als Ergebnis.
Also wie LL auch schon sagte, die beiden Verwaltungsbytes mitzählen. Ich vermute auch mal, das der String nicht ordentlich in die Variable geschrieben wurde.

<EDIT>
Mist, falsch erklärt. Zählen beginnt beim 1. Zeichen also dem "<". Von da an 2 Zeichen. Also die Verwaltungsbytes nicht mitzählen.
</EDIT>
 
Zuletzt bearbeitet:
whow Leute, Danke für die flotten Antworten.

Ja, in die Richtung wird mein Problem gehen. Ich habe mir jetzt nochmal den FB P_RECV angeschaut, da gibt es den Eingang DBB_NO = Empfangsdaten ab Datenbyte. Der Wert war erst 0 und ich habe den jetzt auf 2 gesetzt. Seit dieser Änderung liefert die Mid Funktion überhaupt nichts mehr zurück. Ich vermute jetzt also, dass der String Inhalt zwar beschrieben wurde, doch das Byte aktuelle Länge überhaupt nichts enthält. Vor dieser Änderung wurden wohl dann vermutlich meine ersten zwei String Bytes als MaxLen und ActLen interpretiert, weshalb die MID Funktion immerhin etwas getan hat.

Den besagten String, aus welchem ich etwas extrahieren möchte, versende ich nebenbei auch noch per TCP-Protokoll und empfange ihn mit einem selbst geschriebenen Programm am PC. Seit der letzten Änderung kommen jetzt zwei Leerzeichen vor dem String beim PC an. Da am TCP-Send Baustein die Sendedaten vom Typ ANY sind, wird also der String nicht überprüft und es werden stur alle String Bytes inkl. den ersten zwei versendet, so langsam geht mir ein Licht auf. Sorry ich komme aus der Hochsprachenprogrammierung (C#), da setze ich vermutlich manchmal noch etwas zu viel vorraus :ROFLMAO:

<Edit> Es kommen im TCP Paket nicht zwei Leerzeichen vor dem String sondern Hex: FE und Hex: 00. FE=254 also die Gesamtlänge des Strings und 00 ist die blöderweise noch nicht beschriebene Aktuelle-Länge des Strings </Edit>

Die Länge der Empfangsdaten liefert mir der FB P_RECV zurück, scheinbar muss ich die nun noch irgendwie in das 2. Byte des Strings bekommen, nur wie? Und sehr nett wäre es noch, wenn ihr mir verraten würdet, wie ich einen String beobachten kann, blind programmieren ist wirklich nicht toll :ROFLMAO: Ich benutze Step7 V5.4. Kann man die betreffende Variable statt einem string evtl. als etwas anderes deklarieren, Array of Bytes, etc.? Die MID Funktion sollte aber halt noch damit zurecht kommen.

Gruß & Danke sagt der Alpini
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Die MID-Funktion kommt nur mit einem String zurecht.
Dein Receive-FC hat vielleicht auch schon ein Problem mit dem String, wenn er vorher nicht initialisiert war (soll heissen MyString := '"" - in SCL).
Ich nehme an, du hast das Programm mit Step 7 erstellt.
Zum Initialisieren schreibst du :
Code:
L 0
T akt_Length
L deklarierte_Länge
T max_Length
auf die gleiche Weise könntest du nach dem Receive auch diese Daten in den Kopf bekommen. Es könnte aber auch sein, dass sie dann schon passend darin stehen.

Gruß
LL
 
Nachtrag:
die Receive-Länge bekommst du einfach per L / T in den String. Nehmen wir an, derselbe steht im DB10 ab DBB0, dann schreibst du :
Code:
L Rcv_Length
T DB10.DBB0
Um den String z.B. in der Variablentabelle beobachten zu können musst du diesen dort DWORD-weise auflisten und in der Darstellung dann auf Zeichen umschalten. Mehr wie DWORD (oder eine andere 4-Byte-Variable) wird auf einmal von Siemens nicht dargestellt ...

Gruß
LL
 
nein, die Aktuelle String Länge steht nicht in der String-Variable - habe meinen Beitrag oben gerade nochmal editiert. Das konnte ich im vom PC empfangenen TCP Paket sehen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... dann siehe dazu bitte meinen Beitrag vor diesem ...

Nachsatz:
Nachträgliches Editieren erhöht bei solchen Sachen nicht die Übersichtlichkeit um Probleme lösen zu können. Besser: immer einen neuen Beitrag erstellen und sich ggf. auf den letzten Beitrag beziehen ...
 
Editieren = unübersichtlich -> ja, das habe ich auch gerade bemerkt :ROFLMAO:

dein anderer Beitrag -> wird gerade umgesetzt :s12:
 
Ich versuche aus einer String Variable, die in einem Datenbaustein liegt, mit der MID Funktion zwei Zeichen zu extrahieren. Der String hat folgenden Aufbau:

"<01BOX000001>"

aus dem String brauche ich das 2. und 3. Zeichen, also die "01". Als "P" Parameter habe ich der MID Funktion 2 und als "L" Parameter ebenfalls die 2 übergeben.

Hier ist noch mal ein kurzes Programmbeispiel:

Code:
ORGANIZATION_BLOCK OB 1
TITLE =Hauptprogramm
//15
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'STRING'
VERSION : 1.0
 
VAR_TEMP
  OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ;   //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ; //Priority of OB Execution
  OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ;   //Reserved for system
  OB1_RESERVED_2 : BYTE ;   //Reserved for system
  OB1_PREV_CYCLE : INT ;    //Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ;   //Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =STRING
 
      CALL FC    26 (
           IN                       := DB200.IN_STRING,
           L                        := 2,
           P                        := 2,
           RET_VAL                  := DB200.OUT_STRING);
      NOP   0; 
 
END_ORGANIZATION_BLOCK

Gibt es eine Möglichkeit Strings direkt zu beobachten? Da ich noch etwas grün bin, habe ich mir beholfen mit Blockmove den String in ein Char-Array zu kopieren.

Einen STRING kannst Du in der VAT beobachten.

Gruß Kai
 

Anhänge

  • OB1.pdf
    4,7 KB · Aufrufe: 6
  • DB200.pdf
    3,9 KB · Aufrufe: 6
  • VAT.jpg
    VAT.jpg
    264,5 KB · Aufrufe: 12
Danke auch dir Kay für den Tip mit dem Beobachten, um die interessanten ersten zwei Bytes + ein paar weitere zu beobachten ist das wohl auf alle Fälle sinnvoller also meine Methode. Um komplette, lange Strings zu beobachten ist vielleicht sogar meine Blockmove Methode nicht so schlecht, wenn man vom zusätzlichen Speicherplatzbedarf für den Char-Array DB mal absieht:)
 
Strings beobachten:

Zum beobachten nicht auf die Brille drücken, sondern den baustein Online öffen. Leider werden Strings dann nur mit F5 aktualisiert.

Gruss Andy
 
Zurück
Oben