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

GPS - string garbage

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



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

GPS - string garbage
PostPosted: Wed Jul 22, 2009 4:22 pm     Reply with quote

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, Evil or Very Mad which is my mistake?

Question 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

View user's profile Send private message

PostPosted: Wed Jul 22, 2009 4:55 pm     Reply with quote

Quote:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

NMEA-0183 is 4800 baud. See this article:
http://en.wikipedia.org/wiki/NMEA_0183
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Wed Jul 22, 2009 5:00 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 22, 2009 5:09 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 22, 2009 5:10 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 22, 2009 5:27 pm     Reply with quote

Very Happy thank you
Guest








PostPosted: Wed Jul 22, 2009 8:38 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 22, 2009 8:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 26, 2009 1:55 pm     Reply with quote

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

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Sat Aug 04, 2012 6:48 am     Reply with quote

please i want to understand the interrupt
Code:

void serial_isr() {                       // Serial Interrupt
   int t;

   buffer[next_in]=getc();


how the
Code:
 [next_in]
increment to full in the
Code:
buffer

???
bkamen



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

View user's profile Send private message

PostPosted: Sat Aug 04, 2012 8:41 am     Reply with quote

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
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