C# .net cf 中的 nmea 校验和

发布于 2024-10-18 17:51:51 字数 2940 浏览 7 评论 0原文

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

我正在使用 Codepedia - 计算和验证 nmea 句子

    // 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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

睫毛上残留的泪 2024-10-25 17:51:51

如果您从链接的页面中使用此函数:

private static string getChecksum(string sentence)
{
  //Start with first Item
  int checksum= Convert.ToByte(sentence[sentence.IndexOf('

并传入字符串,以 $ 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]); // Loop through all chars to get a checksum for (int i=sentence.IndexOf('

并传入字符串,以 $ a 开头,以 * 结尾(在校验和之前),并在单词之间使用逗号,则它可以工作。


如您所愿,s1 = 79 且 s2 = 2B。

)+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 开头,以 * 结尾(在校验和之前),并在单词之间使用逗号,则它可以工作。

如您所愿,s1 = 79 且 s2 = 2B。

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('

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.

)+1]); // Loop through all chars to get a checksum for (int i=sentence.IndexOf('

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


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

)+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.

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

最偏执的依靠 2024-10-25 17:51:51

问题不是在计算校验和时丢弃所有 ',' 字符吗?据我所知,它们应该包括在内。因此,计算未删除逗号的原始字符串的校验和,它可能会工作得更好......

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...

何止钟意 2024-10-25 17:51:51

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文