Step 7 INT nach HEX umwandeln

Zuviel Werbung?
-> Hier kostenlos registrieren
Hier
Code:
    // Programmnummer von DEZ in ASCII wandeln
    
    t_1000er :=  NEW_JOBNUMBER / 1000;
    SendReceiveTelegramm.SEND.Zeichen[3] := INT_TO_CHAR(t_1000er+48);
    
    t_100er  := (NEW_JOBNUMBER - (t_1000er*1000)) / 100 ;
    SendReceiveTelegramm.SEND.Zeichen[4] := INT_TO_CHAR(t_100er+48);
    
    t_10er   := (NEW_JOBNUMBER - (t_1000er * 1000)- (t_100er * 100)) / 10;
    SendReceiveTelegramm.SEND.Zeichen[5] := INT_TO_CHAR(t_10er + 48);
    
    t_1er    := (NEW_JOBNUMBER - (t_1000er * 1000) - (t_100er * 100) - (t_10er * 10));
    SendReceiveTelegramm.SEND.Zeichen[6] := INT_TO_CHAR(t_1er + 48);
Gruß
Erich
ps. Hier im Forum gibt es genügend Beispiele, wie man Int nach HEX-Ascii wandelt
 
Zuletzt bearbeitet:
ich weiss jetzt nicht wie int_to_char bei classic arbeitet. bei 1500er macht der befehl aus eine 11 dez ein b char. man muss hier nicht 48 hinzuaddieren.

anzatz wäre evtl int_to_string. wenn du unterschiedliche länge hast also z.b. 43 und auch 143 dann musst du das auswerten um zu sehen wo welche stelle die 1er 10er 100er stehen. ist das immer 2-stellig string_1[2] für die 10er und string_1[3] für die 1er-stelle
fc5981 ist fc5 aus den iec

also
SendReceiveTelegramm.SEND.Zeichen[5] := string_1[2];
SendReceiveTelegramm.SEND.Zeichen[6] := string_1[3];
 

Anhänge

  • Zwischenablage01.jpg
    Zwischenablage01.jpg
    69,3 KB · Aufrufe: 14
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
ich weiss jetzt nicht wie int_to_char bei classic arbeitet. bei 1500er macht der befehl aus eine 11 dez ein b char. man muss hier nicht 48 hinzuaddieren.
Das Programm will/soll Ascii-Zeichen senden, deshalb muss sehr wohl 48 (ASCII '0') addiert werden für Werte von 0 bis 9. Größere Werte kommen in dem vom TE gezeigten FB nicht vor, für Werte von 10 bis 15 müsste man natürlich 65 (ASCII 'A') oder 97 (ASCII 'a') addieren.
Gruß
Erich
 
Hoffentlich anschaulich/verständlich:
Code:
    // Tetraden isolieren für NEW_JOBNUMBER 0 .. 32.767
    Rest := NEW_JOBNUMBER ; 
    X3   := Rest/4096 ; Rest := Rest - X3 * 4096 ; // 4096 = 16^3
    X2   := Rest/256  ; Rest := Rest - X2 * 256  ; //  256 = 16^2
    X1   := Rest/16   ; Rest := Rest - X1 * 16   ; //   16 = 16^1
    X0   := Rest ;                                 //    1 = 16^0
    
    // ASCII-Zeichen bilden
    // GrossBuchstabe 'A'=65 +55 ;      Ziffer '0'=48  
    // alternativ
    // KleinBuchstabe 'a'=97 +87 ;      Ziffer '0'=48  
    IF X3 > 9 THEN X3 := X3 + 55 ; ELSE X3 := X3 + 48 ; END_IF ;
    IF X2 > 9 THEN X2 := X2 + 55 ; ELSE X2 := X2 + 48 ; END_IF ;  
    IF X1 > 9 THEN X1 := X1 + 55 ; ELSE X1 := X1 + 48 ; END_IF ;  
    IF X0 > 9 THEN X0 := X0 + 55 ; ELSE X0 := X0 + 48 ; END_IF ;  
    
    SendReceiveTelegramm.SEND.Zeichen[3] := INT_TO_CHAR(X3);
    SendReceiveTelegramm.SEND.Zeichen[4] := INT_TO_CHAR(X2);
    SendReceiveTelegramm.SEND.Zeichen[5] := INT_TO_CHAR(X1);
    SendReceiveTelegramm.SEND.Zeichen[6] := INT_TO_CHAR(X0);

PS:
Um GrossBuchstaben zu produzieren: 55 addieren (denn A-hex entspricht 10 und A-ascii entspricht 65, also 65 - 10 = 55)
Um KleinBuchstaben zu produzieren: 87 addieren (denn a-hex entspricht 10 und a-ascii entspricht 97, also 97 - 10 = 87)
 
Zuletzt bearbeitet:
Hoffentlich anschaulich/verständlich:
Code:
    // Tetraden isolieren für NEW_JOBNUMBER 0 .. 32.767
    Rest := NEW_JOBNUMBER ; 
    X3   := Rest/4096 ; Rest := Rest - X3 * 4096 ; // 4096 = 16^3
    X2   := Rest/256  ; Rest := Rest - X2 * 256  ; //  256 = 16^2
    X1   := Rest/16   ; Rest := Rest - X1 * 16   ; //   16 = 16^1
    X0   := Rest ;                                 //    1 = 16^0
    
    // ASCII-Zeichen bilden
    // GrossBuchstabe 'A'=65 +55 ;      Ziffer '0'=48  
    // alternativ
    // KleinBuchstabe 'a'=97 +87 ;      Ziffer '0'=48  
    IF X3 > 9 THEN X3 := X3 + 55 ; ELSE X3 := X3 + 48 ; END_IF ;
    IF X2 > 9 THEN X2 := X2 + 55 ; ELSE X2 := X2 + 48 ; END_IF ;  
    IF X1 > 9 THEN X1 := X1 + 55 ; ELSE X1 := X1 + 48 ; END_IF ;  
    IF X0 > 9 THEN X0 := X0 + 55 ; ELSE X0 := X0 + 48 ; END_IF ;  
    
    SendReceiveTelegramm.SEND.Zeichen[3] := INT_TO_CHAR(X3);
    SendReceiveTelegramm.SEND.Zeichen[4] := INT_TO_CHAR(X2);
    SendReceiveTelegramm.SEND.Zeichen[5] := INT_TO_CHAR(X1);
    SendReceiveTelegramm.SEND.Zeichen[6] := INT_TO_CHAR(X0);

PS:
Um GrossBuchstaben zu produzieren: 55 addieren (denn A-hex entspricht 10 und A-ascii entspricht 65, also 65 - 10 = 55)
Um KleinBuchstaben zu produzieren: 87 addieren (denn a-hex entspricht 10 und a-ascii entspricht 97, also 97 - 10 = 87)

SUPER, das hat geklappt!
Ich habe lediglich die neuen TEMP Variablen hinzugefügt. Vielen Dank!


Jetzt ist aber ein weiteres Problem hinzugekommen.
Die Kamera quittiert den neuen Job mit "2B". Nun müsste im Baustein ebenfalls die 43 wieder zurück kommen. Wie setzt sich jetzt die 38 zusammen?

job_empfangen.jpg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
        FOR tmp_Zaehler := 1 TO 4 DO
             
             // Daten von ASCII Zeichen in Hexadezimal umwandeln und kopieren // "Hexadezimal" ist hier irreführend
             tmp_WORD := SHL(IN:= tmp_WORD, N := 4); 
             tmp_DATEN := CHAR_TO_BYTE(SendReceiveTelegramm.RECEIVE.Zeichen[tmp_Zaehler + 2]);
             tmp_DATEN := INT_TO_BYTE(BYTE_TO_INT(tmp_DATEN) - 48);
                 
             IF BYTE_TO_INT(tmp_DATEN) >= 10 THEN // war keine ASCII-Ziffer, also noch 7 subtrahieren (wg. GrossBuchstaben)
                    
                tmp_DATEN := INT_TO_BYTE(BYTE_TO_INT(tmp_DATEN) - 7);
                    
                IF BYTE_TO_INT(tmp_DATEN) >= [COLOR=#ff0000][B]6[/B][/COLOR] THEN // Unsinn! Wenn > 32, dann noch 32 subtrahieren, um KleinBuchstaben zu verarbeiten
                        
                    tmp_DATEN := INT_TO_BYTE(BYTE_TO_INT(tmp_DATEN) - 32); 
                        
                END_IF;    
             END_IF;
                 
             tmp_WORD := tmp_WORD OR BYTE_TO_WORD(tmp_DATEN); 
        END_FOR;
In Deinem FB wird falsch abgefragt. >=6 ist Unsinn - vergleich hier mal mit 32.

PS:
Habe nicht geprüft, ob das schon Dein Problem erklärt, aber die Reparatur kann nicht schaden!
 
Zuletzt bearbeitet:
Code:
        FOR tmp_Zaehler := 1 TO 4 DO
             
             // Daten von ASCII Zeichen in Hexadezimal umwandeln und kopieren // "Hexadezimal" ist hier irreführend
             tmp_WORD := SHL(IN:= tmp_WORD, N := 4); 
             tmp_DATEN := CHAR_TO_BYTE(SendReceiveTelegramm.RECEIVE.Zeichen[tmp_Zaehler + 2]);
             tmp_DATEN := INT_TO_BYTE(BYTE_TO_INT(tmp_DATEN) - 48);
                 
             IF BYTE_TO_INT(tmp_DATEN) >= 10 THEN // war keine ASCII-Ziffer, also noch 7 subtrahieren (wg. GrossBuchstaben)
                    
                tmp_DATEN := INT_TO_BYTE(BYTE_TO_INT(tmp_DATEN) - 7);
                    
                IF BYTE_TO_INT(tmp_DATEN) >= [COLOR=#ff0000][B]6[/B][/COLOR] THEN // Unsinn! Wenn > 32, dann noch 32 subtrahieren, um KleinBuchstaben zu verarbeiten
                        
                    tmp_DATEN := INT_TO_BYTE(BYTE_TO_INT(tmp_DATEN) - 32); 
                        
                END_IF;    
             END_IF;
                 
             tmp_WORD := tmp_WORD OR BYTE_TO_WORD(tmp_DATEN); 
        END_FOR;
In Deinem FB wird falsch abgefragt. >=6 ist Unsinn - vergleich hier mal mit 32.

Nach der Änderung bleibt es weiterhin bei 38...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich durchschaue den FB noch nicht so recht :oops:
Code:
    // ASCII-Zeichen dekodieren für 4-stellige HexZahl
    // Ziffer '0'=48 ; ggfs GrossBuchstabe 'A'=65 ; ggfs KleinBuchstabe ('a'='A'+32)
    X3 := X3 - 48 ; IF X3 > 9 THEN X3 := X3 - 7 ; IF X3 > 32 THEN X3 := X3 - 32 ; END_IF ; END_IF ;  
    X2 := X2 - 48 ; IF X2 > 9 THEN X2 := X2 - 7 ; IF X2 > 32 THEN X2 := X2 - 32 ; END_IF ; END_IF ;
    X1 := X1 - 48 ; IF X1 > 9 THEN X1 := X1 - 7 ; IF X1 > 32 THEN X1 := X1 - 32 ; END_IF ; END_IF ;
    X0 := X0 - 48 ; IF X0 > 9 THEN X0 := X0 - 7 ; IF X0 > 32 THEN X0 := X0 - 32 ; END_IF ; END_IF ;
    Ergebnis := X3 * 4096 + X2 * 256 + X1 * 16 + X0
Am Anfang müssen X3 .. X0 je 1 Byte mit 1 ASCII-Zeichen enthalten.
Hilft Dir das weiter?
Vielleicht reicht folgendes
Code:
    // ASCII-Zeichen dekodieren für 2-stellige HexZahl
    // Ziffer '0'=48 ; ggfs GrossBuchstabe 'A'=65 ; ggfs KleinBuchstabe ('a'='A'+32)
    X1 := X1 - 48 ; IF X1 > 9 THEN X1 := X1 - 7 ; IF X1 > 32 THEN X1 := X1 - 32 ; END_IF ; END_IF ;
    X0 := X0 - 48 ; IF X0 > 9 THEN X0 := X0 - 7 ; IF X0 > 32 THEN X0 := X0 - 32 ; END_IF ; END_IF ;
    Ergebnis := X1 * 16 + X0
Am Anfang müssen X1 .. X0 je 1 Byte mit 1 ASCII-Zeichen enthalten.
 
Ich verstehe nicht, wo in dem Code auf das SendReceiveTelegramm.RECEIVE.Zeichen[7] bis [10] zugegriffen wird....
 
Und mir ist nicht klar, welche Informationen wo im Telegramm zu erwarten sind.
Woher nimmst Du "2b"?
In dem FB werden
SendReceiveTelegramm.RECEIVE.Zeichen[3]
bis
SendReceiveTelegramm.RECEIVE.Zeichen[6]
gelesen und dann als HEX versucht zu interpretieren.
(SendReceiveTelegramm.RECEIVE.Zeichen[tmp_Zaehler + 2] mit FOR tmp_Zaehler := 1 TO 4)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe nicht, wo in dem Code auf das SendReceiveTelegramm.RECEIVE.Zeichen[7] bis [10] zugegriffen wird....
SendReceiveTelegramm.RECEIVE.Zeichen[7..10] ist die Jobnummer in Hex-ASCII - die müsste bei "STATUS.AKTIVER_JOB := ..." noch korrekt umgewandelt werden. (der FB wandelt Dezimal-ASCII)
SendReceiveTelegramm.RECEIVE.Zeichen[3..6] ist ein Bitfeld: "tmp_WORD_BOOL AT tmp_WORD : ARRAY[0..15] OF BOOL;"


Welche Werte kann NEW_JOBNUMBER eigentlich haben? NEW_JOBNUMBER ist als INT deklariert und könnte deshalb auch negative Werte haben!
0 .. 9999 (0 .. 16#270F)?
Bei 0 .. 32767 kann X3 nur 0 .. 7 sein.


Viele Wege führen nach Rom. Hexziffern-Zerlegung kann man auch so:
Code:
    X3 := NEW_JOBNUMBER/4096 ;         // 4096 = 16^3
    X2 := (NEW_JOBNUMBER/256) MOD 16 ; //  256 = 16^2
    X1 := (NEW_JOBNUMBER/16) MOD 16 ;  //   16 = 16^1
    X0 := NEW_JOBNUMBER MOD 16 ;       //    1 = 16^0
(Je nachdem was der Compiler zulässt, kann man anstatt "MOD 16" auch "AND 15" oder "AND 16#F" nehmen. Und für die Divisionen SHR().)

4 ASCII-Hex-Ziffern ('0000' .. 'FFFF') zu WORD wandeln
(hier SendReceiveTelegramm.RECEIVE.Zeichen[3..6], Code wird für SendReceiveTelegramm.RECEIVE.Zeichen[7..10] nochmal gebraucht)
Code:
        tmp_WORD := 0;  //(kann auch weglassen)
        FOR tmp_Zaehler := 1 TO 4 DO

            // Daten von ASCII-HEX in Dezimal umwandeln
            tmp_c := BYTE_TO_INT(CHAR_TO_BYTE(SendReceiveTelegramm.RECEIVE.Zeichen[tmp_Zaehler + 2]));
            CASE tmp_c OF
              '0'..'9': tmp_c := tmp_c - '0';        //ASCII '0'..'9' --> dez  0 .. 9
              'A'..'F': tmp_c := tmp_c - 'A' + 10;   //ASCII 'A'..'F' --> dez 10 .. 15
              'a'..'f': tmp_c := tmp_c - 'a' + 10;   //ASCII 'a'..'f' --> dez 10 .. 15
            ELSE
                tmp_c := 0;     //unzulässiges Zeichen ---> sollte Fehlerbehandlung
            END_CASE;

            tmp_WORD := SHL(IN:= tmp_WORD, N := 4) OR INT_TO_WORD(tmp_c);
        END_FOR;
alternativ für "CASE tmp_c .. END_CASE;":
Code:
            IF tmp_c >= '0' AND tmp_c <= '9' THEN
                tmp_c := tmp_c - '0';                //ASCII '0'..'9' --> dez  0 .. 9
            ELSIF tmp_c >= 'A' AND tmp_c <= 'F' THEN
                tmp_c := tmp_c - 'A' + 10;           //ASCII 'A'..'F' --> dez 10 .. 15
            ELSIF tmp_c >= 'a' AND tmp_c <= 'f' THEN
                tmp_c := tmp_c - 'a' + 10;           //ASCII 'a'..'f' --> dez 10 .. 15
            ELSE
                tmp_c := 0;     //unzulässiges Zeichen ---> sollte Fehlerbehandlung
            END_IF;

Harald
 
Sooo . . .
Code:
    X3 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[7] ;
    X2 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[8] ;
    X1 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[9] ;
    X0 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[10] ;
    // ASCII-Zeichen dekodieren
    // Ziffer '0'=48 ; ggfs GrossBuchstabe 'A'=65 ; ggfs KleinBuchstabe ('a'='A'+32)
    X3 := X3 - 48 ; IF X3 > 9 THEN X3 := X3 - 7 ; IF X3 > 32 THEN X3 := X3 - 32 ; END_IF ; END_IF ;  
    X2 := X2 - 48 ; IF X2 > 9 THEN X2 := X2 - 7 ; IF X2 > 32 THEN X2 := X2 - 32 ; END_IF ; END_IF ;
    X1 := X1 - 48 ; IF X1 > 9 THEN X1 := X1 - 7 ; IF X1 > 32 THEN X1 := X1 - 32 ; END_IF ; END_IF ;
    X0 := X0 - 48 ; IF X0 > 9 THEN X0 := X0 - 7 ; IF X0 > 32 THEN X0 := X0 - 32 ; END_IF ; END_IF ;
    STATUS.AKTIVER_JOB := X3 * 4096 + X2 * 256 + X1 * 16 + X0
 
Code:
X3 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[7] ;
X2 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[8] ;
X1 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[9] ;
X0 := CHAR_TO_INT(SendReceiveTelegramm.RECEIVE.Zeichen[10] ;
// ASCII-Zeichen dekodieren
// Ziffer '0'=48 ; ggfs GrossBuchstabe 'A'=65 ; ggfs KleinBuchstabe ('a'='A'+32)
X3 := X3 - 48 ; IF X3 > 9 THEN X3 := X3 - 7 ; IF X3 > 32 THEN X3 := X3 - 32 ; END_IF ; END_IF ;
X2 := X2 - 48 ; IF X2 > 9 THEN X2 := X2 - 7 ; IF X2 > 32 THEN X2 := X2 - 32 ; END_IF ; END_IF ;
X1 := X1 - 48 ; IF X1 > 9 THEN X1 := X1 - 7 ; IF X1 > 32 THEN X1 := X1 - 32 ; END_IF ; END_IF ;
X0 := X0 - 48 ; IF X0 > 9 THEN X0 := X0 - 7 ; IF X0 > 32 THEN X0 := X0 - 32 ; END_IF ; END_IF ;
STATUS.AKTIVER_JOB := X3 * 4096 + X2 * 256 + X1 * 16 + X0


Yeah, das funktioniert. Ich bin wirklich sehr glücklich!! Vielen lieben Dank für die gute Unterstützung!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin bmwled,
Danke für die Blumen, aber verdient hat sie Harald mit seinem Beitrag #32 !!!
Denn ich hoffe, dass es Dir nicht nur darauf ankommt, Dein Problem "irgendwie" gelöst zu haben, sondern, dass Du Dir auch gut, geschickt, gut lesbar . . . zu programmieren angewöhnen möchtest. Haralds Beiträge sind immer vorbildlich!

Gruss, Heinileini
 
Zurück
Oben