|
|
View previous topic :: View next topic |
Author |
Message |
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
Parsing GPS, example CCS |
Posted: Sun Apr 07, 2019 9:00 pm |
|
|
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
|
|
Posted: Mon Apr 08, 2019 4:54 am |
|
|
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
|
|
Posted: Mon Apr 08, 2019 6:07 am |
|
|
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
|
|
Posted: Mon Apr 08, 2019 7:39 am |
|
|
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
|
|
Posted: Mon Apr 08, 2019 9:24 am |
|
|
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
|
|
Posted: Mon Apr 08, 2019 8:10 pm |
|
|
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
|
|
Posted: Mon Apr 08, 2019 8:16 pm |
|
|
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
|
|
Posted: Mon Apr 08, 2019 8:20 pm |
|
|
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
|
|
Posted: Mon Apr 08, 2019 8:28 pm |
|
|
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
|
|
Posted: Tue Apr 09, 2019 8:15 am |
|
|
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
|
|
Posted: Tue Apr 09, 2019 1:17 pm |
|
|
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
|
|
Posted: Tue Apr 09, 2019 1:45 pm |
|
|
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
|
|
Posted: Tue Apr 09, 2019 1:56 pm |
|
|
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
|
|
Posted: Wed Apr 10, 2019 1:26 pm |
|
|
[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 |
|
|
|
|
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
|