CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Parsing GPS, example CCS

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

Parsing GPS, example CCS
PostPosted: Sun Apr 07, 2019 9:00 pm     Reply with quote

Hi, I use this function, (example of CCS):
Code:
#use delay(internal = 64MHz)
#use rs232(UART2, baud=9600, errors, receive_buffer=300, stream=STREAM_GPS)


    char delimitador[]=": ,\r";                 // Token
    char dat_GPRMC[12][10];                     // Array GPRMC
    char string[128];         //! $GPGGA,045104.000,3014.1985,N,09749.2873,W,1,09,1.2,211.6,M,-22.5,M,,0000*62
                              //! $GPGGA,045104.000,3014.1985,N,09749.2873,W,1,09,1.2,211.6,M,-22.5,M,,0000*62
    char gprmc[] = "$GPRMC,";
    char gpgga[] = "$GPGGA,";
    char tokens[] = ",";
    char *fix, *num ;
    char *ptr,*lat, *latDir=0, *lon=0, *lonDir=0, *time=0;
    //*validity=0,*speed=0,*course=0,*date=0,*variation=0,*east=0,*checksum;
    int1 GPS_OK=0;
     //******* Conversion Grados a Decimal ************
     //          dd + mm.mmmm/60 for latitude
     //          ddd + mm.mmmm/60 for longitude
     //          0610.9689,N,07535.1974,W
     //          6+(10.9689/60)=6.182815N          Lat
     //          75+(35.1974/60)=75.5866233333W    Long
     char    NumLat[3];            // Array para Latitud   ##'\0'
     char    NumLong[4];           // Array para Longitud ###'\0'
     char *  ptrLat;               // Array para extraer flot Latitud
     char *  ptrLong;              // Array para extraer flot Longitud
     float32   Latitud,Longitud=0.0;     // Latitud yLongitud           
     int32 lat_ieee;                   // Values IEEE
     int32 log_ieee;                   // Values IEEE
     



void GPS_GPRMC(){
int i;
     fgets(string, STREAM_GPS);
      if (strstr(string, gprmc)){
      fprintf(debug,"\r\nString Capturado : %s",string);
      fprintf(debug,"\r\nParsing ...\r\n",);
     
                 ptr = zstring_strtok(string, tokens);             //                       
                 i=0;                                       //
                 while(ptr != NULL){                        //
                    if(*ptr != '\n'){                       //   
                        strcpy(&dat_GPRMC[i++][0],ptr);     // Va llenando array
                        } 
                        ptr = zstring_strtok(NULL,tokens);         //             
                    }
                   
                fprintf(debug,"Time Stamp     %s\r\n", &dat_GPRMC[0][0]);    //  1   220516     Time Stamp
                fprintf(debug,"validity       %s\r\n", &dat_GPRMC[1][0]);    //  2   A          validity - A-ok, V-invalid
                fprintf(debug,"Latitude       %s\r\n", &dat_GPRMC[2][0]);    //  3   5133.82    current Latitude
                fprintf(debug,"North/South    %s\r\n", &dat_GPRMC[3][0]);    //  4   N          North/South
                fprintf(debug,"Longitude      %s\r\n", &dat_GPRMC[4][0]);    //  5   00042.24   current Longitude
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[5][0]);    //  6   W          East/West
                fprintf(debug,"Speed in knots %s\r\n", &dat_GPRMC[6][0]);    //  7   173.8      Speed in knots
                fprintf(debug,"True course    %s\r\n", &dat_GPRMC[7][0]);    //  8   231.8      True course
                fprintf(debug,"Date Stamp     %s\r\n", &dat_GPRMC[8][0]);    //  9   130694     Date Stamp
                fprintf(debug,"Variation      %s\r\n", &dat_GPRMC[9][0]);    //  10  004.2      Variation
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[10][0]);   //  11  W          East/West
                fprintf(debug,"checksum       %s", &dat_GPRMC[11][0]);       //  12  A*70       checksum   

               if(dat_GPRMC[1][0] == 'A'){                             // Validacion si hay GPS
                    GPS_OK=1;
               }
               
                else{
                 GPS_OK=0;
                fprintf(debug,"\r\nSin señal GPS\r\n");  //! www.google.com/maps?q=Latitud,Longitud
               }
               
               
                    memcpy(NumLat,&dat_GPRMC[2][0],2);                 //  Lat  ##, Extrae Entero
                    memcpy(NumLong,&dat_GPRMC[4][0],3);                //  Long ###, Extrae Entero
                    NumLat[2]  = '\0';                                 //  Termina Array con un Null
                    NumLong[3] = '\0';                                 //  Termina Array con un Null
                    ptrLat = &dat_GPRMC[2][0] + 2;                     //  Extrae flotante
                    ptrLong = &dat_GPRMC[4][0] + 3;                    //  Extrae flotante
                    Latitud = atoi(NumLat) + (atof(ptrLat) / 60);      //  Latitud  = Entero + (flotante/60)
                    Longitud = atoi(NumLong) + (atof(ptrLong) / 60);   //  Longitud = Entero + (flotante/60)
                   
                    if(dat_GPRMC[3][0] == 'S') Latitud *= -1;          //  Si es S Latitud es Negativa
                    if(dat_GPRMC[5][0] == 'W') Longitud *= -1;         //  Si es W Longitud es Negativa
                   
                    lat_ieee = f_PICtoIEEE( Latitud);   
                    log_ieee = f_PICtoIEEE( Longitud);
                   
                    fprintf(debug,"www.google.com/maps?q=%01.4f,%01.4f\r\n\r\n",Latitud,Longitud);  //! www.google.com/maps?q=Latitud,Longitud
             
             
               
      }
     
       fprintf(debug,"NO capture  UART2\r\n\r\n");  //! www.google.com/maps?q=Latitud,Longitud
}

The function work fine while no receive gps, but when get GPS, let to into to this line
Code:
if (strstr(string, gprmc)){

and go to "no Capture", maybe are many data from GPS module?

output:

Here show that while is "V" (no gps) the function work.
Code:

String Capturado :
$GPRMC,235952.800,V,,,,,0.00,0.00,050180,,,N*43
Parsing ...
Time Stamp     235952.800V
validity       V
Latitude       ,
North/South    ,
Longitude      ,
East/West      ,
Speed in knots 0.00
True course    0.00
Date Stamp     050180
Variation      ,
East/West      ,
checksum       N*43
Sin señal GPS

www.google.com/maps?q=0.0000,0.0000

what is the problem?
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Apr 08, 2019 4:54 am     Reply with quote

If you're saying it doesn't work with a real GPS connected to the PIC, it could be hardware. What PIC, What GPS, What is the VDD for both?
The program you post doesn't have a PIC type as the first line,though at 64MHz ,has to be relatively new. Most GPS 'devices' have 3 volt VDD, GPS ' modules' might be 3,5 or both.
There is a HUGE problem if the PIC is running at 5 volts and the GPS unit at 3.
We need more information about the actual hardware.

Jay
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Apr 08, 2019 6:07 am     Reply with quote

Hi,

This is a major contributor to your problem:

Quote:
fgets(string, STREAM_GPS);


fgets is never going to work in this application. You need to use the serial interrupt, and a circular receive buffer to reliably receive GPS data. Search the forum, this has been covered many, many times!

John
_________________
John

If it's worth doing, it's worth doing in real hardware!
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Mon Apr 08, 2019 7:39 am     Reply with quote

receive_buffer option in the #use rs232 has already set up that circular buffer for you.

So what you need to do is use kbhit() to tell you if there are any contents in the circular buffer.

But since you are still debugging, why not just print string before your strstr so you know what you are receiving? That may help your debugging process.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Mon Apr 08, 2019 9:24 am     Reply with quote

dluu13 wrote:
receive_buffer option in the #use rs232 has already set up that circular buffer for you.

So what you need to do is use kbhit() to tell you if there are any contents in the circular buffer.

But since you are still debugging, why not just print string before your strstr so you know what you are receiving? That may help your debugging process.


GPS and PIC are to 3.3V


Yes I know its better interruption, but I wanted use this example of ccs.

#include <18F26k22.h>

The code work fine, while the gps is "V" If is "A" not capture again.... maybe is many data?





Full code
Code:
#include <18F26k22.h>
#device PASS_STRINGS = IN_RAM
#device adc=10
#FUSES INTRC_IO        // INTRC_IO Internal RC Osc, no CLKOUT
#FUSES NOFCMEN         //Fail-safe clock monitor disabled
#FUSES NOIESO          //Internal External Switch Over mode disabled
#FUSES NOPUT           //No Power Up Timer
#FUSES NOBROWNOUT      //No brownout reset
#FUSES NOWDT           //No Watch Dog Timer
#FUSES NOPBADEN        //PORTB pins are configured as digital I/O on RESET
#FUSES MCLR            //Master Clear pin NOT enabled
#FUSES NOLVP           //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST         //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODEBUG         //No Debug mode for ICD
#FUSES CCP2C1
#fuses PROTECT        //Code protected from reads

#use delay(internal =16MHz)
//#use rs232(UART2, baud=4800, errors, receive_buffer=128, stream=STREAM_GPS)
#use rs232(baud=4800, xmit=PIN_b6,rcv=PIN_b7,bits=8,parity=N,ERRORS,stream=STREAM_GPS)    // UART 2 GPS
#use rs232(baud=57600,xmit=PIN_c6,rcv=PIN_c7,bits=8,parity=N,ERRORS,stream=STREAM_LoRa)   // UART 1 LORA
#use rs232(baud=9600, xmit=PIN_c4,rcv=PIN_c3,bits=8,parity=N,ERRORS,stream=debug)         // UART 2 DEBUG


// ~~~~~~~~~~~~~~~~~~~~~~  Debug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define _debug
#define show_config_RN2903
// ~~~~~~~~~~~~~~~~~~~~~~  Debug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#use fast_io(A)
#use standard_io(B)
#use standard_io(c)


#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <ieeefloat.c>
#include <NMEAParser.c>        // NMEA

void main(){
 enable_interrupts(GLOBAL);
  enable_interrupts(int_rda);                    // Habilita Interrupción RDA UART1
  enable_interrupts(int_rda2);                   // Habilita Interrupción RDA UART2
  delay_ms(100);
      while(1){
      GPS_GPRMC_V2();
      //GPS_GPRMC();

      }
 }



Lib


Code:
// :::::::::::::::: Varibles GPS_L86 ::::::::::::::::::::::::::::::::::::::::::
    char delimitador[]=": ,\r";                 // Token
    char dat_GPRMC[12][10];                     // Array GPRMC
    char string[128];         //! $GPGGA,045104.000,3014.1985,N,09749.2873,W,1,09,1.2,211.6,M,-22.5,M,,0000*62
                              //! $GPGGA,045104.000,3014.1985,N,09749.2873,W,1,09,1.2,211.6,M,-22.5,M,,0000*62
    char gprmc[] = "$GPRMC,";
    char gpgga[] = "$GPGGA,";
    char tokens[] = ",";
    char *fix, *num ;
    char *ptr,*lat, *latDir=0, *lon=0, *lonDir=0, *time=0;
    //*validity=0,*speed=0,*course=0,*date=0,*variation=0,*east=0,*checksum;
    int1 GPS_OK=0;
     //******* Conversion Grados a Decimal ************
     //          dd + mm.mmmm/60 for latitude
     //          ddd + mm.mmmm/60 for longitude
     //          0610.9689,N,07535.1974,W
     //          6+(10.9689/60)=6.182815N          Lat
     //          75+(35.1974/60)=75.5866233333W    Long
     char    NumLat[3];            // Array para Latitud   ##'\0'
     char    NumLong[4];           // Array para Longitud ###'\0'
     char *  ptrLat;               // Array para extraer flot Latitud
     char *  ptrLong;              // Array para extraer flot Longitud
     float32   Latitud,Longitud=0.0;     // Latitud yLongitud           
     int32 lat_ieee;                   // Values IEEE
     int32 log_ieee;                   // Values IEEE
     
     
     
     
     
#DEFINE SIZE_BUFFER_UART2   200      // Serial Buffer Size
#DEFINE SIZE_BUFFER_GPRMC   100      // Serial Buffer Size

enum letras{
        PRIMER_LETRA,    // $
        LETRA_G,         // G
        LETRA_P,         // P
        LETRA_R,         // R
        LETRA_M,         // M
        LETRA_C,         // C
        RESTANTE         // .....
};
enum letras estado;

int  counter_read2 = 0x00;                                  // Serial Buffer Counter
char c=0x00;
char Receive_String_uart2[SIZE_BUFFER_UART2];               // Serial Buffer
//!



char *zstring_strtok(char *str,  char *delim);
/***************************************************************/
//  FUNCIONES
/***************************************************************/
void GPS_GPRMC();
void GPS_GPRMC_V2();
void GPS_GPGGA();

//!****************************************************************************
//!******************** GPS  With UART2 ***************************************
//!****************************************************************************
#INT_RDA2
void RDA_isr2() {
      switch(estado){
             case PRIMER_LETRA:  if(getchar(STREAM_GPS)=='$') estado = LETRA_G; break;                   
             case LETRA_G:       if(getchar(STREAM_GPS)=='G') estado = LETRA_P; break;                 
             case LETRA_P:       if(getchar(STREAM_GPS)=='P') estado = LETRA_R; break;
             case LETRA_R:       if(getchar(STREAM_GPS)=='R') estado = LETRA_M; break;
             case LETRA_M:       if(getchar(STREAM_GPS)=='M') estado = LETRA_C; break;
             case LETRA_C:       if(getchar(STREAM_GPS)=='C') estado = RESTANTE; counter_read2 = 0x00; break;
             case RESTANTE:
                           c = getchar(STREAM_GPS);
                           if(c == '$'){                        // Proximo "$"
                                //disable_interrupts(INT_RDA2);
                                strcpy(string,Receive_String_uart2);
                                estado = LETRA_G;
                               break;
                             }
                           
                           if(counter_read2==SIZE_BUFFER_UART2) counter_read2=0x00;
                           Receive_String_uart2[counter_read2++]=c;
                           break;
            default:         
                           estado = PRIMER_LETRA; break;
      }
}   
// :::::::::::::::: GPRM ::::::::::::::::::::::::::::::::::::::::::::::::::::::
void GPS_GPRMC(){
int i;
     fgets(string, STREAM_GPS);
      if (strstr(string, gprmc)){
      fprintf(debug,"\r\nString Capturado : %s",string);
      fprintf(debug,"\r\nParsing ...\r\n",);
     
                 ptr = zstring_strtok(string, tokens);             //                       
                 i=0;                                       //
                 while(ptr != NULL){                        //
                    if(*ptr != '\n'){                       //   
                        strcpy(&dat_GPRMC[i++][0],ptr);     // Va llenando array
                        } 
                        ptr = zstring_strtok(NULL,tokens);         //             
                    }
                   
                fprintf(debug,"Time Stamp     %s\r\n", &dat_GPRMC[0][0]);    //  1   220516     Time Stamp
                fprintf(debug,"validity       %s\r\n", &dat_GPRMC[1][0]);    //  2   A          validity - A-ok, V-invalid
                fprintf(debug,"Latitude       %s\r\n", &dat_GPRMC[2][0]);    //  3   5133.82    current Latitude
                fprintf(debug,"North/South    %s\r\n", &dat_GPRMC[3][0]);    //  4   N          North/South
                fprintf(debug,"Longitude      %s\r\n", &dat_GPRMC[4][0]);    //  5   00042.24   current Longitude
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[5][0]);    //  6   W          East/West
                fprintf(debug,"Speed in knots %s\r\n", &dat_GPRMC[6][0]);    //  7   173.8      Speed in knots
                fprintf(debug,"True course    %s\r\n", &dat_GPRMC[7][0]);    //  8   231.8      True course
                fprintf(debug,"Date Stamp     %s\r\n", &dat_GPRMC[8][0]);    //  9   130694     Date Stamp
                fprintf(debug,"Variation      %s\r\n", &dat_GPRMC[9][0]);    //  10  004.2      Variation
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[10][0]);   //  11  W          East/West
                fprintf(debug,"checksum       %s", &dat_GPRMC[11][0]);       //  12  A*70       checksum   

               if(dat_GPRMC[1][0] == 'A'){                             // Validacion si hay GPS
                    GPS_OK=1;
               }
               
                else{
                 GPS_OK=0;
                fprintf(debug,"\r\nSin señal GPS\r\n");  //! www.google.com/maps?q=Latitud,Longitud
               }
               
               
                    memcpy(NumLat,&dat_GPRMC[2][0],2);                 //  Lat  ##, Extrae Entero
                    memcpy(NumLong,&dat_GPRMC[4][0],3);                //  Long ###, Extrae Entero
                    NumLat[2]  = '\0';                                 //  Termina Array con un Null
                    NumLong[3] = '\0';                                 //  Termina Array con un Null
                    ptrLat = &dat_GPRMC[2][0] + 2;                     //  Extrae flotante
                    ptrLong = &dat_GPRMC[4][0] + 3;                    //  Extrae flotante
                    Latitud = atoi(NumLat) + (atof(ptrLat) / 60);      //  Latitud  = Entero + (flotante/60)
                    Longitud = atoi(NumLong) + (atof(ptrLong) / 60);   //  Longitud = Entero + (flotante/60)
                   
                    if(dat_GPRMC[3][0] == 'S') Latitud *= -1;          //  Si es S Latitud es Negativa
                    if(dat_GPRMC[5][0] == 'W') Longitud *= -1;         //  Si es W Longitud es Negativa
                   
                    lat_ieee = f_PICtoIEEE( Latitud);   
                    log_ieee = f_PICtoIEEE( Longitud);
                   
                    fprintf(debug,"www.google.com/maps?q=%01.4f,%01.4f\r\n\r\n",Latitud,Longitud);  //! www.google.com/maps?q=Latitud,Longitud
             
             
               
      }
     
       fprintf(debug,"NO se puede leer UART2\r\n\r\n");  //! www.google.com/maps?q=Latitud,Longitud
}

void GPS_GPGGA(){
   int i;
      fgets(string, STREAM_GPS);
      if (strstr(string, gpgga) != 0){
         ptr = strtok(string, tokens);
         i = 0;
         while(ptr != NULL){
            switch(i++){
               case 1:  time = ptr;      break;
               case 2:  lat = ptr;       break;
               case 3:  latDir =ptr;     break;
               case 4:  lon = ptr;       break;
               case 5:  lonDir = ptr;    break;
               case 6:  fix = ptr;       break;
               case 7:  num = ptr;       break;
               default: break;
            }           
            ptr = strtok(NULL, tokens);
         }
         
         fprintf(debug, "Trama capturada >>  fix=%s, num=%s, time=%s, lat=%s %s, lon=%s %s\r\n",
               fix,
               num,
               time,
               lat,
               latDir,
               lon,
               lonDir
            );
      }
}

void GPS_GPRMC_V2(){
     int i;
 //******* Extraer GPRM **************************     
     //strcpy(string,GPRMC_buff);               // +CBC: #,###,####
     ptr = strtok(string, delimitador);         //
     i=0;                                       //
     while(ptr != NULL){                        //
          if(*ptr != '\n'){                     //
            strcpy(&dat_GPRMC[i][0],ptr);       // Va llenando array
            i++;                                //
            }                                   //
            ptr = strtok(NULL,delimitador);     //
        }
       
       
       
       
      if(dat_GPRMC[1][0] == 'A'){               // Validacion si hay GPS
           GPS_OK=1;
           memcpy(NumLat,&dat_GPRMC[2][0],2);                 //  Lat  ##, Extrae Entero
           memcpy(NumLong,&dat_GPRMC[4][0],3);                //  Long ###, Extrae Entero
           NumLat[2]  = '\0';                                 //  Termina Array con un Null
           NumLong[3] = '\0';                                 //  Termina Array con un Null
           ptrLat = &dat_GPRMC[2][0] + 2;                     //  Extrae flotante
           ptrLong = &dat_GPRMC[4][0] + 3;                    //  Extrae flotante
           Latitud = atoi(NumLat) + (atof(ptrLat) / 60);      //  Latitud  = Entero + (flotante/60)
           Longitud = atoi(NumLong) + (atof(ptrLong) / 60);   //  Longitud = Entero + (flotante/60)
           
           if(dat_GPRMC[3][0] == 'S') Latitud *= -1;          //  Si es S Latitud es Negativa
           if(dat_GPRMC[5][0] == 'W') Longitud *= -1;         //  Si es W Longitud es Negativa
           
           lat_ieee = f_PICtoIEEE( Latitud);   
           log_ieee = f_PICtoIEEE( Longitud);
               
           fprintf(debug,"www.google.com/maps?q=%01.4f,%01.4f\r\n",Latitud,Longitud);  //! www.google.com/maps?q=Latitud,Longitud
      }
      else{
      GPS_OK=0;
        // Latitud=0.0;         Longitud=0.0;
        // fprintf(debug,"No hay señal GPS\r\n");
     
      }
       memset(string, NULL, sizeof(string));
    //  memset(string,NULL,SIZE_BUFFER_GPRMC);                 // Set all elements to NULL
     // memset(Receive_String_uart2,NULL,SIZE_BUFFER_UART2);        // Set all elements to NULL
     //counter_read2 = 0x00;                                       // Reinicia Contador
     // enable_interrupts(INT_RDA2);                                // Habilita recepcion GPS
     
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[0][0]);    //  1   220516     Time Stamp
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[1][0]);    //  2   A          validity - A-ok, V-invalid
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[2][0]);    //  3   5133.82    current Latitude
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[3][0]);    //  4   N          North/South
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[4][0]);    //  5   00042.24   current Longitude
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[5][0]);    //  6   W          East/West
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[6][0]);    //  7   173.8      Speed in knots
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[7][0]);    //  8   231.8      True course
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[8][0]);    //  9   130694     Date Stamp
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[9][0]);    //  10  004.2      Variation
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[10][0]);   //  11  W          East/West
//!    fprintf(debug,"%s\r\n", &dat_GPRMC[11][0]);   //  12  *70        checksum     
     
}




char *zstring_strtok(char *str,  char *delim) {
    static char *static_str=0;       /* var to store last address */
    int index=0, strlength=0;         /* integers for indexes */
    int found = 0;                 /* check if delim is found */

    /* delimiter cannot be NULL
    * if no more char left, return NULL as well
    */
    if (delim==0 || (str == 0 && static_str == 0))
        return 0;

    if (str == 0)
        str = static_str;

    /* get length of string */
    while(str[strlength])
        strlength++;

    /* find the first occurrence of delim */
    for (index=0;index<strlength;index++)
        if (str[index]==delim[0]) {
            found=1;
            break;
        }

    /* if delim is not contained in str, return str */
    if (!found) {
        static_str = 0;
        return str;
    }

    /* check for consecutive delimiters
    *if first char is delim, return delim
    */
    if (str[0]==delim[0]) {
        static_str = (str + 1);
        return (char *)delim;
    }

    /* terminate the string
    * this assignment requires char[], so str has to
    * be char[] rather than *char
    */
    str[index] = '\0';

    /* save the rest of the string */
    if ((str + index + 1)!=0)
        static_str = (str + index + 1);
    else
        static_str = 0;

        return str;
}
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Apr 08, 2019 8:10 pm     Reply with quote

Hi,

I haven’t studied your code in detail, but you definitely don’t want to enable interrupts when you don’t have a corresponding handler, such as you are doing for int_rda.....

John
_________________
John

If it's worth doing, it's worth doing in real hardware!
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Mon Apr 08, 2019 8:16 pm     Reply with quote

ezflyr wrote:
Hi,

I haven’t studied your code in detail, but you definitely don’t want to enable interrupts when you don’t have a corresponding handler, such as you are doing for int_rda.....

John


As I understand, since op has specified receive buffer in use rs232, the compiler automatically generates an isr and enables the interrupt. So if anything, his own enable statement is redundant.

But, you are right that in other circumstances, enabling the interrupt without providing an isr will cause problems like random restarts.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Apr 08, 2019 8:20 pm     Reply with quote

Hi,

The OP has commented out the Use rs232 statement that defines the built in buffer. What he’s got now is the ‘classic’ method with an extra, extraneous interrupt enabled!
_________________
John

If it's worth doing, it's worth doing in real hardware!
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Mon Apr 08, 2019 8:28 pm     Reply with quote

Ah... I missed that. Now I see that op is using software uarts, which is more or less pretty terrible when it comes to receiving data, since you need to poll at ten times the baud rate to avoid missing incoming bits.

Another thing I noticed...
In the original code, you have the gps stream at 9600. In the next version you have it at 4800. Have you configured your gps with a slower baud rate now?
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Apr 09, 2019 8:15 am     Reply with quote

dluu13 wrote:
Ah... I missed that. Now I see that op is using software uarts, which is more or less pretty terrible when it comes to receiving data, since you need to poll at ten times the baud rate to avoid missing incoming bits.

Another thing I noticed...
In the original code, you have the gps stream at 9600. In the next version you have it at 4800. Have you configured your gps with a slower baud rate now?

Yes, the 9600 is not problem. but I don't know is the baud has be set in 4800.
The problem is that I used the modulo quectel l80 and the baud come to 9600


The code work very good, in Proteus work very fine and in real work 50%, when the gps get data no capture the string with head "GPRMC", I think is by many data and can not process the -"string search" faster.


I can do with interruption, but I liked many this example of CCS, I find easy for parsing.

when I want use the way with interruption I enable the interruption, else I comment that lines. not to same time.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Apr 09, 2019 1:17 pm     Reply with quote

cvargcal wrote:
dluu13 wrote:
Ah... I missed that. Now I see that op is using software uarts, which is more or less pretty terrible when it comes to receiving data, since you need to poll at ten times the baud rate to avoid missing incoming bits.

Another thing I noticed...
In the original code, you have the gps stream at 9600. In the next version you have it at 4800. Have you configured your gps with a slower baud rate now?

Yes, the 9600 is not problem. but I don't know is the baud has be set in 4800.
The problem is that I used the modulo quectel l80 and the baud come to 9600


The code work very good, in Proteus work very fine and in real work 50%, when the gps get data no capture the string with head "GPRMC", I think is by many data and can not process the -"string search" faster.


I can do with interruption, but I liked many this example of CCS, I find easy for parsing.

when I want use the way with interruption I enable the interruption, else I comment that lines. not to same time.






Thank you .


I fixed one error, Now my way to get GPRMC work find similart to CCS example, I dont know if example CCS work fine in real or if the GPS need set to 4800 for can get data slow.


Code:
// CCS Example
//#use rs232(UART2, baud=4800, errors, receive_buffer=128, stream=STREAM_GPS)


// myself
#use rs232(baud=9600, xmit=PIN_b6,rcv=PIN_b7,bits=8,parity=N,ERRORS,stream=STREAM_GPS)    // UART 2 GPS





With interruption control myself

Code:


// ****** With #INT_RDA2   ****   
#DEFINE SIZE_BUFFER_UART2   200      // Serial Buffer Size
int  counter_read2 = 0x00;                                  // Serial Buffer Counter
char Receive_String_uart2[SIZE_BUFFER_UART2];               // Serial Buffer
int gprmc_messageReady=0;
enum letras{
        PRIMER_LETRA,    // $
        LETRA_G,         // G
        LETRA_P,         // P
        LETRA_R,         // R
        LETRA_M,         // M
        LETRA_C,         // C
        RESTANTE         // .....
};
enum letras estado;
// ****************************




//!****************************************************************************
//!******************** GPS  With UART2 ***************************************
//!****************************************************************************
#INT_RDA2
void RDA_isr2() {
char c=0x00;
      switch(estado){
             case PRIMER_LETRA:  if(getchar(STREAM_GPS)=='$') estado = LETRA_G; break;                   
             case LETRA_G:       if(getchar(STREAM_GPS)=='G') estado = LETRA_P; break;                 
             case LETRA_P:       if(getchar(STREAM_GPS)=='P') estado = LETRA_R; break;
             case LETRA_R:       if(getchar(STREAM_GPS)=='R') estado = LETRA_M; break;
             case LETRA_M:       if(getchar(STREAM_GPS)=='M') estado = LETRA_C; break;
             case LETRA_C:       if(getchar(STREAM_GPS)=='C') estado = RESTANTE;
                                 counter_read2 = 0x00; break;
             case RESTANTE:
                           c = getchar(STREAM_GPS);
                           if(c == '$'){  // Proximo "$"
                               strcpy(string,Receive_String_uart2);
                               estado = LETRA_G;
                               gprmc_messageReady=1;
                               break;
                             }
                           
                           if(counter_read2==SIZE_BUFFER_UART2) counter_read2=0x00;
                           Receive_String_uart2[counter_read2++]=c;
                           break;
            default:   estado = PRIMER_LETRA; break;
      }
}



Code:
// :::::::::::::::: GPRM ::::::::::  BY CONTROL #INT_RDA2 :::::::::::::::::::::
void GPS_GPRMC_v2(){
    int i;
   if ((gprmc_messageReady) ){
      gprmc_messageReady=0;
      //0,1 ........................,12   
      // ,183504.373,V,,,,,,,090419,,,N*44
      // [0]= GPRMC......... [12]= CHKS
      fprintf(debug,"\r\nString Capturado : %s",string);
      fprintf(debug,"\r\nParsing ...\r\n",);
     
                 ptr = zstring_strtok(string, tokens);             //                       
                 i=0;                                       //
                 while(ptr != NULL){                        //
                    if(*ptr != '\n'){                       //   
                        strcpy(&dat_GPRMC[i++][0],ptr);     // Va llenando array
                        } 
                        ptr = zstring_strtok(NULL,tokens);         //             
                    }
                                 
                fprintf(debug,"Head (GPRMC)   %s\r\n", &dat_GPRMC[0][0]);    //  0   Head
                fprintf(debug,"Time Stamp     %s\r\n", &dat_GPRMC[1][0]);    //  1   220516     Time Stamp
                fprintf(debug,"validity       %s\r\n", &dat_GPRMC[2][0]);    //  2   A          validity - A-ok, V-invalid
                fprintf(debug,"Latitude       %s\r\n", &dat_GPRMC[3][0]);    //  3   5133.82    current Latitude
                fprintf(debug,"North/South    %s\r\n", &dat_GPRMC[4][0]);    //  4   N          North/South
                fprintf(debug,"Longitude      %s\r\n", &dat_GPRMC[5][0]);    //  5   00042.24   current Longitude
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[6][0]);    //  6   W          East/West
                fprintf(debug,"Speed in knots %s\r\n", &dat_GPRMC[7][0]);    //  7   173.8      Speed in knots
                fprintf(debug,"True course    %s\r\n", &dat_GPRMC[8][0]);    //  8   231.8      True course
                fprintf(debug,"Date Stamp     %s\r\n", &dat_GPRMC[9][0]);    //  9   130694     Date Stamp
                fprintf(debug,"Variation      %s\r\n", &dat_GPRMC[10][0]);    //  10  004.2      Variation
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[11][0]);   //  11  W          East/West
                fprintf(debug,"checksum       %s", &dat_GPRMC[12][0]);       //  12  A*70       checksum   

               if(dat_GPRMC[1][0] == 'A'){                                   // Validacion si hay GPS
                    GPS_OK=1;
                    memcpy(NumLat,&dat_GPRMC[2][0],2);                 //  Lat  ##, Extrae Entero
                    memcpy(NumLong,&dat_GPRMC[4][0],3);                //  Long ###, Extrae Entero
                    NumLat[2]  = '\0';                                 //  Termina Array con un Null
                    NumLong[3] = '\0';                                 //  Termina Array con un Null
                    ptrLat = &dat_GPRMC[2][0] + 2;                     //  Extrae flotante
                    ptrLong = &dat_GPRMC[4][0] + 3;                    //  Extrae flotante
                    Latitud = atoi(NumLat) + (atof(ptrLat) / 60);      //  Latitud  = Entero + (flotante/60)
                    Longitud = atoi(NumLong) + (atof(ptrLong) / 60);   //  Longitud = Entero + (flotante/60)
                   
                    if(dat_GPRMC[3][0] == 'S') Latitud *= -1;          //  Si es S Latitud es Negativa
                    if(dat_GPRMC[5][0] == 'W') Longitud *= -1;         //  Si es W Longitud es Negativa
                   
                    lat_ieee = f_PICtoIEEE( Latitud);   
                    log_ieee = f_PICtoIEEE( Longitud);
                   
                    fprintf(debug,"www.google.com/maps?q=%01.4f,%01.4f\r\n\r\n",Latitud,Longitud);  //! www.google.com/maps?q=Latitud,Longitud
                    memset(string, 0, sizeof(string));                     
                    memset(Receive_String_uart2, 0, sizeof(Receive_String_uart2)); 
                    counter_read2 = 0;                               
               }
    }   

// :::::::::::::::: GPRM ::::::::::  Similar to CCS Example :::::::::::::::::::
void GPS_GPRMC(){
int i;
      fgets(string, STREAM_GPS);         // To see the UART2 Configuration... for work
      if (strstr(string, gprmc)){
      fprintf(debug,"\r\nString Capturado : %s",string);
      fprintf(debug,"\r\nParsing ...\r\n",);
                 ptr = zstring_strtok(string, tokens);      //                       
                 i=0;                                       //
                 while(ptr != NULL){                        //
                    if(*ptr != '\n'){                       //   
                        strcpy(&dat_GPRMC[i++][0],ptr);     // Va llenando array
                        } 
                        ptr = zstring_strtok(NULL,tokens);         //             
                    }
                   
                fprintf(debug,"Time Stamp     %s\r\n", &dat_GPRMC[0][0]);    //  1   220516     Time Stamp
                fprintf(debug,"validity       %s\r\n", &dat_GPRMC[1][0]);    //  2   A          validity - A-ok, V-invalid
                fprintf(debug,"Latitude       %s\r\n", &dat_GPRMC[2][0]);    //  3   5133.82    current Latitude
                fprintf(debug,"North/South    %s\r\n", &dat_GPRMC[3][0]);    //  4   N          North/South
                fprintf(debug,"Longitude      %s\r\n", &dat_GPRMC[4][0]);    //  5   00042.24   current Longitude
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[5][0]);    //  6   W          East/West
                fprintf(debug,"Speed in knots %s\r\n", &dat_GPRMC[6][0]);    //  7   173.8      Speed in knots
                fprintf(debug,"True course    %s\r\n", &dat_GPRMC[7][0]);    //  8   231.8      True course
                fprintf(debug,"Date Stamp     %s\r\n", &dat_GPRMC[8][0]);    //  9   130694     Date Stamp
                fprintf(debug,"Variation      %s\r\n", &dat_GPRMC[9][0]);    //  10  004.2      Variation
                fprintf(debug,"East/West      %s\r\n", &dat_GPRMC[10][0]);   //  11  W          East/West
                fprintf(debug,"checksum       %s", &dat_GPRMC[11][0]);       //  12  A*70       checksum   

               if(dat_GPRMC[1][0] == 'A'){                                   // Validacion si hay GPS
                   GPS_OK=1;
   
                    memcpy(NumLat,&dat_GPRMC[2][0],2);                 //  Lat  ##, Extrae Entero
                    memcpy(NumLong,&dat_GPRMC[4][0],3);                //  Long ###, Extrae Entero
                    NumLat[2]  = '\0';                                 //  Termina Array con un Null
                    NumLong[3] = '\0';                                 //  Termina Array con un Null
                    ptrLat = &dat_GPRMC[2][0] + 2;                     //  Extrae flotante
                    ptrLong = &dat_GPRMC[4][0] + 3;                    //  Extrae flotante
                    Latitud = atoi(NumLat) + (atof(ptrLat) / 60);      //  Latitud  = Entero + (flotante/60)
                    Longitud = atoi(NumLong) + (atof(ptrLong) / 60);   //  Longitud = Entero + (flotante/60)
                   
                    if(dat_GPRMC[3][0] == 'S') Latitud *= -1;          //  Si es S Latitud es Negativa
                    if(dat_GPRMC[5][0] == 'W') Longitud *= -1;         //  Si es W Longitud es Negativa
                   
                    lat_ieee = f_PICtoIEEE( Latitud);   
                    log_ieee = f_PICtoIEEE( Longitud);
                   
                    fprintf(debug,"www.google.com/maps?q=%01.4f,%01.4f\r\n\r\n",Latitud,Longitud);  //! www.google.com/maps?q=Latitud,Longitud
               }
               else {
                GPS_OK=0;
                fprintf(debug,"\r\nSin señal GPS\r\n");  //! www.google.com/maps?q=Latitud,Longitud
               }
      }           
}   
// :::::::::::::::: GPGGA :::::::::: Similar to CCS Example :::::::::::::::::::
void GPS_GPGGA(){
}


                   
}


Code:
// :::::::::::::::: strtok with empty field ::::::::::
char *zstring_strtok(char *str,  char *delim) {
    static char *static_str=0;       /* var to store last address */
    int index=0, strlength=0;         /* integers for indexes */
    int found = 0;                 /* check if delim is found */

    /* delimiter cannot be NULL
    * if no more char left, return NULL as well
    */
    if (delim==0 || (str == 0 && static_str == 0))
        return 0;

    if (str == 0)
        str = static_str;

    /* get length of string */
    while(str[strlength])
        strlength++;

    /* find the first occurrence of delim */
    for (index=0;index<strlength;index++)
        if (str[index]==delim[0]) {
            found=1;
            break;
        }

    /* if delim is not contained in str, return str */
    if (!found) {
        static_str = 0;
        return str;
    }

    /* check for consecutive delimiters
    *if first char is delim, return delim
    */
    if (str[0]==delim[0]) {
        static_str = (str + 1);
        return (char *)delim;
    }

    /* terminate the string
    * this assignment requires char[], so str has to
    * be char[] rather than *char
    */
    str[index] = '\0';

    /* save the rest of the string */
    if ((str + index + 1)!=0)
        static_str = (str + index + 1);
    else
        static_str = 0;

        return str;
}
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Apr 09, 2019 1:45 pm     Reply with quote

The GPS will send at whatever rate it's going to send at, which is whatever is in its datasheet. You can also measure it with an oscilloscope or logic analyzer.

If your PIC is receiving at the wrong rate, then you will never receive the right messages.

I don't know if you started out with this, but I would plug the GPS into a breadboard with RS232 to USB module and try to interact with it directly from a serial terminal on your PC before going to a PIC. And even then, I like to have a logic analyzer hooked up to see what the incoming messages are to confirm that my PIC is receiving the same information as the analyzer is.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Apr 09, 2019 1:56 pm     Reply with quote

dluu13 wrote:
The GPS will send at whatever rate it's going to send at, which is whatever is in its datasheet. You can also measure it with an oscilloscope or logic analyzer.

If your PIC is receiving at the wrong rate, then you will never receive the right messages.

I don't know if you started out with this, but I would plug the GPS into a breadboard with RS232 to USB module and try to interact with it directly from a serial terminal on your PC before going to a PIC. And even then, I like to have a logic analyzer hooked up to see what the incoming messages are to confirm that my PIC is receiving the same information as the analyzer is.


Yes of course, that is the first i did, alway i did that....
for not work to blind.

The gps work ok, I want use the ccs example for not control the ISR, but to end I had do it.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Apr 10, 2019 1:26 pm     Reply with quote

[quote="cvargcal"]
dluu13 wrote:

The gps work ok, I want use the ccs example for not control the ISR, but to end I had do it.


Having written several GPS enabled applications, you really want to use the serial ISR.

There's all sorts of stuff you can do that's better off in the ISR than in your main program.

...like filtering the NMEA message types where if a character doesn't fall in your sequence, just bail on that message and wait for the next.

Is the first char a $? Ok.
Is the next char a G and then P... ok..
is the next 3 something you want? ok...

If not... nevermind.

Don't even bother collecting the whole string and passing it off to the main loop.

Also, I tend to use the PICs that have decent amounts of RAM in them so the buffer can hold several NMEA sentences for the main loop processor.

So yea... definitely want an ISR handling the serial reception.
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group