Step 7 Falscher Typ, ich seh mal wieder den Wald vor lauter Bäumen nicht

drsnuggles

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

sorry aber ich starre jetzt seit 2h die 5 Zeilen Code an und finde nicht warum mir der Compiler sagt das es ein falscher typ wäre.

Kurz wofür das ganze:

Ich habe ein Array of Char in dem eine Zahl mit bis zu 5 Stellen steht kann aber auch nur eine oder zwei Stellen haben. Die Zahl wird linksbündig ausgegeben. Diese soll in einen Integer wert umgewandelt werden.

Code:
VAR_TEMP
    // temporäre Variablen
    TmpStr : ARRAY[1..4095] OF CHAR;
    i:INT;   
    Laenge:INT;
END_VAR

    FOR i:= 1 TO Laenge BY 1 DO
        IF ((laenge-i)>1) THEN
            GetMsgHeader.ERROR_CODE:=((10**(Laenge-1))*(CHAR_TO_INT(TmpStr[i])));
        ELSE
            GetMsgHeader.ERROR_CODE:=GetMsgHeader.ERROR_CODE+CHAR_TO_INT(TmpStr[i]);
        END_IF;     
    END_FOR;

GetMsgHeader.ERROR_CODE ist ebenfalls vom Datentyp "INT"

Gruß und Danke fürs in die richtige Richtung stoßen

Der Doc
 
Warum schreibst Du "10**(Laenge-1)"? Das ist eine Potenz-Operation, und die liefert REAL als Ergebnis.

PS: Auf welcher SPS soll das laufen mit einem Array 4 kByte in TEMP?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Potenz gibt Real.
Also was anderes für Potenz nutzen.
Was soll in der Schleife herauskommen?
GetMsgHeader.ERROR_CODE wird bei jedem Schleifendurchlauf NEU berechnet, müßte es nciht mit sich selbst addiert werden, so wie im Else-Zweig?
 
Des weiteren ergibt "Char_To_Int" nicht die Ziffer/Wert als Integer des Zeichens...
Was ich meine: Char_to_int => '2' = 50 Int = 32 Hex
 
Hallo,

das war der Fehler, die Potenz muss es schon sein, aber diese dann einmal nach Int wandeln. Da ich eh nur 10er Potenzen einsetze ist das ja kein Problem

Das mit dem Char_To_INT war nicht ganz korrekt das habe ich ich behoben jetzt läuft der Compiler durch, wir schauen dann mal wenn es läuft
 
Was soll Dein Code eigentlich machen? Mir scheint, Du bist auf einem falschen Lösungsweg.

Um 1..5 ASCII-Zeichen in INT zu wandeln braucht man keine Potenzfunktion. Dazu müsste man lediglich Ziffer für Ziffer das Char zu INT wandeln (bei ASCII-Code: 48 abziehen), und den bisher umgewandelten INT mit 10 multiplizieren und den Zahlenwert des Char addieren. (und gerne prüfen ob das Zeichen überhaupt eine Ziffer '0'..'9' ist)
MyInt := MyInt * 10 + (CHAR_TO_INT(TmpStr) - 48 );

In der 317-2PN/DP können die Lokaldaten je Baustein max 2 kB groß sein.

Wo kommt der Datenstrom bzw. das Char-Array her? Kannst Du das Array nicht per IN_OUT an Deinen Baustein übergeben?

Harald
 
Was soll Dein Code eigentlich machen? Mir scheint, Du bist auf einem falschen Lösungsweg.

Um 1..5 ASCII-Zeichen in INT zu wandeln braucht man keine Potenzfunktion. Dazu müsste man lediglich Ziffer für Ziffer das Char zu INT wandeln (bei ASCII-Code: 48 abziehen), und den bisher umgewandelten INT mit 10 multiplizieren und den Zahlenwert des Char addieren. (und gerne prüfen ob das Zeichen überhaupt eine Ziffer '0'..'9' ist)
MyInt := MyInt * 10 + (CHAR_TO_INT(TmpStr) - 48 );

In der 317-2PN/DP können die Lokaldaten je Baustein max 2 kB groß sein.

Wo kommt der Datenstrom bzw. das Char-Array her? Kannst Du das Array nicht per IN_OUT an Deinen Baustein übergeben?

Harald


Im Prinzip macht meiner das gleiche wie dein Code

nimmt die Potensstelle aus der länge und dann macht er nur

10^4*wert=10000*wert
dann 10^3*Wert=1000*wert
usw.

dein code ist natürlich noch etwas kürzer und durch die umgeangene Potenz einfacher ressourcenschonender

Der Datenstrom kommt als Input und wird dann etwas modifiziert. Ich werde die Temps wohl in einen Schmier-DB umlegen. da werden noch mehr dazu kommen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
He Harald,

hast du eventuell ne clevere Formel für den umgekehrten Weg? Ich hab eine 1 bis 6 stellige DINT Zahl und muss diese in ein Array of character wandeln,

MyInt := MyInt * 10 + (CHAR_TO_INT(TmpStr) - 48 );


Meine Schullösung mit DIV ist schon etwas aufwendig:
Code:
 IF (Msg.diMsgID DIV 100000)>0 THEN
        Msg.wsMsgID[1]:=INT_TO_CHAR((Msg.diMsgID DIV 100000)+48);
        Msg.diMsgID:=Msg.diMsgID-((Msg.diMsgID DIV 100000)*100000)
    ELSE
        Msg.wsMsgID[1]:='0';
    END_IF;

Und das quasi für jede der 6 stellen.
 
in tia 1500er kannst du zuerst dint_to_string und dann string_to_char anwenden.
 
hast du eventuell ne clevere Formel für den umgekehrten Weg? Ich hab eine 1 bis 6 stellige DINT Zahl und muss diese in ein Array of character wandeln
Für die Wandlung DINT zu Chars solltest Du möglichst die bereits vorhandenen Anweisungen benutzen, es sei denn, Du brauchst die Zeichenfolge irgendwie anders aussehend als von den Anweisungen geliefert (doch vielleicht kannst Du da auch String-basteln?). Ein Weg könnte sein, den DINT-Wert fortlaufend von hinten in Dezimalziffern zu zerlegen, durch Division durch 10: "MOD 10" liefert die niederwertigste Ziffer (Divisionsrest 0..9), "/ 10" liefert den Wert vor der letzten Ziffer. (so eine selbstprogrammierte ziffernweise Zerlegung ist in SCL allerdings nicht besonders effizient machbar, das geht besser in AWL. Deshalb in SCL besser fertige Anweisungen nutzen.)

Wie soll Deine Ziffern-Zeichenfolge "vorne" aussehen, wenn sie weniger als 6 Ziffern hat? Linksbündig/abgeschnitten, Vor-Leerzeichen, Vor-Nullen?

Harald
 
Zurück
Oben