I faced a strange phenomenon while tried to run a gps parser. Briefly the hardwer: NEO-6M GPS module, Atmega328p, LCD1602. While the program is running, the LCD shows the time from the GPRMC message. But after some time, the uC starts reseting (in the init part of the code I have a greeting message on the LCD - this indicates me that the uC has rebooted). After some time it stucks in a reset loop.
There is no watchdog running, so I have no idea what can cause the reset. My first guess was the amount of ram is too less for processing the GPS sentences. I tried using the freeRam() function I found on Jeelabs, but there there was no meaningful data displayed (and the compiler warn me that an adress is used as a value...).
Do you have any idea what can cause the reset-loop, and how can I debug it? (I'm using USB-asp programmer, no debugger, and atmel studio). I include some parts of the code:
NMEA_parse.c:
#include "NMEA_parse.h" struct gprmc gprmc_datas; static void fill_data (char* param_in) { uint8_t i = 0U; char* trunk; char trunk_datas[20U][10U]; trunk = strtok(param_in, ","); while(trunk != NULL) { i++; if(i > 20) { i = 0; } strcpy(trunk_datas[i],trunk); trunk = strtok (NULL, ","); } if(memcmp(trunk_datas[1U],"GPRMC",6U) == 0U) { strcpy(gprmc_datas.time,trunk_datas[TIME]); strcpy(gprmc_datas.latitude,trunk_datas[LAT]); strcpy(gprmc_datas.longitude,trunk_datas[LON]); strcpy(gprmc_datas.date,trunk_datas[DATE]); strcpy(gprmc_datas.time,trunk_datas[TIME]); } } PARSE_RESULT proc_sentence (char* data_in) { char buffer[100U]; char cs_got[3U]; uint8_t u8cs_counted = 0U; uint8_t cc_flag = FALSE; uint8_t i = 0U, j = 0U; if(strlen(data_in) < 100U){ for(i = 0U; i < strlen(data_in); i++){ if(i == 0){ if(data_in[0U] != '$') { return D_ERROR; } else { ; } } else{ if(cc_flag == TRUE){ if(data_in[i] == 0x0DU) {} else{ if(j > 3){ return CL_ERROR; } else if(j == 2) { cs_got[j] = '\0'; } else { cs_got[j] = data_in[i]; j++; } } } else{ if( (data_in[i] == '$') || (data_in[i] == 0x0A) || (data_in[i] == 0x0D) || (data_in[i] == '\0')) { return S_ERROR; } else if(data_in[i] != '*'){ buffer[i - 1U] = data_in[i]; u8cs_counted ^= data_in[i]; } else { cc_flag = TRUE; buffer[i -1U] = '\0';} } } } if(strtol(cs_got,NULL,16U) == u8cs_counted){ fill_data(buffer); return OK; } else { return C_ERROR; } } else { return L_ERROR; } }
main.c:
/* * gps_logger.c * * Created: 2016. 11. 13. 21:33:16 * Author: Barta Tamás */ #include <avr/io.h> #include "config_avr.h" #include "NMEA_parse.h" #include "UART.h" #include "lcd1602_i2c.h" volatile uint8_t data[100U]; volatile uint8_t counter = 0U, sentence_end_flag = FALSE; volatile uint8_t begin_flag = 0U, end_flag = 0U, begin_temp = 0U; ISR(USART_RX_vect) { if(counter >= 100U) { counter = 0U; } data[counter] = UART_Receive(); if(data[counter] == '$') { begin_temp = counter; } else if(data[counter] == 0x0AU) { end_flag = counter; begin_flag = begin_temp; sentence_end_flag = TRUE; } counter++; } int main(void) { uint8_t i, j, k; uint8_t status = D_ERROR; char sentence[100U]; DDRB |= (1 << PB5); LcdInit(NOCURSOR, NOBLINK); LcdStringSend(0, 0, "Welcome"); _delay_ms(1000); LcdClear(); UART_Init(9600U); sei(); while(1U) { if(sentence_end_flag == TRUE) { cli(); if(begin_flag < end_flag) { for(i = begin_flag; i <= end_flag; i++) { if(i >= 100) { i = 0; } sentence[i - begin_flag] = data[i]; } sentence[i - begin_flag] = '\0'; } else { k = begin_flag; j = 0; for(i = begin_flag; i <= (end_flag + 100); i++) { if(k == 100) { k = 0; } if(j >= 100) { j = 0; } sentence[j] = data[k]; j++; k++; } sentence[j] = '\0'; } status = proc_sentence(sentence); strcpy(sentence,""); sentence_end_flag = FALSE; sei(); } if(status == OK) { LcdClear(); LcdWriteString(0, 0, gprmc_datas.time); status = D_ERROR; } } }