C# .net cf 中的 nmea 校验和
我正在尝试编写自己的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您从链接的页面中使用此函数:
并传入字符串,以 $ a 开头,以 * 结尾(在校验和之前),并在单词之间使用逗号,则它可以工作。
如您所愿,s1 = 79 且 s2 = 2B。
If you use this function from the page you linked:
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.
问题不是在计算校验和时丢弃所有
','
字符吗?据我所知,它们应该包括在内。因此,计算未删除逗号的原始字符串的校验和,它可能会工作得更好......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...在许多情况下,确保校验和匹配只是浪费时间。当 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.