TIA TIA String Daten als HEX interpretieren (nicht umwandeln!)

Manney

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

Sitze seit geraumer Zeit an einem verzwickten Problem:

Ich lese von einem Can-Teilnehmer mehrere Daten aus. 8 16 und 32 Bit Dezimalwerte stellen keine Probleme dar.
Jedoch sendet mir der Teilnehmer auch einige andere Daten.
Ein Beispiel (Telegramm bereits in String umgewandelt):

'M SD8 0582 00 48 44 2D 48 36 30 20'

Dieses Telegramm beinhaltet einen 7-stelligen Text.

Es sollte später folgende Informationen widerspiegeln: 'HD-H60 '
Die Informationen kann ich in diesem Telegramm auch schon erkennen wenn ich die Textinformationen von Hex in Char umwandle:

48 -> H
44 -> D
2D -> -
48 -> H
36 -> 6
30 -> 0
20 -> "leer"

Das große Problem an der Sache ist nun allerdings, dass die Informationen im String-Format jedoch als Hex interpretiert werden müssten.
Einfach ausgedrückt ich müsste den Text '48' als Hex 0x48 interpretieren um an die richtigen Informationen zu kommen.

Die Infos werden vom Can-Teilnehmer in ein 128 Byte Array eingelesen. Beispiel für 'M SD8 0582 00 48 44 2D 48 36 30 20'

Ich habe folgende Informationen im DB stehen:

Byte 14 16#34 Umwandeln in Char > 4
Byte 15 16#38 Umwandeln in Char > 8

Hat irgendjemand eine Idee wie ich die Daten "korrekt" in mein gewünschtes Format gewandelt kriege?
Mir gehen aktuell leider die Ideen aus...

Danke schon mal im Voraus.

Gruß
Manney
 
Du müsstest je zwei ASCII-Zeichen von hex nach UINT wandeln und den UINT als CHAR interpretieren. Dafür könntest Du die Anweisung ATH verwenden oder gleich ganz low Level "zu Fuß" programmieren.
Hier ein Beispiel (ist zwar Codesys-ST, kannst Du aber als Vorlage für SCL verwenden).

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das grosse Problem an der Sache ist nun allerdings, dass die Informationen im String-Format jedoch als Hex interpretiert werden müssten.
Wer muss aus welchem Grund als HEX interpretieren??? Hast Du Dich in diese "Forderung" verrannt? Ich verstehe Dein Problem nicht :oops:
 
Wer muss aus welchem Grund als HEX interpretieren??? Hast Du Dich in diese "Forderung" verrannt? Ich verstehe Dein Problem nicht :oops:

Leider hab ich mich da nicht verrannt.
Habe sowas auch noch nie gesehen jedoch übermittelt mir der Can-Teilnehmer die 128 Byte Daten welche ich zuerst als String interpretieren muss.
Und um meine Firmwarebezeichnungen aus diesem Text rausfischen zu können muss ich 7x2Chars als Hex interpretieren.

In meinem Beispiel:

String: 'M SD8 0582 00 48 44 2D 48 36 30 20'

Und das fett markierte muss ich schlussendlich als:

String: 'HD-H60 '

ausgeben.

Und das gestaltet sich in der 1500er SPS als gar nicht mal so leicht. Zumindest mit normalen Funktionen.
Hab mir das nun in nem "Umwandelbaustein" selber geschrieben da ich anders zu keiner Lösung gekommen bin...

Gruß
Manney
 
Vielleicht versteckt sich der Grund für Dein Problem in ...
Ein Beispiel (Telegramm bereits in String umgewandelt):
'M_SD8_0582_00_48_44_2D_48_36_30_20'
... ?
Wer hat das Telegramm bereits in String umgewandelt? Hast Du Einfluss auf diese Umwandlung? Kannst Du sie für die besagten 7 Byte weglassen und stattdessen in ASCII wandeln?
Wie sieht denn Dein empfangenes Telegramm "im Original" aus? Woher kommen in Deinem Beispiel die LeerZeichen (habe sie mal durch Unterstriche ersetzt) und warum bzw. woher die Gruppierung zu 1, 2, 3 oder 4 Zeichen zwischen den LeerZeichen? Hier scheint doch schon reichlich (vermutlich zuviel bzw. falsch) "interpretiert" worden zu sein - irgendwas verschweigst Du uns anscheinend.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Umwandlung in den besagten String geschieht wie oben beschrieben in der SPS also wird das von mir gemacht.
Das Originaltelegramm besteht aus 128 Byte.
Der Can Teilnehmer liefert mir über einen Can-Profinet Umsetzer dieses Telegramm.
Im Can-Open Standard wird ja mittels einer Kennung übermittelt wie lange die tatsächlichen Daten sind. 8 16 oder 32 Bit beispielsweise.
Das hier ist aber offensichtlich fernab vom Standard. Zumindest von dem Teil den ich weiß...

Besagter String 'M SD8 0582 00 48 44 2D 48 36 30 20' entspricht also auch tatsächlich den gesendeten Daten.

Nachfolgend die Daten die in den einzelnen übertragenen Bytes vor der Umwandlung stehen:

Byte 14: 16#34
Byte 15: 16#38
Byte 16: 16#20
Byte 17: 16#34
Byte 18: 16#34

Entspricht also in Chars genau dem Telegrammteil '48 44'
Der Kunde hat es mir auch so ausgelistet. Es stehen also tatsächlich im String Daten die als Hex interpretiert werden müssen.

Ob das sinnvoll ist oder nicht bleibt mal dahingestellt...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Mich würde zwar interessieren ob noch jemand ne galantere Methode wüsste um das umzusetzen
Eine galantere Methode als welche? Wo können wir sie begutachten?
Mein bisheriges Verständnis:
Aus 7 DreierGruppen von Bytes (bzw. 6 DreierGruppen und 1 ZweierGruppe)
- musst Du ermitteln, welche Bytes die TrennZeichen beinhalten, diese ggfs prüfen und wegschmeissen
- bei den restlichen Zeichen prüfen, ob sie im Bereich '0' .. '9', 'A' .. 'F' oder 'a' .. 'f' liegen und sie ggfs in die entsprechende DezimalZahl 0 .. 15 "umrechnen"
- den 16-fachen Wert der ersten Zahl nach einem TrennZeichen zum Wert der zweiten Zahl nach einem TrennZeichen addieren und das Ergebnis als ASCII-Zeichen in die nächste Position des Strings eintragen.
Also: ProgrammSchleife, die 7mal durchlaufen wird, in jedem SchleifenDurchlauf 2 (bis 3) Zeichen auswertet und daraus 1 ErgebnisZeichen macht.

Ist irgendwie "ungalant", aber das ist der Tatsache zu verdanken, dass im Telegramm jedes dieser 7 ASCII-Zeichen in jeweils 2 ASCII-Zeichen plus TrennZeichen codiert ist.
 
Aktuell wird es bei mir folgendermaßen gelöst:
For.jpg
Die Daten stehen im String immer an der gleichen Position. Also Pos. 15 18 .... 33.
Der Umwandelbaustein wird in der Schleife dann die 7x aufgerufen und die ausgegebenen Chars zu einem String zusammengefügt.
Das ganze passiert in der Schrittkette noch mehrmals, da ich über das Serientelegramm 5x Teildaten für die gewünschte Firmwarenummer erhalte.

Im aufgerufenen FC werden schlicht 2 Chars übergeben als Hex interpretiert und als 1 Char ausgegeben.
Auszug:
fc.jpg

Ne "schönere" Lösung liegt wie immer im Auge des Betrachters.
Für mich war es die schnellste da es natürlich eilig war...
 
Die von Harald in #2 vorgeschlagene Lösung mit CASE ...
Code:
[LEFT][COLOR=#333333][FONT=Courier][I]        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;[/I][/FONT][/COLOR][/LEFT]
... wäre sinngemäss angepasst statt der IF-ELSIF-END_IF-Konstruktion schon um einiges "galanter"! Aber wie Du schon sagst, "... im Auge des Betrachters" ...

Edit:
Sorry, habe mich durch Deinen CodeAusschnitt irritieren lassen . . . Du erwartest doch nicht nur die Ziffern 0 .. 9 und die Buchstaben A ... F als Ergebnis, sondern in Deinem Beispiel auch 'H' oder '-' also diverse bis alle "druckbaren" ASCII-Zeichen!?! Da sind nach Deiner Methode 95 Vergleiche erforderlich! Und das Umschwenken auf CASE wäre auch nicht von nennenswertem Vorteil.
Die irgendwann vorausgegangene Umwandlung des OriginalTelegramms in STRING erfordert beim Dekodieren eine Stufe mehr an Umwandlung, die man umgehen könnte.

PS:
Zum Trost hier noch einige Beispiele in Excel VBA und als TabellenBlattFormeln für "zu-Fuss"-Umwandlungen von 1 Zeichen von HEX(ASCII)-in-DEZ, die alle darauf beruhen, das zu wandelnde Zeichen in einer StringKonstante zu finden:
Code:
' Hex(ASCII)-in-Dezimal-Wandlung für VBA / zu wandelndes Zeichen in x$
' Kommentare zeigen entsprechende Excel-TabellenBlattFormeln / zu wandelndes Zeichen in Zelle 'A1'

decNoBlankA = (InStr("0123456789ABCDEF0123456789abcdef", x$) - 1) Mod 16
decNoBlankB = InStr("0123456789ABCDEF", UCase$(x$)) - 1
' =WENN(ISTFEHLER(SUCHEN(A1;"0123456789ABCDEF"));-1;SUCHEN(A1;"0123456789ABCDEF")-1)

dec04BlankA = (InStr("0123456789ABCDEF 123456789abcdef", x$) - 1) Mod 16
dec04BlankB = (InStr("0123456789ABCDEF ", UCase$(x$)) - 1) Mod 16
' =WENN(ISTFEHLER(SUCHEN(A1;"0123456789ABCDEF "));-1;REST(SUCHEN(A1;"0123456789ABCDEF ")-1;16))

decUpperOnly = InStr("0123456789ABCDEF", x$) - 1
' =WENN(ISTFEHLER(FINDEN(A1;"0123456789ABCDEF"));-1;FINDEN(A1;"0123456789ABCDEF")-1)

decLowerOnly = InStr("0123456789abcdef", x$) - 1
' =WENN(ISTFEHLER(FINDEN(A1;"0123456789abcdef"));-1;FINDEN(A1;"0123456789abcdef")-1)
Für ein nicht dekodierbares Zeichen wird -1 zurückgegeben.
Die 04Blank-Varianten liefern 0 für ein LeerZeichen.
Zu den TabellenBlattFormeln: SUCHEN unterscheidet nicht zwischen Gross- und KleinBuchstaben, FINDEN jedoch sehr wohl.
 
Zuletzt bearbeitet:
Zurück
Oben