# Frage zu Elau Problem, ein Array in 2 Strings



## Trashman (19 September 2007)

Morgen allerseits,

Ich hab vor kurzem Angefangen  mit Elau. Hab zwar gewisse Vorkenntnise mit Simatic und einige andere Programiergeschichten, bin aber jetzt auf ne Elau verbannt worden.

Soweit so gut.

Folgendes meint mein Cheff zu wollen:

Messdaten vom typ real (können au in Int gewandelt werden) werden in nen Array gespeichert. Sind so 300-360 Messwerte (Entsprechende Array-Größe.
also hab ich aktuell nen Array[1..360] of int(real)

Dieses Array wird so alle 3,6S neu mit Daten bespielt. 
Das Array soll nun gesplittet in 2 oder X Strings werden und dann per Opc an ne Indusoft geschickt werden. (Teilung in Strings um den Opc nicht zu sehr zu belasten)

Dort soll das ganze wieder zusammengefasst in ein Array gespeichert werden und dann grafisch dargestellt werden. Ich würds wohl über Trend Task oder was machen.

Vorrangiges Problem ist allerdings die Speicherung der 360 Daten in 2-X Strings. 
Wenn mir da jemand nen Tipp geben könnte, wär ich schon nen großen Schritt weiter.

Jemand ne Idee wie ich das am geschicktesten realisieren kann?


----------



## zotos (19 September 2007)

Bevor man daran geht sollte man noch ein zwei Fragen klären:

Angenommen wir nehmen einen Realwert, wie viele Stellen von und nach dem Komma willst Du denn nutzen?

Wenn man z.B. drei vor und drei nach dem Komma nimmt das ganze in einen String packt dann noch Trennzeichen einpflegt würde das etwa so aussehen:
123.456;452.142;525.934;234.446;142.346;653.346;343.436;233.996;

Also 8 Zeichen pro Messwert ein String (bei CoDeSys) kann eh nur 255 Zeichen Fassen.

Also würde man ca 31 Messwerte in dem Format in einen String quetschen können.

Bei 360 Messwerten würde ich dann 12 Strings nehmen mit je 30 Messwerten.

Also bevor ich da jetzt einige Code Fetzen liefere sag mir mal wie die Strings aussehen sollen.


----------



## Trashman (19 September 2007)

Mir reicht eine Stelle nach dem Komma völlig aus und vorm Komma werden es 3 Stellen im Maximum.

Also geht von 0.X bis 359.X.... in dem bereich eben 360 Werte

Kommt laut meiner Rechnung: 
Hab ich im Maximum 6 Zeichen 
um auf Nummer Sicher zu gehen, Bedarf es 9 Strings bei 360 Werten und 8 Strings bei 300 werten.

Richtig?


----------



## J Schohaus (19 September 2007)

Hallo

Ich stelle mal in zweifel das die Kommunikation über OPC durch die aktion schneller wird.
Bei OPC werden die angeforderten daten vom system schon zusammengepackt und im block übertragen!

mfG Jochen


----------



## Trashman (19 September 2007)

Mag sein, kann ich leider nicht beurteilen. 
Hatte mit den OPC´s noch nichts zu tun.

Bin hier seit 2 Wochen erst der Praktikant 

Mir wurde nur gesagt, mach das mal so und so und schau mal ob du das hinbekommst 

Leider hat mein Chef grad etwas Stress mit Kundenterminen und darum etwas schwierig für mich bei ihm nachzuhacken.

Darum hoff ich hier auf bissl Hilfe. Wär toll


----------



## zotos (19 September 2007)

Also mal gerade auf die Schnelle:


```
VAR
  myRealArray      :ARRAY[0..359] OF REAL;      (* Messwerte im Realformat*)
  myStringArray    :ARRAY[0..8] OF STRING(255); (* Messwerte als Datenstrom *)
  myStringTemp     :STRING(6);                  (* Hilfs String *)
  myRealTemp       :REAL;                       (* Hilfs Real *)
  forCount1        :INT;                        (* äußerer Schleifenzähler *)
  forCount2        :INT;                        (* innerer Schleifenzähler *)
  myIndex          :INT;                        (* Index für das Real Array *)
END_VAR
```


```
(* Strings leeren *)
FOR forCount1 := 0 TO 8 DO
  myStringArray[forCount1] := '';
END_FOR;

(* Strings beschreiben *)
FOR forCount1 := 0 TO 8 DO
  FOR forCount2 := 0 TO 39 DO
    myIndex := forCount1 * 40 + forCount2; (* Der Index für das RealArray bilden *)

    myRealTemp := INT_TO_REAL(REAL_TO_INT(myRealArray[myIndex] * 10)) / 10; (* Runden auf eine Kommastelle *)

    myStringTemp := REAL_TO_STRING(myRealTemp); (* Realwer in einen String verwandeln *)

    IF myRealTemp = REAL_TO_INT(myRealTemp) THEN
      myStringTemp := CONCAT (myStringTemp,'0'); (* Eine 0 anhängen wenn die Kommastelle 0 ist *)
    END_IF;
    
    myStringTemp := CONCAT (myStringTemp,';'); (* Ein ; als Trennzeichen anhängen *)
    
    myStringArray[forCount1] := CONCAT(myStringArray[forCount1],myStringTemp); (* Die Großen Strings zusammen setzen *)
  END_FOR;
END_FOR;
```
da sind noch Stolpersteine drin. Aber es ist ein Ansatz.

//Edit: Wenn die Kommastelle 0 ist wird jetzt auch eine 0 angefügt.


----------



## Trashman (19 September 2007)

Danke, werd mich mal damit beschäftigen


----------



## Werner29 (19 September 2007)

Hi, 

übrigens kann man in CoDeSys (und damit in Epas) schon strings länger als 255 definieren. Nur kann man die dann nicht mit dem Standard-Concat bearbeiten.
Ich habe mal eine IEC-Variante von Concat geschrieben mit der man auch längere strings bearbeiten kann, dazu statt 255 einfach einen anderen Wert nehmen.

Schnittstelle:

```
FUNCTION My_CONCAT : STRING(255)
(*
    Concatenation of two strings.
*)
VAR_INPUT
    STR1:STRING(255);
    STR2:STRING(255);
END_VAR
VAR
    pbyte1 : POINTER TO BYTE;
    pbyte2 : POINTER TO BYTE;
    pbyteRes : POINTER TO BYTE;
    bString2 : BOOL := FALSE;
END_VAR
```
Rumpf:

```
pbyte1 := ADR(str1);
pbyte2 := ADR(str2);
pbyteRes := ADR(My_CONCAT);

WHILE TRUE DO
    IF (bString2) THEN
        pbyteRes^ := pbyte2^;
        IF (pbyte2^= 0) THEN
            EXIT;
        END_IF
        pbyte2 := pbyte2 + 1;
        pbyteRes := pbyteRes + 1;
    ELSE
        IF (pbyte1^ = 0) THEN
            bString2 := TRUE;
        ELSE
            pbyteRes^ := pbyte1^;
            pbyte1 := pbyte1 + 1;
            pbyteRes := pbyteRes + 1;
        END_IF
    END_IF
    IF (pbyteRes - ADR(My_CONCAT) >= 255) THEN
       (*Korrektur mit Dank an [URL="http://www.sps-forum.de/member.php/356-Thomas_v2.1"][B]Thomas_v2.1[/B][/URL][COLOR=#3E3E3E] [/COLOR]*)
        pbyteRes^ := 0;
        EXIT;
    END_IF
END_WHILE
```

Bernhard


----------



## Trashman (19 September 2007)

Also mal rein theoretisch nachdem was Bernhard/werner29 geschrieben hat....

Ich hab meine Werte die von 0.0 bis 360.0 gehen können. 

Rein theoretisch könnte 
-ich bei jedem dieser Wert den Komma . rausnehmen
-bei den Werten kleiner 10.0 könnte ich eine 00 vorne anhängen
-bei den Werten gößer 10.0 und kleiner 100.0 könnte ich eine 0 vorne anhängen

Damit hätte ich immer genau 4 zeichen pro wert, niemals mehr.

Dann könnte ich alle 360 Werte in einen String schreiben... müsste eben eine länge von 1440 besitzen. Und könnte diesen übertragen.

Später müsste ich dann beim extrahieren eben sehen, dass ich immer 4 Zeichen aus den String entnehme, den Kommapunkt wieder einfüge und dann umwandel.

Könnte das gehen?
Und wenn, welche Variante ist "einfacher" bzw. schneller zu schreiben?


----------



## Trashman (19 September 2007)

Wobei ok, das wäre dann absoluter nonsens, dann könnt ich gleich das komplette Array senden


----------



## zotos (19 September 2007)

Trashman schrieb:


> Danke, werd mich mal damit beschäftigen



Hast Du jetzt den Code getestet?


----------



## Trashman (19 September 2007)

Hab den Code auf meine Variablen entsprechend abgeändert, eingebunden und überstetzt. Fehlermeldungen kamen keinen.

Richtigen Test mit meinen Daten kann ich wohl erst morgen fahren.


----------



## Trashman (21 September 2007)

So nachdem ich den Code von Zotos (mit kleinen Abwandlungen) eingebunden, die OPC-Übertragung auf die Reihe gebracht und die Rückwandlung soweit hinbekommen hab, besteht noch ein Problem.

Beim Setzten des ; passiert es in einigen Fällen, dass es eben nicht passiert.

Soll heissen, die Werte werden als String hintereinander geschrieben ohne ein entsprechendes ; dazwischen.

Das ganze Passiert nur dann, wenn meine Werte auf unter -100 Steigen. Alle anderen Funktionieren einwandfrei


----------



## Trashman (21 September 2007)

Gut ich hab die Lösung selbst gefunden...

Der Hilfststring myStringTemp     :STRING(6);  
Ist nur für 6 Zeichen ausgelegt... 
bei -100.0 sind es mit dem ";" allerdigns 7 Zeichen, darum funktionierte es nicht.

Lösung war:
myStringTemp     :STRING(7);

Und ich konnte aus Sicherheitsgründen nur noch 32 Werte pro String speichern, da sonst ne Gefahr bestand, dass sie in die 255 Zeichen nicht reinpassen.

Also alles etwas anpassen und es funktioniert


----------



## zotos (21 September 2007)

Trashman schrieb:


> Gut ich hab die Lösung selbst gefunden...



Sowas lese ich immer gerne und finde es super das Du es selbst hinbekommen hast.

Die Beschränkung auf 255 Zeichen kommt wie Werner29 ja erwähnt hat nicht vom System sondern von den Standard Funktionen wie CONCAT. Wenn man seine Version von myCONCAT angepasst hätte, hätte man auch mehr Zeichen in einen String rein kopieren können.

Aber wichtig ist das es zufriedenstellend funktioniert.


----------

