Frage zu FC5: DINT to STRING

Scanda

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

ich versuche einen DINT in einen STRING umzuwandeln. Dafür gibt es den FC5.

Nun will ich in einem FCxxx diesen Code in AWL ausführen:

Code:
      CALL  "DI_STRNG"
       I      :="DB_Umwandlung_Seriennr".STRING_STRUCT_DINT.Zahlenblock1
       RET_VAL:="DB_Umwandlung_Seriennr".Schmierstring
Der Zahlenblock1 ist ein DINT
Der Schmierstring ein STRING[18]
Die beiden Variablen sind in einem Global-DB gespeichert

Doch er macht die Umwandlung nicht bzw. er kopiert mir den String nicht auf den "Schmierstring".

Was läuft da falsch?

Danke schon mal im Voraus!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Aus Online-Hilfe

Die Funktion FC 5 wandelt eine Variable im DINT­Format in eine Zeichenkette. Die Zeichenkette wird mit einem führenden Vorzeichen darstellt. Ist die am Rückgabeparameter angegebene Variable zu kurz, findet keine Wandlung statt und das BIE­Bit wird auf "0" gesetzt.

Hast du das mal geprüft?
 
Aus der Step7-Hilfe:


STRING

Wenn Sie diesem Formalparameter einen Aktualparameter zuweisen, den Sie im Lokaldatenbereich des aufrufenden Bausteins definiert haben, so beachten Sie bitte:
Vor dem FC-Aufruf müssen Sie in der temporären Variable vom Datentyp STRING das Verwaltungsbyte "maximale Länge des Strings" mit der definierten Stringlänge beschreiben.

Das sind Byte 0 und Byte 1 der Stringvariable.
Prüfe mal, ob das in der DB-Variablen korrekt eingetragen ist. (Byte 0 und 1 des String im DB)
 
Also direkt Fehler gibt es nicht. Die CPU läuft ganz normal durch.

Am Ausgabestring ist alles "0". Selbst die ersten beiden Statusbits des Strings sind "0".

Zu klein dürfte der String[18] auch nicht sein, da auch bei sehr kleinen Zahlen das gleiche Problem besteht. Außerdem können DINT nur 10stellig (+Vorzeichen) werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also direkt Fehler gibt es nicht. Die CPU läuft ganz normal durch.

Am Ausgabestring ist alles "0". Selbst die ersten beiden Statusbits des Strings sind "0".

Zu klein dürfte der String[18] auch nicht sein, da auch bei sehr kleinen Zahlen das gleiche Problem besteht. Außerdem können DINT nur 10stellig (+Vorzeichen) werden.

Du mußt dir mal den String direkt ansehen in der Variablentabelle, byteweise.

Die beiden ersten Byte 0 und 1 enthalten die maximale und die tatsächliche Stringlänge. Steht da 0, macht der FC5 nichts, du mußt dann in Byte 0 eine 18dez eintragen, in Byte 1 sollte 11dez stehen. Das geht leider nur über Absolutadressierung oder über Zeiger. Zum Test kannst du das ja absolut machen, indem du dir aus dem DB die Absolutadresse für Byte 0 und 1 suchst.
 
Ich bin der Meinung, dass das Byte 1 von der FC beschrieben wird und somit lediglich das Byte 0 mit 18dez beschrieben werden muss.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe schon mal überlegt, ob ich es mir in die Signatur schreibe ...
ALLE Siemens String-FC's arbeiten (wie schon von Ralle und Aventinus geschrieben) NUR mit INITIALISIERTEN Strings - das heißt die Hearder-Informationen müssen vor der ersten Verwendung schon richtig eingetragen sein - in diesem Fall die deklarierte Länge. Durch das blosse Anlegen eines Strings in einem DB wird dieser Header in denselben NICHT eingetragen (keine Ahnung warum nicht).

Fazit:
Deklariere einfach den Header korrekt und die Welt ist wieder OK ...

Gruß
Larry
 
Zuletzt bearbeitet:
Hallo,
ich habe schon mal überlegt, ob ich es mir in die Signatur schreibe ...
ALLE Siemens String-FC's arbeiten (wie schon von Ralle und Aventinus geschrieben) NUR mit INITIALISIERTEN Strings - das heißt die Hearder-Informationen müssen vor der ersten Verwendung schon richtig eingetragen sein - in diesem Fall die deklarierte Länge. Durch das blosse Anlegen eines Strings in einem DB wird dieser Header in denselben NICHT eingetragen (keine Ahnung warum nicht).

Dann schreib bitte auch in deiner Signatur für welche Step7 Version das gelten soll.
Step7 5.5 trägt bei Strings in Datenbausteinen und auch bei Strings im statischen Bereich von Funktionsbausteinen die Header Daten, also Maximale und Aktuallänge, (zumindest bei mir) korrekt ein.
Imho muss man nur bei Temp-Variablen dafür sorgen dass die Header passend gesetzt werden.
In SCL reicht dazu das Initialisieren mit
stringVar := '';
 
Zuviel Werbung?
-> Hier kostenlos registrieren
der test mit dem bildchen was ich gemacht habe ist mit s7 v5.5 geproggt.
und du muss, wie du sehen kannst das byte 0 initialisiert werden.
 
der test mit dem bildchen was ich gemacht habe ist mit s7 v5.5 geproggt.
und du muss, wie du sehen kannst das byte 0 initialisiert werden.
Komisch, bei mir funktioniert das. Ich hatte dahingehend auch noch nie Probleme mit Strings in statischen Daten.

Wenn man einen komplett neuen Datenbaustein anlegt geht es direkt, bei einer Änderung an einem Datenbaustein muss man aber noch "Datenbaustein initialisieren" durchführen.
 
ich hab jetzt mal folgendes probiert.

simu gestartet und programm übertragen
und siehe da es geht. aber auch NUR solange man nicht byte 0 überschreibt. danach geht es nicht mehr.
keine ahnung was s7 da bei ERSTEN mal macht.

bild1

in der vat einmal dbb40 auf 0 gesetzt.
nix geht mehr. bild2
 

Anhänge

  • Zwischenablage02.gif
    Zwischenablage02.gif
    29,8 KB · Aufrufe: 15
  • Zwischenablage03.gif
    Zwischenablage03.gif
    29,5 KB · Aufrufe: 17
Zuviel Werbung?
-> Hier kostenlos registrieren
nachtrag.

übertrage ich, nachdem ich dbb40 mal auf 0 gesetzt habe den db "test" erneut in die cpu geht es wieder.

aus sicherheitsgründen würde ich aber immer hergehen und den string neu initalisieren bevor ich eine der stringfunktionen nutze.
 
ich hab jetzt mal folgendes probiert.

simu gestartet und programm übertragen
und siehe da es geht. aber auch NUR solange man nicht byte 0 überschreibt. danach geht es nicht mehr.
keine ahnung was s7 da bei ERSTEN mal macht.

bild1

in der vat einmal dbb40 auf 0 gesetzt.
nix geht mehr. bild2

Also ich sehe hier nichts verwunderliches.
Du bügelst den Header per VAT oder Programm mit falschen Werten platt und wunderst dich dass es nicht funktioniert?
 
ja. gebe ich dir recht.
das zeigt aber auch wie 'verwundbar' diese art des stringhandlings ist.
ich bleibe dabei und initialisiere das lieber neu bevor, aus welchem grund auch immer, plötzlich das ganze prog nicht mehr vernünftig läuft.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Step7 5.5 trägt bei Strings in Datenbausteinen und auch bei Strings im statischen Bereich von Funktionsbausteinen die Header Daten, also Maximale und Aktuallänge, (zumindest bei mir) korrekt ein.
Imho muss man nur bei Temp-Variablen dafür sorgen dass die Header passend gesetzt werden.
In SCL reicht dazu das Initialisieren mit
stringVar := '';

Hallo Thomas,
Danke für die nette Belehrung. Tatsächlich war es mir neu, dass Step7 die maximale Länge bei der Deklaration in den String-Header schreibt - wieder etwas gelernt.
Als deklarierte Länge wird bei mir allerdings nicht die Stringlänge eingetragen sondern 0 (auch wenn es ein neu erstellter DB ist und in dem deklarierten String etwas drinsteht).
Das dieses Verhalten bei DB's und im STAT-Bereich eines FB identisch ist kann ich mir vorstellen.
Das SCL das Paket gleich rund macht war mit auch bekannt. SCL kann hier auch (egal ob STAT oder TEMP) die Headerdaten komplett erstellen - also auch die tasächliche Länge und auch nach 10maligen hin- und herändern.

Bei TEMP-Variablen ist es immer noch so, wie von mir genannt (und natürlich auch von dir). Wo ist da der signifikante Unterschied ?

Da wir nach wie vor die Header-Info's des TE nicht kennen - was sagt dir, dass ich mit meiner Vermutung dann nicht doch Recht habe ?
Es ist für mich nicht ersichtlich, warum Step7 nicht auch mit einem nicht deklarierten String arbeiten kann, wenn es doch einen Pointer bekommt - ich hatte mir mal selber einen Baustein in dieser Art erstellt und mein Baustein konnte wunderbar auch ohne den Header arbeiten.
Naja - sei es drum ...

Gruß
Larry
 
Es ist für mich nicht ersichtlich, warum Step7 nicht auch mit einem nicht deklarierten String arbeiten kann, wenn es doch einen Pointer bekommt - ich hatte mir mal selber einen Baustein in dieser Art erstellt und mein Baustein konnte wunderbar auch ohne den Header arbeiten.

Du hast also einen Baustein geschrieben der mit korrupten String-Variablen arbeiten kann, schön.
Wie prüft dein Baustein denn ob der String in den z.B. Texte kopiert werden sollen überhaupt lang genug ist? String ist ein Pointer, also steckt dort nicht wie im Any-Pointer die Längenangabe mit drin.
Mal angenommen dein Baustein soll 'Hallo' in den String kopieren, jemand der deinen Baustein verwendet legt aber in einem DB den String mit der Länge 3 an, und nun?
 
@Thomas:
Was passiert, wenn du einem Baustein (von mir aus ein FC), der als Übergabeparameter einen String[5] (z.B.) haben will einen String[3] übergibst ?
 
Zurück
Oben