No código abaixo para calcular o checksum (CRC) de uma string tipo NMEA0183 está ocorrendo algo estranho:
No loop() se executar somente makeACHDT() funciona correto com o checksum sendo 22 resposta = ($ACHDT,75.55,T*22)
Se descomentar o makeGNRMC() passa a dar o CRC errado na sentença $ACHDT..... ficando 4E (errado).
Sendo que o checksum da sentença $GNRMC sempre fica correto que seria o valor 1A em qualquer situação.
Alterando a ordem das funções no loop também não altera
Alguém poderia testar ?
//============================================================
const byte buff_len = 100; // aqui é do CRC calculador
char CRCbuffer[buff_len];
// create pre-defined strings to control flexible output formatting
//String sp = "";
String cr = "";
String msg = "";
String HEADING;
void setup() {
Serial.begin(115200);
}
//================================
void loop() {
//makeGNRMC(); // se descomentar atlatera o CRC da seguinte string ACHDT mesmmo se ela for executada antes
makeACHDT();
delay (500);
} // fim do loop
//===============================
void outputMsg(String msg) {
msg.toCharArray(CRCbuffer, sizeof(CRCbuffer)); // put complete string into CRCbuffer
byte crc = convertToCRC(CRCbuffer); // call function to compute the crc value
cr= ""; //zera a substring
if (crc < 16) cr="0"; //acrescenta o zero se menor que 16
cr = cr + String(crc, HEX); // acrescenta o crc
cr.toUpperCase(); // converte a string cr para maiusculas
}
//=============================
byte convertToCRC(char *buff) {
// NMEA CRC: XOR each byte with previous for all chars between '$' and '*'
char c = 0 ;
byte i = 0 ;
byte start_with = 0; // index of starting char in msg
byte end_with = 0; // index of starting char in msg
byte crc = 0;
for (i = 0; i < buff_len; i++) {
c = buff[i];
if (c == '$') {start_with = i; }
if (c == '*') {end_with = i; }
}
if (end_with > start_with) {
for (i = start_with + 1; i < end_with; i++) { // XOR every character between '$' and '*'
crc = crc ^ buff[i] ; // xor the next char
}
}
else { // else if error, print a msg
Serial.println("CRC ERROR");
}
return crc;
// based on code by Elimeléc López - July-19th-2013
}
//=====================================
void makeGNRMC() {
msg ="";
cr ="";
msg = "$GNRMC,153815.000,A,2259.11572,S,04312.66106,W,201009,000.0,E,A*";
// resultado da string acima é 1A
outputMsg(msg); // envia a msg e chama função que calcula e acrescenta a CRC a string
msg.concat(cr); // acrescenta o CRC calculado
Serial.println (msg); // imprime a string completa
}
//====================================
//======================================
void makeACHDT(){
msg ="";
cr= "";
HEADING = "75.55";
// o resultado da string com o valor acima é 22 = $ACHDT,75.55,T*22
msg = "$ACHDT";
msg.concat (",");
msg.concat (HEADING);
msg.concat (",");
msg.concat ("T");
msg.concat ("*");
outputMsg(msg); // envia a msg e chama funcção que calcula e acrescenta a CRC a string
msg.concat(cr); // acrescenta o CRC calculado
Serial.println (msg); // imprime a string completa
}