Forum: Compiler & IDEs Dezimal zu Hex


von Philipp M. (lord-maricek)


Lesenswert?

Moin,

ich hab schon gesucht aber nichts passendes gesucht, sorry wenn ich was 
übersehen habe.

Ich decodiere einen NMEA GPS Satz und möchte die Checksumme überprüfen.
Ich erstelle die Checksumme mit einer for Schleife, und speicher sie in 
einem unsigned char.

Die Checksumme, die am Satz hinten dranhängt sind aber 2 Ascii 
Buchstaben bzw. kann man die auch in einen Integer konvertieren.

Aber wie kann ich die Checksummen vergleichen?

MfG
Philipp
1
unsigned char checksum = 0x00;
2
        for(unsigned char i=0;i<=this->indexer;i++)
3
        {
4
            if(this->buffer[i]=='*')
5
            {
6
                break;
7
            }
8
            else if(this->buffer[i]!='$')
9
            {
10
                checksum ^= this->buffer[i];
11
            }
12
        }

this ist ein Pointer auf ein Struct

von Karl H. (kbuchegg)


Lesenswert?

Philipp Maricek schrieb:

> Die Checksumme, die am Satz hinten dranhängt sind aber 2 Ascii
> Buchstaben bzw. kann man die auch in einen Integer konvertieren.

natürlich.

wenn du 2 Ziffern hast   3 und 4
dann ist die entsprechende Dezimalzahl
   x = erste_Ziffer * 10 + zweite_Ziffer

Aus 3 und 4  wird so     3 * 10 + 4 -> 34

jetzt hast du aber keine Dezimalziffern, sondern Hex-Ziffern. Und die 
auch noch nicht in Zahlenform sondern als 'Buchstaben'. Also wird es 
wohl schlau sein, sich diese 'BUchstaben' erst mal in richtige Zahlen zu 
verwandeln und dann .... bei Dezimalziffern wird die erste Zahl mit 10 
Multipliziert, bei Hexadezimalziffern dann eben mit 16

> Aber wie kann ich die Checksummen vergleichen?

Du kannst aber auch deine errechnete Checksumme in einen String 
verwandeln und dann einen Stringvergleich machen. Ist halt in der 
umgekehrten Richtung. Aber aus dem NMEA die CHecksumme numerisch zu 
machen dürfte etwas einfacher und auch schneller sein.

von Jürgen S. (jsachs)


Lesenswert?

Dein Wert in "checksum" ist ja schon Hex.
Du musst also nur deine Checksumme von ASCII in "hex" umrechnen, dazu 
gibt es Funktionen oder eben manuell in der Art:
1
unsigned char chk = 0x00;
2
// von ASCII nach hex (binär)
3
if ((this->buffer[i] >= 0) && (this->buffer[i] <= 9 ))
4
     chk+=(this->buffer[i] - '0');
5
else if ((this->buffer[i] >= 'a') && (this->buffer[i] <= 'f'))
6
     chk+=(this->buffer[i] - 'a' + 10);
7
// auch für "i+1" machen
8
9
if (chk == checksumme)
10
     -> alles gut
11
else
12
     -> ups schlecht.

Der Code setzt voraus das dein ASCII in kleinbuchstaben ist, sonst eben 
anapssen.
Habs nicht gecheckt, aber als Richtung sollte es reichen :-)

Gruss
Juergen

von Philipp M. (lord-maricek)


Lesenswert?

Ok, danke,

aber müsste es hier nicht heißen:
1
if ((this->buffer[i] >= '0') && (this->buffer[i] <= '9' ))

statt
1
if ((this->buffer[i] >= 0) && (this->buffer[i] <= 9 ))

MfG
Philipp

von Jürgen S. (jsachs)


Lesenswert?

Correct.

Wie gesagt das war nur pro forma.

Gruss
Juergen

von Philipp M. (lord-maricek)


Lesenswert?

Hi,
leider funtzt das bei mir nicht so richtig.

Als test benutzte ich diesen NMEA Satz.
1
$GPRMC,191410,A,4735.5634,N,00739.3538,E,0.0,0.0,181102,0.4,E,A*19

Ich habe die Funktion noch erweitert, dass groß und Kleinbuchstaben 
verwendet werden können.

Hier der Code: Die letzten beiden Chars lasse ich mit auch ausgeben und 
bekomme auch 19 angezeigt, also ist das nicht das Problem und er gehts 
in
der Abfrage in 0-9, also das auch richtig.
1
unsigned char checksum = 0x00;
2
3
        printf("Last chars: %c, %c\n",this->buffer[this->indexer-1],this->buffer[this->indexer]);
4
        unsigned char chk = 0x00;
5
        if ((this->buffer[this->indexer-1] >= '0') && (this->buffer[this->indexer-1] <= '9' ))
6
        {
7
            chk+=(this->buffer[this->indexer-1] - '0');
8
            printf("\nChar 1: 0-9\n");
9
        }
10
        else if ((this->buffer[this->indexer-1] >= 'A') && (this->buffer[this->indexer-1] <= 'F'))
11
        {
12
            chk+=(this->buffer[this->indexer-1] - 'A' + 10);
13
            printf("\nChar 1: A-F\n");
14
        }
15
        else if ((this->buffer[this->indexer-1] >= 'a') && (this->buffer[this->indexer-1] <= 'f'))
16
        {
17
            chk+=(this->buffer[this->indexer-1] - 'a' + 10);
18
            printf("\nChar 1: a-f\n");
19
        }
20
21
22
        if ((this->buffer[this->indexer] >= '0') && (this->buffer[this->indexer] <= '9' ))
23
        {
24
            chk+=(this->buffer[this->indexer] - '0');
25
            printf("\nChar 2: 0-9\n");
26
        }
27
        else if ((this->buffer[this->indexer] >= 'A') && (this->buffer[this->indexer] <= 'F'))
28
        {
29
            chk+=(this->buffer[this->indexer] - 'A' + 10);
30
            printf("\nChar 2: A-F\n");
31
        }
32
        else if ((this->buffer[this->indexer] >= 'a') && (this->buffer[this->indexer] <= 'f'))
33
        {
34
            chk+=(this->buffer[this->indexer] - 'a' + 10);
35
            printf("\nChar 2: a-f\n");
36
        }
37
        printf("Check: %x\n",chk);

Wenn ich mir das am ende ausgeben lasse, bekomme ich als Hex nur 'a' 
ausgeben.

Was ist falsch?

MfG
Philipp

von visitor (Gast)


Lesenswert?

Moin,

Du kannst auch strtol verwenden um die ASCII Zeichen der Checksumme in 
einen numerischen Wert zu wandeln. Bei strtol kann man die Basis mit 
angeben.

von visitor (Gast)


Lesenswert?

Du rechnest 1 + 9 = 10.  10 in hex angezeigt ist a.
Die Ausgabe ist korrekt, aber die erste Stelle gibt ja
das Vielfache von 16 an. Also 1*16 + 9 = 25.
25 in hex ist dann 19h.

von Karl H. (kbuchegg)


Lesenswert?

Un dtu dir selbst einen Gefallen und schreib dir ein paar Funktionen zu 
diesem thema
1
unsigned char hexDigit( char c )
2
{
3
  if( c >= '0' && c <= '9' )
4
    return c - '0';
5
6
  if( c >= 'a' && c <= 'f' )
7
    return c - 'a' + 10;
8
9
  if( c >= 'A' && c <= 'F' )
10
    return c - 'A' + 10;
11
12
  return 0;
13
}
14
15
unsigned char toHex( char c1, char c2 )
16
{
17
  return hexDigit(c1) * 16 + hexDigit(c2);
18
}
19
20
21
....
22
23
24
25
  unsigned char checksumNMEA = toHex( this->buffer[this->indexer-1],
26
                                      this->buffer[this->indexer] );

von Philipp M. (lord-maricek)


Lesenswert?

Ok, danke jetzt läufts wunderbar.

MfG
Philipp

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.