Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 8 von 8

Thema: Scl string_to_real

  1. #1
    Registriert seit
    11.12.2009
    Beiträge
    2.113
    Danke
    388
    Erhielt 390 Danke für 271 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Guten Tag,

    ich hab mal wieder ein Problem, und denke wohl etwas kompliziert... vielleicht geht es ja ganz einfach.

    Von einer Maschine bekomme ich Werte übermittelt. Diese liegen in einem Array of CHAR.

    Beispiel:

    Code:
    RCV_ARRAY[0] = VORZEICHEN
    RCV_ARRAY[1] = 1
    RCV_ARRAY[2] = 2
    RCV_ARRAY[3] = 3
    RCV_ARRAY[4] = 4
    RCV_ARRAY[5] = 5
    RCV_ARRAY[6] = 6
    RCV_ARRAY[7] = .
    RCV_ARRAY[8] = 1
    RCV_ARRAY[9] = 2
    RCV_ARRAY[10] = 3
    RCV_ARRAY[11] = 4
    RCV_ARRAY[12] = 5
    RCV_ARRAY[12] = 6
    Also handelt es sich vereinfacht um einen String '-123456.123456'

    Mit der tollen Funktion FC39 STRNG_R (STRING_TO_REAL) hoffte ich mein Problem zu lösen, aber siehe da... Siemens kann halt nicht einfach.
    Es muss folgendes Format eingehalten werden

    Code:
    -1.1234567E+00
    Warum das so ist, weiß ich nicht. Wenn ich z.B. folgendes tippe geht es:

    Code:
    DUMMY:=STRING_TO_REAL('3.1415');
    Wohingegen dieses nicht tut

    Code:
    VARIABLE:='3.1415';
    DUMMY:=STRING_TO_REAL(VARIABLE);
    Das sollte ja eigentlich KEINEN Unterschied machen (Außer Siemens hat es nicht so mit den ersten zwei Byte des String?)


    Mein Ansatz ist nun folgender. Jedes Array Element mit einem Faktor versehen,und manuell zu einem Real zusammen zu basteln... aber das muss doch einfacher gehen?!

    Also Dann so:

    Code:
    RCV_ARRAY[0] = VORZEICHEN
    RCV_ARRAY[1] = 1
    RCV_ARRAY[2] = 2
    RCV_ARRAY[3] = 3
    RCV_ARRAY[4] = 4
    RCV_ARRAY[5] = 5
    RCV_ARRAY[6] = 6
    RCV_ARRAY[7] = .
    RCV_ARRAY[8] = 1
    RCV_ARRAY[9] = 2
    RCV_ARRAY[10] = 3
    RCV_ARRAY[11] = 4
    RCV_ARRAY[12] = 5
    RCV_ARRAY[12] = 6
    
    REALVAR:= (RCV_ARRAY[1] * 100 000) + (RCV_ARRAY[2] * 10 000) + (RCV_ARRAY[3] * 1 000) + (RCV_ARRAY[4] * 100) + (RCV_ARRAY[5] * 10) + (RCV_ARRAY[6] * 1) + (RCV_ARRAY[8] * 0.1) + (RCV_ARRAY[9] * 0.01) ...
    Das sieht aber meiner Meinung nach weder hübsch aus, noch ist es "sauber".

    Wie geht ihr mit sowas um? Ich brauche auch die Genauigkeit, mit der die Daten übermittelt werden, also wäre STRING_R eh keine Option für mich.
    Das ganze muss später auch rückwärts gehen. Also REAL_TO_STRING.

    Freu mich auf eure Vorschläge!

    Grüße

    Marcel

    P.S: Warum kann Siemens nicht einfach einfach sein?
    Zitieren Zitieren Scl string_to_real  

  2. #2
    Registriert seit
    06.10.2009
    Ort
    NRW
    Beiträge
    1.569
    Danke
    63
    Erhielt 258 Danke für 218 Beiträge

    Standard

    Leg Dir eine Variable tmp an.

    tmp := STRING[16]

    tmp :='000000000000E+00'; // Initialisieren

    FOR i := 1 to 12 DO // Werte eintragen
    tmp := REPLACE(IN1:=tmp,IN2:=RCV_ARRAY[i],L:=1,P:=i);
    END_FOR

    Sollte so gehen.
    Meine Motivation läuft nackig mit einem Cocktail über eine Wiese.

  3. #3
    Matze001 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    11.12.2009
    Beiträge
    2.113
    Danke
    388
    Erhielt 390 Danke für 271 Beiträge

    Standard

    Zitat Zitat von Matze001 Beitrag anzeigen
    Ich brauche auch die Genauigkeit, mit der die Daten übermittelt werden, also wäre STRING_R eh keine Option für mich.
    Danke für die Antwort! Aber leider hast du meinen Beitrag nicht komplett gelesen Ich werde wohl auf zwei DINT statt nen REAL ausweichen müssen...
    Denn ich denke nicht das ich mit einem REAL die Werte die ich bekomme so genau abbilden kann.

    Grüße

    Marcel

  4. #4
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.218
    Danke
    533
    Erhielt 2.696 Danke für 1.948 Beiträge

    Standard

    Zitat Zitat von Matze001 Beitrag anzeigen
    Danke für die Antwort! Aber leider hast du meinen Beitrag nicht komplett gelesen Ich werde wohl auf zwei DINT statt nen REAL ausweichen müssen...
    Denn ich denke nicht das ich mit einem REAL die Werte die ich bekomme so genau abbilden kann.

    Grüße

    Marcel
    Das kannst du in der Tat nicht, denn die Real in der S7 kann nur 7 Ziffern enthalten, dazwischen noch ein Komma und dazu der zugehörige Exponent.
    Geändert von Ralle (22.02.2012 um 15:15 Uhr)
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  5. #5
    Registriert seit
    06.10.2004
    Ort
    Kopenhagen.
    Beiträge
    4.620
    Danke
    377
    Erhielt 799 Danke für 642 Beiträge

    Standard

    RCV_ARRAY[0] = VORZEICHEN
    RCV_ARRAY[1] = 1
    RCV_ARRAY[2] = 2
    RCV_ARRAY[3] = 3
    RCV_ARRAY[4] = 4
    RCV_ARRAY[5] = 5
    RCV_ARRAY[6] = 6
    RCV_ARRAY[7] = .
    RCV_ARRAY[8] = 1
    RCV_ARRAY[9] = 2
    RCV_ARRAY[10] = 3
    RCV_ARRAY[11] = 4
    RCV_ARRAY[12] = 5
    RCV_ARRAY[12] = 6
    Diese Real-Format ist sehr Speziell !
    Wenn es um eine skalierte Signal handelt, kannst du eventuell den unskalierte Signal bekommen, und zwar als INT oder DINT, und dann selber den benötigte skalierung machen ?
    Es wird einfacher, und du verlierst kein genauigkeit wegen rundungen.
    Jesper M. Pedersen

  6. #6
    Matze001 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    11.12.2009
    Beiträge
    2.113
    Danke
    388
    Erhielt 390 Danke für 271 Beiträge

    Standard

    Hallo,

    ich hatte gehofft es in einen Real-Wert stopfen zu können. Geht aber nicht

    Meine VERMUTUNG ist, dass die Gegenseite sich zweier DINT bedient, und genau das werde ich wohl auch machen (müssen )

    Grüße

    Marcel

  7. #7
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.710
    Danke
    398
    Erhielt 2.397 Danke für 1.997 Beiträge

    Standard

    Hallo,
    zu dem Thema hatte ich mir mal etwas in SCL gebaut (aus dem gleichen Grund).
    Vielleicht hilft es ja :
    Code:
    FUNCTION FC437 : VOID                       // UP String nach REAL umwandeln
    Title   = 'UP String nach REAL umwandeln'   // UP String nach REAL umwandeln
    AUTHOR  : 'Larry Laffer'
    VERSION : '1.0'   //  15.07.2011
    //     Bausteinparameter
    VAR_INPUT
       Real_String : string ;  // umzuwandelnder Eingangs-String
    END_VAR
    
    VAR_IN_OUT
    END_VAR
    
    VAR_OUTPUT
       Wert        : REAL ;    // umgewandelter Wert
    END_VAR
    
    VAR_TEMP
       i : INT ; 
        
       is_VZ_Basis : BOOL ;    // false = VZ positiv , true = VZ negativ
       is_VZ_Exp   : BOOL ;    // false = VZ positiv , true = VZ negativ
       is_Basis    : BOOL ;    // true = Bearbeitung der Basis , false = Bearbeitung vom Exponent
       is_Vorkomma : BOOL ;    // true = Bearbeitung der Vorkommastellen , false = Bearbeitung der Nachkommastellen
       is_Zahl     : BOOL ;    // true = akt. Zeichen ist eine Zahl
        
       Wert_Basis  : REAL ;
       Wert_Exp    : REAL ;
       Faktor_Nachkomma : REAL ;
       akt_Zahl    : REAL ;
       
       myString : STRING ;
       a_myString AT myString : STRUCT 
              Total  : BYTE ;
              Length : BYTE ;
              Chars  : ARRAY [1..254] OF BYTE ;
       END_STRUCT ;
       myStringLen : INT ;
       
    END_VAR
    
    //     Anweisungsteil
    BEGIN
    is_VZ_Basis := false ;    // false = VZ positiv , true = VZ negativ
    is_VZ_Exp   := false ;    // false = VZ positiv , true = VZ negativ
    is_Basis    := true ;     // true = Bearbeitung der Basis , false = Bearbeitung vom Exponent
    is_Vorkomma := true ;     // true = Bearbeitung der Vorkommastellen , false = Bearbeitung der Nachkommastellen
         
    Wert_Basis := 0.0 ;
    Wert_Exp   := 0.0 ;
    Faktor_Nachkomma := 0.1 ;
    myString    := Real_String ;
    myStringLen := BYTE_TO_INT(a_myString.Length) ;
    FOR i := 1 TO myStringLen BY 1 DO
       IF (a_myString.Chars[i] = CHAR_TO_BYTE('.')) THEN is_Vorkomma := false ; END_IF ;
       IF (a_myString.Chars[i] = CHAR_TO_BYTE(',')) THEN is_Vorkomma := false ; END_IF ;
       IF (a_myString.Chars[i] = CHAR_TO_BYTE('e')) THEN is_Basis := false ; END_IF ;
       IF (a_myString.Chars[i] = CHAR_TO_BYTE('E')) THEN is_Basis := false ; END_IF ;
       
       IF (a_myString.Chars[i] = CHAR_TO_BYTE('-')) THEN
          IF is_Basis THEN is_VZ_Basis := true ; ELSE is_VZ_EXP := true ; END_IF ; 
       END_IF ;
       
       akt_Zahl := INT_TO_REAL(BYTE_TO_INT(a_myString.Chars[i])-48) ;
       is_Zahl := (akt_Zahl >= 0) AND (akt_Zahl <= 9) ;
       
       IF is_Zahl THEN
          IF is_Basis  THEN
             IF is_Vorkomma THEN
                Wert_Basis := (Wert_Basis * 10.0) + akt_Zahl ;
             ELSE
                Wert_Basis := (akt_Zahl * Faktor_Nachkomma) + Wert_Basis ;
                Faktor_Nachkomma := Faktor_Nachkomma * 0.1 ;
             END_IF ;      
          ELSE
             Wert_Exp := (Wert_Exp * 10.0) + akt_Zahl ;
          END_IF ;    
       END_IF ;  
    END_FOR ;    
    IF is_VZ_Basis THEN Wert_Basis := Wert_Basis * -1.0 ; END_IF ;
    IF is_VZ_Exp THEN Wert_Exp := Wert_Exp * -1.0 ; END_IF ;
       
    Wert := Wert_Basis * 10**Wert_Exp ;  
       
    END_FUNCTION
    ... das lösst allerdings nicht das Problem mit dem Double ...

    Gruß
    Larry

  8. Folgender Benutzer sagt Danke zu Larry Laffer für den nützlichen Beitrag:

    Matze001 (22.02.2012)

  9. #8
    Matze001 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    11.12.2009
    Beiträge
    2.113
    Danke
    388
    Erhielt 390 Danke für 271 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Trotzdem ein guter Ansatz.

    ich habe nun die Variable in zwei Teile zerlegt. Vor dem Komma ein DINT, und danach auch einer.
    Das ist für meine Zwecke mehr als ausreichend, und funktioniert tadellos!

    Grüße

    Marcel

Ähnliche Themen

  1. Antworten: 1
    Letzter Beitrag: 23.01.2012, 17:06
  2. STRING_TO_REAL im Twin CAT version 2.11
    Von tech007 im Forum CODESYS und IEC61131
    Antworten: 8
    Letzter Beitrag: 02.08.2011, 16:32
  3. SCL: FB Aufruf unter SCL mit Variablen DB
    Von ThorstenK im Forum Programmierstrategien
    Antworten: 32
    Letzter Beitrag: 10.02.2011, 19:15
  4. Antworten: 4
    Letzter Beitrag: 07.10.2006, 00:34
  5. Brauche Hilfe bei SCL.SFC Aufrufen in SCL
    Von Gerold im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 06.10.2005, 10:47

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •