Zahlenwert <256 in 1 Byte wandeln

boling
2006-12-20
2007-02-06
  • boling - 2006-12-20

    Hallo,

    ich möchte Messwerte möglichst dicht packen und suche einen einfachen weg, um Zahlenwerte zwischen 0 und 255 in einen Bytewert umzuwandeln. Aus anderen Sprachen ist dieser Befehl z.B. Char ( Wert), das Gegenteil von Ascii (Stringzeichen).

    Gibt es sowas in CoDeSys?

     
  • Ralph Holz - 2006-12-20

    Hallo boling,

    das klingt nach den Typkonvertierungen STRING_TO_BYTE und umgekehrt BYTE_TO_STRING.

    Gruß

    Ralph

     
  • boling - 2006-12-20

    Leider nicht,

    Beispiel: der Wert 33 würde als String ein ! darstellen, der Wert 65 ein A. D.h. ich brauche eine Möglichkeit, den Ascii-Wert in ein Ascii-Zeichen umzuwandeln. Der Datentyp BYTE wäre schon auch richtig, ich kann den ja mit BYTE_TO_STRING umwandeln. Schöner wäre natürlich, wenn ich direkt einen Befehle hätte mit z.B. ASCIIWERT_TO_STRING. (Nicht ASCIIBYTE_TO_STRING).

    Oder ein weiterer Weg, wie komme ich vom ASCII-Wert auf das BYTE?

     
  • Erik Böhm - 2006-12-20

    Hallo

    Das heisst, du willst von einem einzelnen Zeichen den Binärwert ?

    Z.B. sTempString := 'A' umwandeln in byTempByte = 65 ?

    Dann nimm doch nen Pointer.

    pby: Pointer to Byte;

    pby := adr(sTempString);

    byTempByte := pby^;

    Gruß

    Erik

     
  • boling - 2006-12-20

    Hallo Erik,

    gerade umgekehrt, ich habe den Binärwert und möchte den platzsparend als einzelnes Zeichen (hat ja 8Bit) verpacken.

    Also iWert ist gleich 64 -> in ein Byte umwandeln. (= Zeichen A).

    Gruss

    Peter

     
  • Ralph Holz - 2006-12-20

    Genau das wolte ich jetzt auch vorschlagen!

    Variablendeklartion:

    x: STRING;
    
    y: POINTER TO BYTE;
    
    z: BYTE;
    
    a: BYTE;
    
    b: POINTER TO STRING;
    
    c: STRING;
    

    Code:

    (ASCII Character -> ASCII Code)

    x:= 'b'; (Character)

    y:= ADR(x);

    z:= y^; (Code)

    (ASCII Code -> ASCII Character)

    a:= 98; (Code)

    b:= ADR(a);

    c:= b^; (Character)

    Naja und das ganze Schreibt man dann natürlich als Funktion.

    Gruß

    Ralph

     
  • Erik Böhm - 2006-12-20

    Tja, so wie ich das verstehe wäre das ja nur ein casting.

    also ByteWert := INT_TO_BYTE(iWert) und fertig.

     
  • Ralph Holz - 2006-12-20

    Jetzt verstehe ich irgendwie Bahnhof!

    Ich komme genau zu dem gleichen Ergebniss wie Erik! Alles andere macht ihmo keine Sinn. Ein im Speicher abgelegter String benötigt die definierte Länge (also bei Deklaration als STRING 80 Byte oder als STRING(1) 1 Byte) PLUS ein zusätzliches Byte als Separator. D.h. ein 1 Byte langer String braucht 2 Byte! Spart also nichts sondern kostet eher Platz.

     
  • Erik Böhm - 2006-12-20

    Wenn ich mal im 1.Post nachschaue, dann finde ich da

    Zitat: "Aus anderen Sprachen ist dieser Befehl z.B. Char ( Wert)"

    Das ist doch ein casting, oder etwa nicht ?

    Wir haben nur die einfachste Lösung übersehen.

    Einfach ist eben einfach zu einfach...

     
  • boling - 2006-12-21

    ja, manchmal ist es tatsächlich zu einfach, der Tip INT_TO_Byte war richtig. Ist irgendwie auch logisch, nachher...

    Nun komme ich aber dennoch nicht weiter. Ich möchte das Byte in String umwandeln, weil ich regelmässig ein Dutzend Temperaturen abspeichern möchte und diese Werte als String mit Zeitstempel in ein File schreiben kann.

    Aber nun erhalte ich beim Umwandeln in string die Fehlermeldung: Zugriff auf unerlaubte Adresse. Hier das Testprogrämmchen im Simulationsmodus (die Variablen sind korrekt deklariert)

    FOR counter:=0 TO 255 BY 1 DO

    ergebn:=INT_TO_BYTE(counter);

    texas:= ASCIIBYTE_TO_STRING (ergebn) ;

    END_FOR

     
  • Denkes - 2006-12-21

    Hallo boling

    nach deinem Progrämmchen steht in ergebnis kein ASCII-Zeichen sondern deine Zahl im Format USINT

    Diese kannst du problemlos in einen String wandeln mit der Konvertierung BYTE_TO_STRING

    Eine Konvertierung ASCIIBYTE_TO_STRING gibt es meines Wissens in CoDeSys nicht.

    Nochmals zusammenfassend:

    Über die Konvertierung INT_TO_BYTE wandelst du den Messwert. Da du genau weist, dass es sich um den Wertebereich 0..255 handelt, darfst du das auch machen, obwohl Informationen verloren gehen. Jetzt steht der Messwert als abrufbare Zahl (nicht Sting) im Byte und damit ist das Ziel erreicht.

    Einfacher und auch schneller erscheint mir aber die folgende Lösung mit dem an dein Beispiel angelehnten Progrämmelchen (mit Variablendeklaration)

    VAR

    counter: INT; ( Reine Zählvariable )

    ergebn: USINT; ( als Speicher im Byte-Format )

    texas: STRING; ( Test, ob sich das Gespeicherte zurücklesen lässt )

    END_VAR

    FOR counter:=0 TO 255 BY 1 DO ( alle Zahlen 0..255 werden getestet )

    ergebn:=INT_TO_USINT(counter); ( abspeichern des "Messwertes" im Byteformat )

    texas:= USINT_TO_STRING(ergebn) ; ( Test, ob sich die Zahl lesen und zum String umwandeln lässt )

    END_FOR ( Ergebnis: Kein Fehler, also alles i.O. )

     
  • boling - 2006-12-24

    Hallo Denkes.

    usint_to_string macht nicht das richtige. Ergibt lediglich die höchste Ziffer als String. Der Befehle ASCIIBYTE_TO_STRING ist in der Standardlib enthalten. Hatte bisher auch funktioniert. Bin mir nun aber nicht sicher, ob das nur im Simulationsmodus nicht geht?!? Ich werde das demnächst an der Anlage selbst testen können und melde mich dann wieder.

    Schöne Festtage allerseits.

     
  • boling - 2006-12-28

    Es ist tatsächlich so, dass der Befehl ASCIIBYTE_TO_STRING im Simulationsmodus nicht geht, auf der Steuerung (750-841) hingegen schon.

    Die Lösung bringt mir mit 15 Byte als String nun 8 Temperaturmesswerte, die Zeit und den Status der Anlage im Journal. So kann ich alle Minuten diese Werte abspeichern und brauche nur wenig Speicher.

    Besten Dank fürs mitdenken und die Tips!

    en guete Rutsch ins 2007.

     
  • hugo - 2007-02-06

    hallo in der oscat lib rev 1.4 zum download unter w www.oscat.de w

    findest du den baustein char() der wandelt einen bytewert in das entsprechende asccii zeichen

     

Log in to post a comment.