View previous topic :: View next topic |
Author |
Message |
pilar
Joined: 30 Jan 2008 Posts: 197
|
GPS - string garbage |
Posted: Wed Jul 22, 2009 4:22 pm |
|
|
Hi, I am trying to capture a message of string NMEA of a GPS, specifically the GPRMC, I have implemented this code with the examples of this forum, the problem is that the buffer NMEA_RMC[] there are only trash, which is my mistake?
This is the message that I'm looking for
"$GPRMC,144055.000,A,1209.1120,S,07701.3939,W,0.05,70.22,180209,,*34"
Code: | #include <18F452.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)// RS232 Estándar
char NMEA_RMC[58] ;
#include <STDLIB.H>
#include <MATH.H>
#define BUFFER_SIZE 58
int8 buffer[BUFFER_SIZE];
int8 next_in = 0;
int8 next_out = 0;
int xbuff=0x00;
char GPS_OK = 0;
#INT_RDA
void serial_isr() { // Serial Interrupt
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
int8 bgetc() {
BYTE c;
WHILE(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
void Ini_NMEA_RMC(void){ // Inicia a \0 cbuff -------------------
int i;
int count=58;
for(i=0;i<count;i++){ // Bucle que pone a 0 todos los
buffer[i]=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el índice de siguiente
}
void main() {
int8 n = 0;
int32 i =0;
int8 theChar = 0;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
enable_interrupts(global);
enable_interrupts(int_rda);
delay_ms(50);
do{
GPS_OK == 0;
WHILE (theChar != '$') theChar = bgetc(); // Look for a '$' - the start of a NMEA sentence
theChar = bgetc();
IF (theChar == 'G') {
theChar = bgetc();
IF (theChar == 'P') {
theChar = bgetc();
IF (theChar == 'R') {
theChar = bgetc();
IF (theChar == 'M') {
theChar = bgetc();
IF (theChar == 'C') {
theChar = bgetc(); // Discard ','
theChar = bgetc(); // Discard Time
WHILE (theChar != ',') theChar = bgetc();
xbuff =0;
Ini_NMEA_RMC();
while (theChar != '*'){
NMEA_RMC[xbuff++] = bgetc();
}
GPS_OK == 1;
}
}
}
}
}
} while (GPS_OK == 0);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
pilar
Joined: 30 Jan 2008 Posts: 197
|
|
Posted: Wed Jul 22, 2009 5:00 pm |
|
|
Hi, PCM programmer, this GPS is to 9600KB, because when I use the Hyperterminal it is OK. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 22, 2009 5:09 pm |
|
|
Instead of running the message through your "if" statement code, just
send the data from the buffer to your PC and look at it in a terminal
window. Then you can tell if it's being received properly by your PIC. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jul 22, 2009 5:10 pm |
|
|
Code: | xbuff =0;
Ini_NMEA_RMC();
while (theChar != '*'){
NMEA_RMC[xbuff++] = bgetc(); | The call to Ini_NMEA_RMC() has several problems:
1) It will erase data already received in the background, causing data loss.
2) The received data buffer will be empty, but the next_in and next_out variables are not reset. If data was present before resetting the buffer this will cause problems.
There is no need to reset the buffer to all zeroes, so get rid of this call.
The while loop will never exit as variable theChar never changes inside the loop.
Change to something like: Code: | xbuff =0;
do {
theChar = bgetc();
NMEA_RMC[xbuff++] = theChar;
} while (theChar != '*');
|
|
|
|
pilar
Joined: 30 Jan 2008 Posts: 197
|
|
Posted: Wed Jul 22, 2009 5:27 pm |
|
|
thank you |
|
|
Guest
|
|
Posted: Wed Jul 22, 2009 8:38 pm |
|
|
Hi,
Maybe this is not so important with a circular buffer, but your buffer size is only 58 characters, whereas the receive string is 65+ characters. This means that you won't even get the whole string in the receive buffer before it wraps around. I don't see any good reason to do this.
George |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Jul 22, 2009 8:47 pm |
|
|
Anonymous wrote: | Hi,
Maybe this is not so important with a circular buffer, but your buffer size is only 58 characters, whereas the receive string is 65+ characters. This means that you won't even get the whole string in the receive buffer before it wraps around. I don't see any good reason to do this.
|
Good point, George. It is important.
The NMEA "manual" from Garmin is pretty nice in that it tells you, "this sentence will give you at maximum this many characters".
You should make your buffer at least that big.
I did a GPS parsing routine for both the Garmin 16/17 series OEM sensors as well as the DeLorme GPS2058.
Both work as they should because they have enough buffer space and are state machine driven.
Your ISR just stuffs chars into a buffer until it's done. try waiting until the beginning of a sentence ( marked by '$') and THEN storing the string until it ENDS with a CR or LF (you should get both) and then flag the buffer as ready and then process it. Look at the beginning of the sentence and if it's not GPRMC, dump the buffer and get the next. (I happen to copy the buffer immediately and then release the state machine to continue running to gather the next sentence while I process the one I have)
Regards,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
jma_1
Joined: 08 Feb 2005 Posts: 147 Location: Wisconsin
|
|
Posted: Sun Jul 26, 2009 1:55 pm |
|
|
Greetings,
As an off topic to the already addressed problem, PCM programmer correctly lists the standard NMEA-0183 baud rate at 4800. Another high speed version of this exists and is 38400 baud. Any other baud rates are non-standard and do not follow the NMEA spec.
Cheers,
JMA |
|
|
gamal eldeen
Joined: 29 May 2012 Posts: 29 Location: Alexandria - Egypt
|
|
Posted: Sat Aug 04, 2012 6:48 am |
|
|
please i want to understand the interrupt
Code: |
void serial_isr() { // Serial Interrupt
int t;
buffer[next_in]=getc();
|
how the increment to full in the
??? |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sat Aug 04, 2012 8:41 am |
|
|
gamal eldeen wrote: | please i want to understand the interrupt
|
Look up ring or circular buffers and how they work. That's the explanation you're searching for. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|