我搞砸了在cstring char数组上为电报计算的简单XOR校验和。
奇怪的是:校验和的解码有效。这是一个Arduino应用程序从一个Arduino发送电报到另一个。
这是要发送的电报,包括*:
之后的正确校验和$ GPS,52.534015,3.9,13.496394,2.5,0.053,0,44.6,6.2 * 65
你看起来正确:它就像一条NEMEA信息。
所以这是校验和计算的代码
MessageStr.toCharArray(MessageBuffer, MessageStr.length()); //Arduino String Class
for (int x = 1; x < (sizeof(MessageBuffer)/sizeof(MessageBuffer[0])); x++)
{
if (MessageBuffer[x] == '*')
{
Serial.println();
break;
}
else
{
MesChecksum ^= MessageBuffer[x]; //XOR the Message data...
}
}
MessageStr += MesChecksum;
Serial.println(MessageStr);
它甚至计算大校验和。
102而不是62
103而不是67
我使用这个在线工具检查了校验和: NEMEA checksum calc
另一方面,我使用了类似的代码来解析NEMEA消息:
boolean TelegramCheckChecksum(char* Message, int MessageLength)
{
byte checksumReceived = 0, checksum = 0;
for (int x = 1; x < MessageLength; x++)
{
if (Message[x] == '*') //Checksum starts with '*'
{
checksumReceived = strtol(&Message[x + 1], NULL, 16); //Parsing received checksum... |strtol parsing string to integer
break; //Exit for and continue with next if
}
else
{
checksum ^= Message[x]; //XOR the received data...
}
}
if (checksum == checksumReceived)
{
return true;
}
else
{
return false;
}
}
我真的尝试了一切。甚至用手按位检查。没有任何成功。
答案 0 :(得分:0)
您的代码在计算校验和时看起来是正确的,但是在将数字添加到消息时,您不会将数字转换为十六进制。 请注意,十进制的102是十六进制的62。
要使用标准库将数字转换为十六进制字符串,您可以使用stringstream
std::stringstream stream;
stream << std::hex << MesChecksum;
std::string result( stream.str() );
使用Arduino String类,你可以做这样的事情(我想 - 我不能测试它):
MessageStr += String(MesCheckSum, HEX);