c#.net cf中的nmea校验和

时间:2011-02-23 10:42:44

标签: c# nmea

我正在尝试编写自己的nmea解析器,因为我只需要gps中的一些信息,而不需要解释所有消息。我遇到的问题是我的nmea消息验证器给了我一个错误的校验和。有人能看出我错了吗?

我正在使用 Codepedia - Calculating and Validating nmea sentences中的想法。

    // Returns True if a sentence's checksum matches the 
    // 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);
    }

运行日志

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

4 个答案:

答案 0 :(得分:4)

如果您从链接的页面使用此功能:

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");
}

并传入你的字符串,其中$ a为开头,*为结尾(校验和之前),单词之间为逗号,有效。

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和s2 = 2B。

答案 1 :(得分:2)

在计算校验和时,不是丢弃所有','个字符的问题。就我所见,它们应该被包括在内。因此,计算你没有删除逗号的原始字符串的校验和,它可能会更好...

答案 2 :(得分:0)

这是一个一步计算校验和的例子(单句解析句子)。 https://code.google.com/p/avr-nmea-gps-library/ 你可能不会比这更快。

答案 3 :(得分:0)

对于许多情况,确保校验和匹配只是浪费时间。当NMEA句子的源和宿被串行电缆分开时,它实际上只是(边缘)有用,这可能是嘈杂的。如果源和接收器在同一设备中,通过共享存储器进行通信,则校验和将始终是正确的。