In the loop () if not enabled the makeGNRMC () the checksum for $ACHDT sentence is correct = 22
But if enabled the makeGNRMC() function the checksum for $ACHDT becomes wrong = 4E
In all cases the checksum for $GNRMC still correct = 1A.
Changing the order of the functions does not change the error....
Could our friends give me a help about what is happening ?
//============================================================
const byte buff_len = 100; // aqui é do CRC calculador
char CRCbuffer[buff_len];
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
}
It does do it right the very first time, but then it repeats the '4E' checksum afterward.
Post Edit --
(Single-letter Variables are easy to type but hard to talk about or to revise later.)
It is because of the variable i
in
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");
}
Serial.print("\r\ni = ");
Serial.println(i);
return crc;
// based on code by Elimeléc López - July-19th-2013
}
When the final value of i is printed out you can see it's corrupted after the first pass.
const byte buff_len = 100; // aqui é do CRC calculador
char CRCbuffer[buff_len];
String cr = "";
String msg = "";
String HEADING;
String XX = "";
//================================
void setup() {
Serial.begin(19200);
}
//================================
void loop() {
//makeGNRMC(); // se descomentar atlatera o CRC da seguinte string ACHDT mesmmo se ela for executada antes
makeACHDT();
makeGNRMC();
delay (2000);
} // 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= XX; //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 < strlen(CRCbuffer); 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");
}
//Serial.print("\r\ni = ");
//Serial.println(i);
return crc;
// based on code by Elimeléc López - July-19th-2013
}
//=====================================
void makeGNRMC() {
msg = XX;
cr = XX;
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 = XX;
cr = XX;
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 (",T*");
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
}
Very good !!! Thanks a lot. You have solved the problem. Then the new code becomes :
//============================================================
const byte buff_len = 100; // aqui é do CRC calculador
char CRCbuffer[buff_len];
String cr = "";
String msg = "";
String HEADING;
//================================
void setup() {
Serial.begin(115200);
}
//================================
void loop() {
makeGNRMC();
makeACHDT();
delay (200);
} // 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 < strlen(CRCbuffer); 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
// with the BUG solved by WILDBILL changed buff_len to strlen(CRCbuffer)
}
//=====================================
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 função que calcula e acrescenta a CRC a string
msg.concat(cr); // acrescenta o CRC calculado
Serial.println (msg); // imprime a string completa
}