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

Data extraction from Trimble Lassen iQ GPS module

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



Joined: 02 Mar 2006
Posts: 2

View user's profile Send private message

Data extraction from Trimble Lassen iQ GPS module
PostPosted: Thu Mar 02, 2006 3:56 am     Reply with quote

Hi,

I'm trying to extract a string of data containing the latitude and longitude from my Trimble Lassen iQ GPS module to be sent to a PIC (16f876A) which would then transmit the data to be displayed on Hyperterminal.
I've written a program but it doesn't work.

#include<16F876A.h>
#include<stdio.h>
#use delay (CLOCK=20000000)
#fuses hs, noprotect, nowdt, nolvp //do i need to include brownout?
#use rs232 (BAUD=4800,XMIT=PIN_C6,RCV=PIN_C7, parity=N) //connection between GPS and PIC
#use rs232 (BAUD=4800,XMIT=PIN_C5,RCV=PIN_C4, parity=N) //connection between PIC and PC
#byte PORTC=7

void init();
void main();
void read_RS232();
int i = 0;
int j = 0;
char string[73];
char latitude[13];
char longitude[14];


void main(){

init();
set_tris_C(0x90); // is this correct?
while(1){
output_high(pin_C6); // is this line correct?
read_RS232();
output_low(pin_C7); // is this line correct?

for (i=0; i<12; i++){
latitude[i] = string[j+17];
j++;
}
latitude[12] = '\0';
j=0;
for (i=0; i<13; i++){
longitude[i] = string[j+30];
j++;
}
longitude[13] = '\0';
j=0;
printf("Latitude: %S\n\r", latitude);
printf("Longitude: %S\n\r", longitude);
}
}


void read_RS232(){

for(i=0; i<73; i++){ // is this correct?
string[i] = getc();
}
string[72] = '\0'; //is this correct?
}


void init(){
output_bit(pin_C7,0); //is this line correct?
}

I'm still a novice in C-programming and PIC, so the program might look terrible to some of you. Please give me some guidelines on how to improve my program. Or if some of you have successfully tried retrieving data from the Trimble Lassen iQ using PIC16f876A, i would really appreciate it if you can show me a sample of your program. Thanks so much!!

Regards,
Tom
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

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

PostPosted: Thu Mar 02, 2006 8:13 am     Reply with quote

Tom,

First, I think you need to do a search on the internet for NMEA 0183 to find out what you should expect to get out of a GPS unit. NMEA 0183 is the serial format used for most GPS sensor outputs (using RS232). The serial output contains a number of 'sentences' each of which contain position, satellite, speed and time information.

it looks something like:
Code:
$GPRMC,195506,A,5210.318,N,00312.616,W,,,051095,005.3,W*7B
$GPGGA,195506,5210.318,N,00312.616,W,1,00,2.0,187.4,M,-49.5,M,,*7E
$GPGSA,A,3,,,,,,,,,,,,,3.3,2.0,3.0*33
$GPGSV,2,1,08,02,48,069,,07,13,111,,09,37,251,,12,89,214,*79
$GPGSV,2,2,08,16,09,176,,17,07,268,,23,28,311,,26,83,181,*7D
$PGRME,15.0,M,150.0,M,15.0,M*2A
$GPRMB,A,0.00,R,EGDD ,CONGL,5209.82,N,00312.80,W,0.5,192.5,,A*6A
$GPBOD,192.4,T,197.7,M,CONGL,EGDD *2E
$GPWPL,5220.29,N,00308.94,W,EGDD *75

...and is usually sent at either 4800 or 9600 baud. This 'block' of information is sent out at either 1 or 2 second intervals.

'Your code', which looks very similar to a recent post on this forum, so I doubt if this can be referred to as yours !!!

Also do a search on this forum for 'NMEA', 'Parse' or 'parsing' and you'll find all the info you need.
_________________
Regards,
Simon.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Mar 02, 2006 11:40 am     Reply with quote

You'll need an interrupt routine to stuff into a circular buffer the inbound sentence from the GPS
Hint search this forum for circular buffer.

In your main routine loop until your interrupt routine signals a sentence has been received then begin parsing the sentence.
To keep the buffer size down reject unwanted sentences from the GPS by
testing the first few chars to get the ones you want.
You'll learn alot by working through this yourself.
Remember RS232 is asynchronous so when you look at your code in main know that at any point in your program the GPS can and will be sending data..that's why you need the interrupt to service the GPS and then return to your main code.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Mar 02, 2006 12:42 pm     Reply with quote

This routine looks at one particular sentence and retrieves the Speed information from it. It detects a '$' character, which indicates the begining of a new sentence. Then looks to see if a 'C' is sent as part of the sentence header. This indicates that this sentence contains the speed information. It then, simply, counts the comma's and when it gets to the speed info it stuffs it into the variable SBUF which is used in another part of the program.

You can modify the code a bit to grab the information you need and place it into a variable where you can use it elsewhere.

Code:

#int_RDA
RDA_isr()
{
static int i, start, scount;

  SBUF = getc();

  switch(SBUF)
  {
    case 0x24:  /* '$' */ // Start of a sentence
      start = 1;
      break;
    default:
      break;
  }/* end of switch(SBUF) */

  switch(start)
  {
    case 1:
      if(scount++ >= 4)
      {
        start = 2;
      }
      break;
    case 2:
      if(SBUF == 0x43) /* 'C' */ // this sentence contains the SPEED information
      {
        start = 3;
        scount++;
      }
      else
      {
        start = 0;
        scount = 0;
      }
      break;
    case 3:
      if(SBUF == 0X2C) /* comma */
      {
        scount++;
      }
      if(scount >= 8)
      {
        start = 4;
      }
      break;
    case 4:
      if(SBUF == 0x41) /* 'A' */ // is the data valid???
      {
        valid = 1;
      }
      else
      {
        valid = 0;
      }
      start = 5;
      break;
    case 5:
      if(SBUF == 0x2C) /* 'comma' */
      {
        if(scount++ >= 12)
        {
          start = 6;
        }
      }
      break;
    case 6:
      if(SBUF != 0x2C) /* 'comma' */
      {
        if(i < 4)
        {
          speed[i++] = SBUF;// stuff the variable 'speed' with the current
        }                              // speed value to be displayed elsewhere
        else
        {
          speed[4] = SBUF;
          speed[5] = 0x00;
          start = 0;
          scount = 0;
          i = 0;
          ready = 1;// flag that we're done retrieving the speed
        }
      }
      else
      {
        speed[0] = speed[1] = speed[2] = speed[4] = 0x30;// stuff with 0's
        speed[3] = 0x2E;
        speed[5] = 0x00;
        ready = 1;
        scount = 0;
        start = 0;
        i = 0;
      }
      break;
    default:
      scount = 0;
      start = 0;
      break;
  } /* end of switch */
}// end of RDA()


Ronald
tom83



Joined: 02 Mar 2006
Posts: 2

View user's profile Send private message

PostPosted: Fri Mar 03, 2006 1:37 am     Reply with quote

Sigh, i really appreciate all your advice...but too bad i don't really understand your suggestions or the correct way to implement them. Anyway, thanks again.
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

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

PostPosted: Fri Mar 03, 2006 2:00 am     Reply with quote

Douglas Kennedy wrote:
You'll need an interrupt routine to stuff into a circular buffer the inbound sentence from the GPS
Hint search this forum for circular buffer.


Another similar approach is to use a technique called "ping-pong buffers". You need 2 buffers, each one holding an NMEA string or a TSIP packet depending on the protocol you are using. The first buffer is being filled by the serial ISR, while the second one is being processed. When the first buffer is full (i.e. a complete string/packet has been received) the buffers are swapped.
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