www.mikrocontroller.net

Forum: PC-Programmierung C++ NMEA-checksum


Autor: Cnewbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte von jedem Daten der von der GPS-Maus kommt die Checksumme 
berechnen.
int CheckChecksum(char* packet)
{
  unsigned char Character,x;
  unsigned int Checksum = 0;
  int i,length;

  length = strlen(packet);

  for(i=0;i<length;i++)
  {
    Character = packet[i];
    
    if (Character == '$')
    {
      // Ignore the dollar sign
    }
    else if (Character == '*')
    {
      // Stop processing before the asterisk
      break;
    }
    else
    {
      if(Character != '$')
        Checksum ^= Character;
    }
  } 
 return 0;
}

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?

Autor: Cnewbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich Trottel,

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cnewbie wrote:
>       if(Character != '$')

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

Autor: Olaf Stieleke (olaf2001)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessanterweise liefert die Funktion immer 0 zurück... Ein wenig 
umständlich ist das ganze zudem formuliert:
unsigned char Character;
unsigned int i=1, Checksum = 0;

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

while (packet[i] != '*')
{
   Checksum ^= packet[i++];
}
return Checksum;

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
unsigned char Checksum = 0;
++packet;
while (*packet != '*' && *packet != '\0')
   Checksum ^= *(unsigned char*)packet++;

return Checksum;

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.