My buffer data is lost once it leaves GPS() and enters back into while()

Thread Starter

chillcat

Joined Jan 23, 2018
15
Ok I'm using gps to retrieve data, storing the latitude data into special buffer "str1[15]", it displays fine inside the GPS(), but retrieving it outside the GPS() i get 15 black boxes on my lcd, guessing that means empty spots so where did the data go and how can I correct this issue? Reason being I am going to send the str1 value by SMS() once it leaves the GPS() mode. This is debugging mode because my SMS not giving me the str1 data. First things first how can I display str1 data from inside the while(). For simplicity I removed the unnec portions of code (LCD info, Rx/Tx) thanks!!!
Code:
char str1[15];             // LATITUDE data to be saved for displaying on LCD (gps()) and through SMS()

unsigned char ch, i;
char gpstime[7];
char gpsdate[7];
char buffer[7];
char gps_header[]="GPRMC,";

int main(){
    ADCON1 = 0b00001111;        // sets A to digital only
    OSCCON = 0x76;              // Sets internal oscillator to 8MHz
    TRISA = 0b00111100;         // LED A0 (r),A1 (g)
    TRISB = 0b11111111;         // Interrupts B0,B1
    TRISD = 0b01100000;         // LCD: E-D7,RS-D4, Data-3:0
    TRISC = 0b11111111;

    Delay_Ms(10);
    LCDinit(),  UART_Init(9600);
    LCDcmd(0x01);

    while(1){
        GPS_get();
         LCDcmd(0xD4);             // LINE 4
         LCDdata(str1[0]),LCDdata(str1[1]),LCDdata(str1[2]);
          LCDdata(str1[3]),LCDdata(str1[4]),LCDdata(str1[5]),LCDdata(str1[6]);
          LCDdata(str1[7]),LCDdata(str1[8]),LCDdata(str1[9]),LCDdata(str1[10]);
          LCDdata(str1[11]),LCDdata(str1[12]),LCDdata(str1[13]),LCDdata(str1[14]);
       
    Delay_Ms(1000);
    }
    return 0;
}

void GPS_get(void){
    ch = UART_Read();
        if (ch == '$'){
            for (i=0;i<6;i++){
                ch = UART_Read();               // read one char at a time (6 characters total)
                buffer[i] = ch;}
            if (strcmp(buffer, gps_header)==0){
                for (i=0;i<6;i++){          // These simply go through and store parts of string data into                         // separate buffers                   
            ch = UART_Read();}
                for (i=0;i<7;i++){ 
            ch = UART_Read();}
                for (i=0;i<9;i++){ 
            ch = UART_Read();
            str1[i] = ch;}        // SAVE THIS LONGITUDE data into str1 to recall later
                for (i=0;i<3;i++){ 
            ch = UART_Read();}
                for (i=0;i<11;i++){
            ch = UART_Read();
                for (i=0;i<14;i++){
            ch = UART_Read();}
                for (i=0;i<6;i++){ 
            ch = UART_Read();}
                for (i=0;i<10;i++){
            ch = UART_Read()}

            LCDcmd(0x80),LCDstring("LAT: ");                   // Displays latitude data on LCD just fine LAT: xxxx.xxxx
            if (str1[0] == ','){notvalidlat();}
            LCDstring(""),LCDdata(str1[0]),LCDdata(str1[1]),LCDdata(str1[2]);
            LCDdata(str1[3]),LCDdata(str1[4]),LCDdata(str1[5]),LCDdata(str1[6]);
            LCDdata(str1[7]),LCDdata(str1[8]);
            }
        }
    }
 

MrSoftware

Joined Oct 29, 2013
2,273
I only have a sec so I skimmed very quickly.. Open the memory watch in your debugger and enter the address for str1[0]. Watch the memory for the array as you step through and see where it changes. If the memory contents don't change as you expect, then double check that the address for str1[0] is the same both where you have good data and where you have bad data (make sure str1 isn't accidentally declared more than once somewhere else).
 

Picbuster

Joined Dec 2, 2013
1,057
You might into a timing problem with waits and reading chars one by one.
I did a lot for GPS reading and transferring it via gsm/mail and ftp.
My mechanism is simple:

Use interrupt and read one string(buffer) starting with the attention($GPMRC) and end with Cr/Lf or what ever is used.
After received one block disable interrupt. ( no data goes into buffer anymore)
//end interrupt
// handle in main
the separator comma is normal used.
Scan for comma and lift the data in between.( this will produce a number of fields)
$GPRMC,104831.000,A,5213.2921,N,00440.1235,E,0.00,,200515,,,A*74
pick the fields you want and put them into a variables you want.

place on display or/and output buffer.
when done
reset buffer pointer.
release receive interrupt.

Advantage: your main will never hang on a failing receive.

Picbuster
 

Ian Rogers

Joined Dec 12, 2012
1,136
Do yourself a tiny favour.... Just check if it prints to line 2 or 3...

I had a screen not so long ago that line 4 DIDN'T start at 0xD4 OR!! you haven't enabled 2 lines in the LCDInit!!
 

Thread Starter

chillcat

Joined Jan 23, 2018
15
the initializing is fine, line 4 works on cmd(0xd4). Here is what I wrote. I went ahead and put the gps GET into an interrupt and it works just as well. My data shows up on LCD, so I enable int at start of while() and disable it after 1 sec (only enough time to gather data. It works as far as the data showing up on lcd and the clock is ticking by the sec. Problem is very minor, I am not storing the LAT and LON data properly. I know it's an extremely simple thing I'm missing. PLEASE SEE convert_lat_to_degrees AND convert_lon_to_degrees and you'll see that after I do the equations I set a LAT = finished lat data (as shown on LCD) and the LON = finished lon data (also on LCD). Please let me know what I'm doing wrong. Gotta be something stupid easy, perhaps because it's a floating decimal or something. I went ahead and set line 4 as a debug viewer, I'm trying to view LAT information and all I see is a squiggly symbol followed by parallel lines

Code:
#define _XTAL_FREQ 8000000
#define GGA_Buffer_Size 80
#define GGA_Pointers_Size 20[/I][/I][/I]

[I][I][I]#pragma config BOREN=ON,CPD=OFF,OSC=INTIO7,WDT=OFF[/I][/I][/I]

[I][I][I]void Delay_Ms(unsigned int delay);
void convert_time_to_UTC(unsigned long int);
float convert_lon_to_degrees(float raw);
float convert_lat_to_degrees(float raw);
void convert_time_to_UTC(unsigned long int UTC_Time);
float get_longitude(unsigned char long_pointer);
float get_latitude(char lat_pointer);
unsigned long int get_gpstime();
void UART_Data(char data);
void UART_String(char *text);
#define GGA_Buffer_Size 80
#define GGA_Pointers_Size 20
char LAT[9],LON[10];                       // STORE CONVERTED LAT and LON values here (located in convert(). )
unsigned char i;
char GGA_Buffer[GGA_Buffer_Size];              /* to store GGA string */
char GGA_CODE[3];
unsigned char GGA_Pointers[GGA_Pointers_Size]; /* to store instances of ',' */
char CommaCounter;
char Data_Buffer[15];
volatile unsigned int GGA_Index;
volatile unsigned char    IsItGGAString    = 0;[/I][/I][/I]

[I][I][I]int main(){
    char GPS_Buffer[15];
    unsigned long int Time;
    float Latitude,Longitude;
    Delay_Ms(10);
    LCDinit(),  UART_Init(9600);
    LCDcmd(0x01);
    Delay_Ms(2000);
    LCDcmd(0x01);
   
    while(1){
        INTCONbits.GIE=1;   // TURN ON INTERRUPT !
        INTCONbits.PEIE=1;
        PIE1bits.RCIE=1;

        Delay_Ms(1000);       // TIME TO GATHER DATA

        INTCONbits.GIE=0;  // TURN OFF INTERRUPT !
        INTCONbits.PEIE=0;
        PIE1bits.RCIE=0;
       
        memset(GPS_Buffer,0,15);
        LCDcmd(0x80),LCDstring("Clock: ");
        Time = get_gpstime();            /* Extract Time */
    convert_time_to_UTC(Time);       /* convert time to UTC */
    LCDstring(Data_Buffer);
    LCDstring("  ");

    LCDcmd(0xc0),LCDstring("LAT:  ");
    Latitude = get_latitude(GGA_Pointers[0]); /* Extract Latitude */
    Latitude = convert_lat_to_degrees(Latitude);  /* convert raw latitude in degree decimal*/

    sprintf(GPS_Buffer,"%.06f",Latitude);            /* convert float value to string */
    LCDstring(GPS_Buffer);                            /* display latitude in degree */
    memset(GPS_Buffer,0,15);

    LCDcmd(0x94),LCDstring("LON: ");
    Longitude = get_longitude(GGA_Pointers[2]);/* Extract Latitude */
    Longitude = convert_lon_to_degrees(Longitude);/* convert raw longitude in degree decimal*/

    sprintf(GPS_Buffer,"%.06f",Longitude);        /* convert float value to string */
    LCDstring(GPS_Buffer);                            /* display latitude in degree */
    memset(GPS_Buffer,0,15);

        LCDcmd(0xd4),LCDdata(LAT[0]),LCDdata(LAT[1]);[/I][/I][/I]

[I][I][I]        Delay_Ms(5000);
    }
}
void interrupt Serial_ISR(){
    if(RCIF){
        GIE  = 0;                            /* Disable global interrupt */
        unsigned char received_char = RCREG;
    if(RCSTAbits.OERR){                 /* check if any overrun occur due to continuous reception */                     CREN = 0;
        if (OERR){CREN=0,CREN=1;}
        CREN=1;}
            if(received_char =='$'){                  /* check for '$' */
                GGA_Index = 0;
                IsItGGAString = 0;
                CommaCounter = 0;}
            else if(IsItGGAString == 1){            /* if true save GGA info. into buffer */
                if(received_char == ',' ) GGA_Pointers[CommaCounter++] = GGA_Index;    /* store instances of ',' in buffer */
                GGA_Buffer[GGA_Index++] = received_char;}
            else if(GGA_CODE[0] == 'G' && GGA_CODE[1] == 'G' && GGA_CODE[2] == 'A'){
                IsItGGAString = 1;
                GGA_CODE[0] = 0; GGA_CODE[1] = 0; GGA_CODE[2] = 0;}
            else{
                GGA_CODE[0] = GGA_CODE[1];  GGA_CODE[1] = GGA_CODE[2]; GGA_CODE[2] = received_char;}}}

unsigned long int get_gpstime(){
    unsigned char index;
    unsigned char Time_Buffer[15];
    unsigned long int _Time;
    for(index = 0;GGA_Buffer[index]!=','; index++){
        Time_Buffer[index] = GGA_Buffer[index];}
    _Time= atol(Time_Buffer);        /* convert string of Time to integer */
    return _Time;}                    /* return integer raw value of Time */[/I][/I][/I]

[I][I][I]float get_latitude(char lat_pointer){
    unsigned char lat_index = lat_pointer+1;    /* index pointing to the latitude */
    unsigned char index = 0;
    char Lat_Buffer[15];
    float _latitude;
    for(;GGA_Buffer[lat_index]!=',';lat_index++){
        Lat_Buffer[index]= GGA_Buffer[lat_index];
        index++;}
    _latitude = atof(Lat_Buffer);     /* convert string of latitude to float */
    return _latitude;}                 /* return float raw value of Latitude */

float get_longitude(unsigned char long_pointer){
    unsigned char long_index;
    unsigned char index = long_pointer+1;        /* index pointing to the longitude */
    char Long_Buffer[15];
    float _longitude;
    long_index=0;
    for( ; GGA_Buffer[index]!=','; index++){
        Long_Buffer[long_index]= GGA_Buffer[index];
        long_index++;}
    _longitude = atof(Long_Buffer);    /* convert string of longitude to float */
    return _longitude;}                 /* return float raw value of Longitude */

void convert_time_to_UTC(unsigned long int UTC_Time){
    unsigned int hour, min, sec;
    hour = (UTC_Time / 10000);                  /* extract hour from integer */
    min = (UTC_Time % 10000) / 100;             /* extract minute from integer */
    sec = (UTC_Time % 10000) % 100;             /* extract second from integer*/
    sprintf(Data_Buffer, "%d:%d:%d", hour,min,sec);} /* store UTC time in buffer */

float convert_lat_to_degrees(float raw){
    double value;
    float decimal_value,temp;
    long int degrees;
    float position;
    value = raw;
    decimal_value = (value/100);
    degrees = (int)(decimal_value);
    temp = (decimal_value - (int)decimal_value)/0.6;
    position = (float)degrees + temp;
    LAT[i] = position;
    return position;}    /* return float value in degrees */
float convert_lon_to_degrees(float raw){
    double value;
    float decimal_value,temp;
    long int degrees;
    float position;
    value = raw;
    decimal_value = -1*(value/100);
    degrees = (int)(decimal_value);
    temp = (decimal_value - (int)decimal_value)/0.6;
    position = (float)degrees + temp;
    LON[i] = position;
    return position;}    /* return float value in degrees */
 

Thread Starter

chillcat

Joined Jan 23, 2018
15
Using mplab with xc8 compiler. Works just fine, just gotta figure out how to store the LAT and LON values in their own buffers so that I may send those 2 values via SMS, which my sms does work also. It's just simple code writing that I am not doing correctly, the LAT and LON values will be in the following format xx.xxxxxx
 

Thread Starter

chillcat

Joined Jan 23, 2018
15
CORRECTION, the program compiles just fine and I've never any issue writing code that way. The problem is the data is not storing in buffers correctly.
 
Top