Anfängerfrage! : Daten in ein Array(Struct) schreiben

pepper
2009-11-06
2009-11-10
  • pepper - 2009-11-06

    Hallo Community,

    wie ihr am Titel schon sehen könnt bin ich ein SPS-Anfänger. Ich habe ein Problem bei dem Ihr mir vielleicht helfen könnt.

    Ich habe ein Array mit einer Struktur. :

    maildata:Array[0..1440] OF typ1;

    TYPE typ1 :
    STRUCT
       timestamp: DT;
       sensor: STRING(10);
       wert: REAL;
    END_STRUCT
    END_TYPE
    

    jetzt möchte ich dieses Array mit Messdaten füllen. (Es handelt sich dabei immer um (Zeitstempel;Sensorname;Messwert). Da mich mich zum ersten mal mit Arrays beschäftige, weiss ich leider nicht wie man jetzt die Daten in die entsprechnenden Arrayfelder bekommt.

    Das nächste Problem was ich warscheinlich haben werde ist, dass ich dieses Array in Byte konvertieren muss um es dann in einer TXT-datei als Emailanhang zu versenden. Dabei sollten (Zeitstempel;Sensorname;Messwert) pro zeile nebeneinander stehen. Mein Eingang für den Mailversand sieht so aus:

    ptAttachment      : POINTER TO ARRAY[0..MAX_SEND_TCP_CLIENT] OF BYTE; (*  *)
    

    vom Baustein "MAIL_ESMTP_Client" aus der "WagoLibMail_02.lib"

    Ich hoffe ihr könnt mir weiterhelfen.

    Grüße

    Pepper

     
  • Rolf-Geisler - 2009-11-06

    Hallo,

    Teil 1 der Frage ist leicht zu beantworten.

    Du musst irgendwo in den Variablen eine Instanz Deiner Struktur deklarieren, damit Du überhaupt darauf zugreifen kannst, z.B.

    VAR
      DataToSend: MailData;
    END_VAR
    

    Jetzt kannst Du das Array füllen. Dazu brauchst Du einen Index vom Typ INT, um einzelne Elemente anzusprechen, z.B.

    VAR
      Idx : INT;
    END_VAR
    

    und dann geht's ganz einfach

      DataToSend[Idx].timestamp := ...
      DataToSend[Idx].sensor := ...
      DataToSend[Idx].wert := ...
    

    Natürlich musst Du vor jedem Schreiben Idx fortschreiben, sonst schreibst Du immer nur in das gleiche Array-Element.

    Zu Teil 2 der Frage kann ich nichts beitragen. In der IEC gibt es zwar jede Menge von Typumwandlungen, z.B. DINT_TO_INT, aber ob es so etwas auch für den Datentyp DT gibt, oder wie es bei Strings funktioniert, kann ich nicht sagen. Vielleicht weiss jemand andres etwas dazu.

    Gruss Rolf

     
  • Isegrim - 2009-11-08

    Hallo,

    Time_To_, Date_To_ und Dt_To_ -Konvertierungen gibt es. Ist sogar in der Hilfe aufgeführt.

    Grüße

    Klaus

     
  • pepper - 2009-11-09

    Erstmal Danke für eure Mühe. Ich habe das soweit hinbekommen. Ich kann jetzt meine Messdaten und Zeitstempel in einem String(Array) ausgeben und in eine csv datei schreiben.

    Jetzt ist mir aufgefallen das nach mehrmaligen schreiben in meine CSV-Tabelle plözlich die Formatierung nicht mehr stimmt. Es schummeln sich Zeichen dazwischen usw. .

    Kann es sein das es irgendeinen Buffer gibt der die Daten zwischenspeichert und den man resetten muss? Oder muss man gar den Inhalt des Arrays löschen bevor man wieder neue Daten reinschreibt?

    Grüße Pepper

     
  • KlOis - 2009-11-09

    Wenn der String nach dem Initialisieren beschrieben wird:

    aus '' wird 'Hallo/0' wobei '/0' das Ende des Strings symbolisiert.

    Bei dem zweiten mal, wenn du den String beschreibst (mit einem kürzeren Wert) wird auss 'Hallo/0' z.B. 'Hi/0lo'.

    Entweder du setzt den String zurück mit ```

    String:='';

    oder du schreibst nicht die gesamte Variablegröße des Strings in die Datei, sondern nur die Stringlänge. Also statt

    SIZEOF(String)

    nimmst du

    LEN(String)

    ```

     
  • pepper - 2009-11-10

    So, jetzt habe ich mein "Array of String" und möchte es in ein "Array of Byte" konvertieren.

    Hintergrund: Ich möchte meine "Text-Strings" als Emailanhang in einer txt-Datei versenden. Und dafür brauche ich ein Array of Byte ( ich denke mal als ASCII zeichen)

    Ich habe leider keine richtige Konvertfunktion gefunden. Hat vielleicht jemand einen Tip?

     
  • KlOis - 2009-11-10

    Du brauchst deine Strings nicht in Bytes umwandeln, im Grunde sind sie es ja schon.

    Ich gehe mal davon aus das du die Funktion "SysyFileWrite" benutzt.

    Wenn du einen String (z.B. strTest: STRING:='Hallo'; ) mit dieser Fkt. in eine Datei schreiben willst, dann übergib der Eingangsvariable einfach:

    SysFileWrite(File,ADR(strTest),Len(strTest));
    

    Das Handle File erhältst du über SysFileOpen.

    oder hab ich dich falsch verstanden?

     
  • pepper - 2009-11-10

    Erstmal danke für die schnelle Antwort.

    Ich kann ja mal aufführen was ich bis jetzt habe.

    Ich sammel meine Daten indem ich diese in ein Array of String schreibe.

    arrMesswerte[loop]:=messwert;
      (* Textzeile bilden: Zeitstempel Messstelle Wert Einheit CRLF, Vorgabe: 10:36 - 05.11.09 Temperaturfühler1: 23.45 °C *)
        arrMesswerteKlartext[loop]:= DWORD_TO_STRF(dtAktDatumUhrzeit.HOUR, 2);
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], ':');
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], DWORD_TO_STRF(dtAktDatumUhrzeit.MINUTE, 2));
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], ' - ');
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], DWORD_TO_STRF(dtAktDatumUhrzeit.DAY, 2));
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], '.');
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], DWORD_TO_STRF(dtAktDatumUhrzeit.MONTH, 2));
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], '.');
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], DWORD_TO_STRF((dtAktDatumUhrzeit.YEAR MOD 100), 2));
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], ';');
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], fuehler);
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], ';');
        arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], REAL_TO_STRF(arrMesswerte[loop], 1));
    arrMesswerteKlartext[loop]:= CONCAT(arrMesswerteKlartext[loop], ';$r$n');
    

    Diese Array was, ich damit erstelle, möchte ich nun per Emailanhang versenden. Das funktioniert auch soweit ganz gut. Leider schummeln sich nach mehrmaligen sende irgendwelche zeichen dazwischen. Ich dachte vielleicht liegt es daran das ich ein "Array of String" benutze anstatt ein "Array od Byte". Dem scheint aber nicht so zu sein.

    Zum versenden benutze ich die "WagoLibMail_02" und den Baustein "MAIL_ESMTP_Client". Dort habe ich dann am Eingang "ptAttachment" habe ich mein "Array of String".

    Muss ich vielleicht den Internen Buffer nach jedem versenden resetten oder muss irgendwas mit meinem Array anstellen, damit wirklich nur das in meiner txt-datei drin ist was ich reingeschriben habe.

    Wenn ich im Onlinemodus in das Array reingucke, stehen die Daten alle richtig drin. Wenn ich sie dann versende sind plötzlich weitere zeichen und Leerzeichen dazugekommen.

     
  • KlOis - 2009-11-10

    da ich nicht mit Wago arbeite, kenn ich mich leider auch nicht benannten Bibos und Funktionen aus.

    Aber wie ich schon oben beschrieben habe, kann es sein, dass beim 2. Beschreiben eines Strings im 1. Eindruck alles i.O. scheint, aber nur durch das Trennzeichen, was das Ende des Strings Symbolisiert.

    Ergo:

    bevor du dein Feld ein 2. mal beschreibst, lösch den kompletten Inhalt.

    Du kannst dazu die SysMemSet Funktion der SysLibMem.lib nutzen (falls dein System diese unterstützt).

    SysMemSet(ADR(arrMesswerteKlartext),0,SIZEOF(arrMesswerteKlartext));
    

    ansosnten könntest du über eine Schleife selbst alles zurücksetzen oder durch ein 2. identisches Feld, welches unbeschrieben ist, das 1. zurücksetzen. Also ```

    Feld1:=Feld2;

    ```

     
  • pepper - 2009-11-10

    Erstmal vielen Dank für deine schnelle Hilfe KIOis,

    dein Beispiel hat super funktioniert, leider besteht mein Problem aber weiterhin. Ich habe langsam die Vermutung, das vielleicht was mit dem Wagobaustein nicht funktioniert. Ich habe mich daher auch mit Wago in Verbindung gesetzt und denen mein Projekt geschickt.

    Ich werde euch informieren, sobald ich eine Antwort bekommen habe.

     

Log in to post a comment.