String zusammen setzen und als Array of Char abspeichern - ohne SCL

Zuviel Werbung?
-> Hier kostenlos registrieren
Ähh ... DBW 1,2,3,4 ?????
DBW's bitte nur in 2er Schritten hochzählen, weil z.B. das DBW0 das DBB0 und 1 beinhaltet, DBW1 das DBB1 und 2 usw.
Ansonsten sollte es dann passen ...

Ja sorry mein Fehler ... aber auch wenn ich in der VAT bei DBB0 starte (Array of Char), hab ich noch immer sonderbare Strich-Zeichen. Außer bei DBB3 steht eine 9 (Zeichen) und hier wandert der Wert auch die ersten 10 (bzw 9) Sekunden. Dann bleibts aber bei 9 (Zeichen) stehen. Als DEZ ist es dann die 57
 
Ich nehme mal an, dass bei DBB0 irgendeiner der Strings anfängt.
Wenn du dir den in der VAT anzeigen lassen willst, dann mußt du dir die ersten beiden Bytes, die ja der Header sind, als WORD oder so darstellen lassen. Denn Rest kannst du dir dann in maximal DBD's als Zeichen anzeigen lassen. Da sollte dann auch etwas passendes drin stehn.
Falls dem nun nicht der Fall ist müssen wir das Ganze mal einzeln debuggen.
Dafür wäre es dann ganz interessant, wenn du erstmal nur einen String bildest und mitteilst, was wann wo drin steht.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ach ... noch etwas :
was machst du, wenn deine Einzel-Variablen (z.B. die Sekunden) vom Betrag her nur einstellig sind ? In dem Fall würdest du nur das erste Byte des Strings beschreiben und das 2. so lassen, wie es zu letzt war. Deswegen hatte ich dir das mit dem 100 draufaddieren vorgeschlagen (du erinnerst dich) dann wird nämlich aus z.B. 7 als Wert 107 und die rechten 2 Zeichen dieses Strings beinhalten dann "07" ...
 
Ich nehme mal an, dass bei DBB0 irgendeiner der Strings anfängt.
Wenn du dir den in der VAT anzeigen lassen willst, dann mußt du dir die ersten beiden Bytes, die ja der Header sind, als WORD oder so darstellen lassen. Denn Rest kannst du dir dann in maximal DBD's als Zeichen anzeigen lassen. Da sollte dann auch etwas passendes drin stehn.
Falls dem nun nicht der Fall ist müssen wir das Ganze mal einzeln debuggen.
Dafür wäre es dann ganz interessant, wenn du erstmal nur einen String bildest und mitteilst, was wann wo drin steht.

Gruß
Larry

Naja ich kann ja ruhig den Header anzeigen lassen, danach müssen dann aber ja irgendwo die richtigen Zeichen anfangen. Die speichere ich ja als array of char und somit muss er doch auch in den einzelnen Bytes die Zeichen anzeigen?!

Ich habe ja tatsächlich die Sekunden fast richtig drin gehabt - allerdings sind die nur von 1-9 gelaufen, die Zehnerposition lief nicht richtig. Minuten und Stunden garnicht.


Ich dachte es liegt evt. an den Vorzeichen der Int-Zahlenwerte und habe jetzt mal hinter die Int2String-Funktionen die MID-Funktion gesetzt, um 2 Zeichen ab dem 2. Zeichen in die Stunden_Str, Minuten_Str, Sekunden_Str zu schreiben. Half aber auch nichts...



Ich bastel das jetzt mal um, ohne Concat usw. Dann schauen wir mal was da drin steht



EDIT1: Wenn ich nur den Sekunden-Str (ohne Vorzeichen über MID) mittels BLKMOV in den DB schreibe, bekomme ich:

DBB2 und DBB3 läuft von 0-9 (ZEICHEN) im Sekundentakt, danach steht in
DBB2 die 2 (DEZIMAL) und DBB3 bleibt auf 9 (ZEICHEN) stehen, bis es wieder von vorne los geht



EDIT2: Komme der Sache wohl auf die Spur. Die STRING-Vars waren nur mit einer Länge von 2. Wenn aber erstmal das Vorzeichen mit drin ist, brauche ich ja 3.
Nachdem ich das geändert habe, laufen nun insgesamt 3 Werte (Bytes) mit, aber immernoch fehlerhaft


DBB3+4 läuft von 0-9 im Sekundentakt
DBB2 zeigt die Zehnerstelle

Nach einem vollen Durchlauf (Zehnerstelle eigentlich 0) laufen DBB2+3 im Sekundentakt, bis die ersten 10 Sekunden voll sind (Zehnerstelle 1).


>>> Muss ich evt. nach Int2String in String[3] speichern und danach über MID das Vorzeichen abschneiden und in einen extra String[2] speichern, der auch im Header mit der Länge 2 belegt ist? Der aktuell noch genutzte String[3] ist ja auch dann mit einer Länge von 3 im Header belegt, hat nach der MID-Funktion aber nur noch eine (tatsächliche) Länge von 2?!


EDIT3: Hab das mal zum Test umgesetzt und es funktioniert. Auch das mit der Addition von 100.

Jetzt brauche ich eigentl. nur noch etwas Hilfe, um den Pointer zum Abschneiden vom Header (für BLKMOV) zu basteln :)
...hab da jetzt alles probiert was ging bzw. was ich im Netz fand, aber klappte nicht. BLKMOV gibt nen Ausrichtungsfehler beim Lesen aus :-( Kann mir da wer helfen?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren

Danke, den Link kenne ich und das liegt schon lange ausgedruckt hier - hat mir schon oft geholfen :)

aaaber ich habs damit nicht hinbekommen ... wie gesagt, die BLKMOV liefert den Ausrichtungsfehler beim Lesen. Keine Ahnung was ich falsch mache, habe fast alle Datentypen sowie Speicherbereiche (L-Stack, vorherige Lokaldaten usw) usw getestet.
 
... dann poste doch bitte mal den das betreffenden Code.
Schön wäre es, zu wissen wo deine Quell-Variable steht.

Gruß
Larry
 
Naja ich hab da jetzt schon so viel rumgebastelt, dass ich womöglich wieder weit von einer funktionierenden Lösung entfernt bin. Jedenfalls stimmen die Kommentare da natürlich nicht mehr, also einfach ignorieren.

Der StringOhneHeader_ANY liegt in Temp ab 0.0 - der String, welcher ohne Header referenziert werden soll, liegt in Temp ab 56.0. Ich wollte den dann ab 58.0 mit dem Pointer referenzieren...

Code:
      LAR1  P##StringOhneHeader_ANY
      L     B#16#10                     // Syntax-ID
      T     LB [AR1,P#0.0]

      L     B#16#4                      // WORD
      T     LB [AR1,P#1.0]

      L     2                           // 8 WORD
      T     LW [AR1,P#2.0]

      L     0
      T     LW [AR1,P#4.0]

      L     56                          // LW 10
      SLD   3
      T     LD [AR1,P#6.0]

      L     B#16#87                     //Lokaldaten
      T     LB [AR1,P#6.0]
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Neeeeiiiiin, ich packs net :-D

Ich hab nach
L 56
SLD 3
das "T LD [AR1,P#6.0]" auskommentiert gehabt wg. nem Test. Das fehlte natürlich...
Scheint jez erstma zu gehen ...


Funktioniert mit folgendem Code:
Code:
      LAR1  P##StringOhneHeader_ANY
      L     B#16#10                     // Syntax-ID
      T     LB [AR1,P#0.0]

      L     B#16#4                      // WORD
      T     LB [AR1,P#1.0]

      L     3                           // 3 WORD
      T     LW [AR1,P#2.0]

      L     0
      T     LW [AR1,P#4.0]

      L     58                          //Lokaldaten TEMP ab 58.0 (String ab 56.0)
      SLD   3
      T     LD [AR1,P#6.0]

      L     B#16#87                     //vorherige Lokaldaten
      T     LB [AR1,P#6.0]
 
Zuletzt bearbeitet:
Ok einen Punkt habe ich noch, das könnte aber einen eigenen Thread wert sein...

Ich brauche noch ein ASCII-Sonderzeichen in den Strings. Ich dachte erstmal daran, die zum ASCII-Zeichen gehörende Nummer als INT zu speichern und dann wie oben alles in einen String zu wandeln. Allerdings steht dann nachher natürlich die Nummer in meinem Array-of-Char statt das Sonderzeichen.
Auch die FC5 DINT_2_String hilft mir da erstmal nicht viel weiter.

Wie wär hier der Ansatz?


EDIT: Ich hätte mehr probieren sollen bevor ich das poste ^^
Habe einfach den ASCI-Code direkt über T LB [AR1,...] reingeschrieben statt den Umwandlungen :)
 
Zuletzt bearbeitet:
Lass uns damit ruhig in diesem Thread bleiben ...

Was genau hast du vor ?
Den ASCII-Code eines Zeichens kannst du im einfachsten Fall direkt an die passende Stelle des Byte-Array's bringen - egal ob im String oder ob in deinem Zielspeicher.
Beispiel : der ASCII-Code 48 ist ein Byte-Wert und steht für das Zeichen '0'.
Du kannst aber auch den Concat mit dem Zeichen füttern - du mußt das dann nur in Hochkomma setzen.

Also ... need more Info ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke Larry,

ich habs nochmal editiert, da ich selbst drauf gekommen bin. War eigentlich auch logisch :)


Einen diesmal hoffentlich wirklich letzten Punkt:
Ich würde das Ganze gerne in eine eigene Funktion auslagern, frage mich aber nun ob bzw. wie ich den "End-String" (um die 15 Zeichen) aus der Funktion raus bekomme (ohne Umweg über einen DB, also OUT bzw IN_OUT oder RET_VAL).

Ich kann zwar allem Anschein nach einen String als OUT definieren, aber String[15] z.B. geht nicht. Ich müsste dann ja erstmal wieder den Rest abschneiden ... oder gibts da ne andere Möglichkeit?
 
Das Ganze in eine eigene Funktion (ich würde allerdings eher einen FB nehmen - aber FC ist auch OK) halte ich für absolut sinnvoll ...
Der Datentyp String beinhaltet in seinem Header immer die Längen-Information. Das eine Byte gibt die deklarierte Länge an, das andere die verwendete (also tatsächliche) Länge. Wenn du den String mit den Siemens-Bausteinen zusammengestezt hast (also z.B. ConCat) dann ist die Länge bereits korrekt eingetragen. Die kannst du dann manuell wieder auslesen oder mittels des Siemens-FC Length (steht in der gleichen Bibliothek wie Concat und Right).

Gruß
Larry
 
Thx nochmal für die Info. FB ist tatsächlich besser, hier kann ich einfach als OUT meine Variable mit korrekter Länge einsetzen - z.B. String[15]. Damit hats schon geklappt. Nice :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Gibt doch noch ein Problem... mir fehlt jetzt irgendwie das Trennzeichen überall. Ich vermute irgendwie, dass sich die Adressierung der Lokaldaten durch den nun einzigen Eintrag in STAT geändert hat - kann das sein?


EDIT: Noch ein paar Infos...

Ich habe den Kram von oben nun in einem FB ausgelagert. Dort gibts zusätzlich die OUT-Variable "Zeitstempel_Str_15" als String[15] - diese ist auch entsprechend im Header belegt. Ich schreibe in diesem FB nun am Ende über BLKMOV nicht in einen DB sondern in diesen String[15]

Dieser FB wird im überlagerten FB als Multiinstanz aufgerufen (dort der einzigste Eintrag in STAT), die OUT-Variable "Zeitstempel_Str_15" existiert auch im überlagerten FB (natürlich auch als String[15] und auch Header vorbelegt) und ist entspr. dann dort mit BLKMOV verschaltet - der schreibt dann wieder in den DB.
 
Zuletzt bearbeitet:
Gibt doch noch ein Problem... mir fehlt jetzt irgendwie das Trennzeichen überall. Ich vermute irgendwie, dass sich die Adressierung der Lokaldaten durch den nun einzigen Eintrag in STAT geändert hat - kann das sein?

Das ist immer schwer, so etwas pauschal zu beantworten (so ohne den Code) - ich kann es mir aber vorstellen wenn du die LB's direkt ansprichst (L LB15) und nicht symbolisch (L #meine_TempVariable) bzw. wenn du ein Misch-Masch fährst.

Gruß
Larry
 
Also ich hab hier noch was von Siemens ausgedruckt liegen. Da steht, dass wenn ich diesen FB als Multiinstanz nutzen will, einen Aufruf wie
Code:
L P##test
LAR1

ersetzen muss durch
Code:
TAR2
UD DW#16#00FF_FFFF
LAR1 P##test
+AR1


Wenn das stimmt, muss ich das echt bei zig Stellen in dem FB machen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hatte dir doch schon mit dem pauschal was geschrieben ...
Das mit der Multi-Instanz und dem AR2 darufaddieren ist dann ein Thema, wenn du für deinen FB nicht einen eigenen Instanz-DB machst sondern ihn in die Instanz eines anderen FB mit einlagerst. Machst du das bzw. hast du das vor ? Wenn du es vorhast - OK ... Wenn du es aktuell aber nicht machst, so ist das nicht dein Problem ...
 
Wenn du den FB als Multiinstanz aufrufen willst, dann kommst da nicht drum rum.

Für dein Beispiel reicht:
Code:
LAR1 AR2
L P#test
+AR1
 
Ich hab irgendwo noch ein dickes Problem drin.

Die ganze Geschichte hat eigentlich funktioniert, aber wenn ich die CPU von STOP wieder anlaufen lasse, stimmt das alles nicht mehr. Dann fehlen die Trennzeichen und es wird teilweise zu wenig übertragen. Einfach unerklärlich erstmal.

Wenn ich dann im übergeordneten FB eine neue TEMP-Variable anlege (egal welcher TYP), ändert sich etwas. Wenn ich das gleiche im Zeitstempel-FB mache (Aufruf NOCH NICHT über Multiinstanz!), ändert sich wieder etwas.
Wenn ich dann wieder einen oder beide neue TEMP-Variablen lösche, hab ich wieder die richtigen Werte mit Trennzeichen.

Wenn ich dann wieder die CPU stoppe und neu anlaufen lasse, fängt das ganze Spielchen wieder von vorne an...


HAt da jemand auch nur die leiseste Ahnung oder muss ich beide Bausteine mal hier abtippen? :)
 
Zurück
Oben