Forum: PC-Programmierung C++ NMEA-checksum


von Cnewbie (Gast)


Lesenswert?

Hallo,

ich möchte von jedem Daten der von der GPS-Maus kommt die Checksumme 
berechnen.
1
int CheckChecksum(char* packet)
2
{
3
  unsigned char Character,x;
4
  unsigned int Checksum = 0;
5
  int i,length;
6
7
  length = strlen(packet);
8
9
  for(i=0;i<length;i++)
10
  {
11
    Character = packet[i];
12
    
13
    if (Character == '$')
14
    {
15
      // Ignore the dollar sign
16
    }
17
    else if (Character == '*')
18
    {
19
      // Stop processing before the asterisk
20
      break;
21
    }
22
    else
23
    {
24
      if(Character != '$')
25
        Checksum ^= Character;
26
    }
27
  } 
28
 return 0;
29
}

Datensatz:

$GPRMC,081638,V,4856.4987,N,00822.1526,E,,,250707,000.6,E*61

Checksumme: 61

Mit meiner Funktion erhalte ich da 97. Wo könnte da der Fehler liegen?

von Cnewbie (Gast)


Lesenswert?

Ich Trottel,

61 ist ja eine Hex Zahl. Wenn ich diese Zahl in dezimal umwandle, dann 
erhalte ich auch die Zahl 97.

von Simon K. (simon) Benutzerseite


Lesenswert?

Cnewbie wrote:
>       if(Character != '$')

Ist unnötig, da du in den Else-Block eh nur reinkommst, wenn der 
Charakter nicht '$' war.

von Olaf S. (olaf2001)


Lesenswert?

Interessanterweise liefert die Funktion immer 0 zurück... Ein wenig 
umständlich ist das ganze zudem formuliert:
1
unsigned char Character;
2
unsigned int i=1, Checksum = 0;
3
4
if (strlen(packet) == 0) return 0;
5
6
while (packet[i] != '*')
7
{
8
   Checksum ^= packet[i++];
9
}
10
return Checksum;

von Rolf Magnus (Gast)


Lesenswert?

> if (strlen(packet) == 0) return 0;

Den gesamten String durchparsen, um festzustellen, ob er leer ist, 
könnte man auch als "umständlich" bezeichnen, vor allem, weil man dafür 
gar keine Sonderbehandlung braucht.
Außerdem wird dein Code amoklaufen, wenn im String mal kein Stern 
enthalten ist. Dazu kann es Probleme geben, wenn char vorzeichenbehaftet 
ist. Ich würd's wohl etwa so schreiben:
1
unsigned char Checksum = 0;
2
++packet;
3
while (*packet != '*' && *packet != '\0')
4
   Checksum ^= *(unsigned char*)packet++;
5
6
return Checksum;

Wobei ich zum Iterieren eigentlich gerne auch eine for-Schleife nehme:
1
for (packet++; *packet != '*' && *packet != '\0'; packet++)
2
   Checksum ^= *(unsigned char*)packet;

von Simon K. (simon) Benutzerseite


Lesenswert?

Rolf Magnus wrote:
> Code [....]

Der Code läuft aber nicht, wenn "packet" folgendes ist:

+---+---+---+
|\0 |'a'|...|
+---+---+---+

Zumindest, wenn du mit dem End-Of-String Check erst beim Element 1 
anfängst.

Oder überseh ich was?

von Rolf Magnus (Gast)


Lesenswert?

Stimmt. Ich übergehe ja einfach das erste Zeichen. Dann ist mir jetzt 
auch klar, wozu der Check auf eine Größe von 0 bei Olafs Code da war.

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.