开发者

nmea checksum in c# .net cf

I'm trying to write my own nmea parser,since i only need some info from the gps, and don't need to interpret all messages. The problem that i have is that my nmea message validator gives me an wrong checksum. Can someone see what i'm droing wrong?

I'm using the idea from Codepedia - Calculating and Validating nmea sentences.

    // Returns True if a sentence's checksum matches t开发者_运维问答he 
    // calculated checksum
    // Calculates the checksum for a sentence
    private static bool IsValid(string sentence)
    {
        if (sentence == "")
            return false;
        if (sentence.Length < 14)
            return false;
        try
        {
            string[] Words = GetWords(sentence);
            Log.writeToLog(Words);
            int checksum = 0;
            string CheckToCompare = Words[Words.Length - 1];
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i < (Words.Length - 2); i++)
            {
                sb.Append(Words[i]);
            }
            string sentecenToParse = sb.ToString();

            foreach (char charY in sentecenToParse)
            {
                checksum ^= Convert.ToByte(charY);
            }


            Log.writeToLog("Checksum: " + checksum.ToString("X2"));
            Log.writeToLog("Obtained CheckSum: " + CheckToCompare);
            return String.Equals(checksum.ToString("X2"), CheckToCompare, StringComparison.OrdinalIgnoreCase);
        }
        catch (Exception exc)
        {
            Log.writeToLog("Exception caused by sentence:" + sentence);
            Log.writeToLog("Exception error message: " + exc.Message);
            return false;
        }


    }

    // Divides a sentence into individual Words
    public static string[] GetWords(string sentence)
    {
        char[] separator = { ',', '*' };
        return sentence.Split(separator);
    }

Run LOG

10:30:07 23-02-2011 Opening Port
10:30:08 23-02-2011 Opened Port
10:30:10 23-02-2011 Processing Data
10:30:12 23-02-2011 $GPGGA
10:30:12 23-02-2011 102957.92
10:30:12 23-02-2011 4104.8569
10:30:12 23-02-2011 N
10:30:12 23-02-2011 00836.4700
10:30:12 23-02-2011 W
10:30:12 23-02-2011 1
10:30:12 23-02-2011 4
10:30:12 23-02-2011 15.100
10:30:12 23-02-2011 157.133
10:30:12 23-02-2011 M
10:30:12 23-02-2011 52.386
10:30:12 23-02-2011 M
10:30:12 23-02-2011 0
10:30:12 23-02-2011 0
10:30:13 23-02-2011 79

10:30:13 23-02-2011 Checksum: 6D
10:30:13 23-02-2011 Obtained CheckSum: 79

10:30:13 23-02-2011 Invalid sentence
10:30:13 23-02-2011 $GPRMC
10:30:13 23-02-2011 102957.92
10:30:13 23-02-2011 A
10:30:13 23-02-2011 4104.8569
10:30:13 23-02-2011 N
10:30:13 23-02-2011 00836.4700
10:30:13 23-02-2011 W
10:30:13 23-02-2011 0.000
10:30:13 23-02-2011 5.822
10:30:13 23-02-2011 230211
10:30:13 23-02-2011 0
10:30:13 23-02-2011 W
10:30:14 23-02-2011 A
10:30:14 23-02-2011 2B

10:30:14 23-02-2011 Checksum: 4E
10:30:15 23-02-2011 Obtained CheckSum: 2B
10:30:15 23-02-2011 Invalid sentence


If you use this function from the page you linked:

private static string getChecksum(string sentence)
{
  //Start with first Item
  int checksum= Convert.ToByte(sentence[sentence.IndexOf('$')+1]);
  // Loop through all chars to get a checksum
  for (int i=sentence.IndexOf('$')+2 ; i<sentence.IndexOf('*') ; i++)
  {
    // No. XOR the checksum with this character's value
    checksum^=Convert.ToByte(sentence[i]);              
  }
  // Return the checksum formatted as a two-character hexadecimal
  return checksum.ToString("X2");
}

And pass in your string, with $ a the start and * at the end (before the checksum), and commas between words, it works.

string s1 = getChecksum("$GPGGA,102957.92,4104.8569,N,00836.4700,W,1,4,15.100,157.133,M,52.386,M,0,0*79");
string s2 = getChecksum("$GPRMC,102957.92,A,4104.8569,N,00836.4700,W,0.000,5.822,230211,0,W,A*2B");

s1 = 79 and s2 = 2B as you would hope.


Isn't the problem that you are discarding all the ',' characters when you calculate the checksum. They should be included as far as I can see. So calculate the checksum on the original string which you have not removed the commas from and it might work better...


For many cases making sure the checksum matches is just a waste of time. It's really only (marginally) useful when the source and sink of the NMEA sentences are separated by a serial cable which may be noisy. If the source and sink are within the same device, communicating via shared memory, the checksum will always be correct.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜