Sie sind auf Seite 1von 26

MAE 5483

Advanced Mechatronics

Term Final Project

GPS Receiver Interfacing With


Microcontroller And Displaying
Data On LCD
Team Member: Shuvra Banik
Instructor: Dr. Gary E. Young

School of Mechanical and Aerospace Engineering


Oklahoma State University

What Is GPS?
A space-based satellite navigation system
developed by U.S. Department of Defense in 1973
Became fully operational in 1994
A constellation of 27 satellites (24 are active at a

time and 3 are standby)


Each satellite makes two complete rotations every
day around the Earth

Orbits are arranged so that at any time, anywhere


on Earth, there are at least four satellites "visible"
in the sky

It utilizes Low Power Radio Signal at 1575.42 MHz


in the UHF band

How to locate?
The process is called Trilateration

Distance from at least 3 satellites are required


GPS Receiver receives radio signals from visible
satellites
It measures the time required by the signal to reach
from satellite to GPS Receiver
Velocity = Distance / Time
So, Distance = Velocity * Time

Here velocity of radio signal = Velocity of light


3

Project Goals
Using GPS standard sentences : NMEA 0183

protocol (NMEA = National Marine Electronics


Association)
Powering up GARMIN 18 LVC, 5m GPS Receiver
and parse the sentences using PIC18F4520
microcontroller
Creating menus like Date, Time, Position etc. which
can be chosen by user input from Keyboard of PC

Displaying the result in LCD


4

NMEA 0183 Protocol


NMEA stands for National Marine Electronics Association
Baud rate 4800
1 Hz frequency
Transmitted Sentences:

1. $PGRMT - Sensor Status Information


2. $GPRMC - Recommended Minimum Specific GPS/TRANSIT Data
3. $GPSGGA - Global Positioning System Fix Data
4. $GPGSA - GPS DOP and Active Satellites
5. $GPGSV - GPS Satellites in View
Received Sentences:
Like: $GPALM, $PGRMO, etc.
5

$GPRMC Sentence

$GPRMC Sentence:

$GPRMC,

204331,

V,

3630.0000,N,

09712.0000,W,

$Code
Latitude: DDMM, hemisphere
(GMT+0) HHMMSS

,,,

\r\n

End of sentence

Longitude: DDDMM, hemisphere

Status: A or V
(Max length = 74 )
6

Programming Strategy
RS232 Initialization:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,STREAM=pc)

#use rs232(baud=9600,parity=N,xmit=PIN_C0,INVERT,STREAM=lcd)
# use rs232(baud=4800,parity=N,INVERT,rcv=PIN_C3,STREAM=GPS,ERRORS)

RDA Interrupt:
Interrupt occurs when RS232 receive data available
For GPS, it should occur at PIN_C3
ERRORS:
Used to cause the compiler to keep receive errors in the
variable RS232_ERRORS and to reset errors when they
occur
7

RDA Interrupt Triggering


char store_data [MAX_BUFFER];
.
# INT_RDA
{
int i;
byte char;
char = fgetc (GPS);
.
If ()
{ store_data [ i ] = char;
}

}
void main ()
{

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

}
8

RDA Interrupt DIDNT Trigger!


RDA Interrupt Problems:
Code was correct but interrupt didnt trigger
Powering Up problem?

Use of Multimeter in PIN_C3 showed continuous change in voltage


So NO Powering Up problem
CCS Forum says that a lot of people faced this problem with RDA
Interrupt

What about External Interrupt?


9

External Interrupt
char store_data [MAX_BUFFER];
.
# INT_EXT // INT_RDA Replaced by INT_EXT
{
int i;
byte char;
char = fgetc (GPS);
.
If ()
{ store_data [ i ] = char;
}

}
void main ()
{

enable_interrupts(INT_EXT); // INT_RDA Replaced by INT_EXT


enable_interrupts(GLOBAL);

}
10

External Interrupt TRIGGERS!

Same Code of RDA Interrupt has been used


INT_RDA has been replaced by INT_EXT
PIN_C3 has been connected to External Interrupt PIN_B0 using a Jumper

So output sentences create change in voltage level in PIN_B0


Change in voltage level triggered External Interrupt

11

Length of Receivable Sentences


Sentence

Maximum Characters

$PGRMT

50

$GPRMC

74

$GPGGA

82

$GPGSA

66

$GPGSV

70

4800 Baud =
480
Characters
per Second

12

Continuous Incoming Sentences


$PGRMT,GPS 18LVC - software ver. 2.90,P,P,R,R,P,C,28,R*77
$GPRMC,070837,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*7A
$GPGGA,070837,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*42
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,05,04,305,00,06,00,000,00,07,67,350,00,08,34,311,00*75
$GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70
$GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72
$GPRMC,070838,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*75
$GPGGA,070838,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*4D
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,05,04,305,00,06,00,000,00,07,67,350,00,08,34,311,00*75
$GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70
$GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72
$GPRMC,070839,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*74
$GPGGA,070839,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*4C
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,05,04,305,00,06,21,044,00,07,67,350,00,08,34,311,00*76
$GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70
$GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72
$GPRMC,070840,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*7A
$GPGGA,070840,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*42

13

Memory Management
If Carriage Return (\r) and Line Feed (\n) are removed, around 400
receivable characters per second
At least data for 2 seconds should be stored to get all these sentences

400*2 = 800 bytes must be reserved to store these data


PIC microcontroller has a limited memory and almost 90 percent of
memory is blocked by this which makes the program inefficient

What about Circular / Ring Buffer system?


14

Circular / Ring Buffer System

A circular buffer, cyclic buffer or ring

buffer is a data structure that uses a

single, fixed-size buffer as if it were

connected end-to-end
A buffer size of 600 should work

15

Circular / Ring Buffer Code


#define BUFFER_SIZE 600
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

#int_EXT
void serial_isr() {
int t;

buffer[next_in]=fgetc(gps);
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)

BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];

next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}

16

Problem with Circular / Ring Buffer


Direct access to stored buffer is not possible
It replaces old values
Interrupt couldnt be disabled when needed
Parameters couldnt be sent to Interrupt Sub Routine based on user input
Processing in Interrupt Sub Routine caused loss of few characters

Can I read data directly from PIN_C3 WITHOUT


using Interrupt?
17

Direct Data Read by a Function Call


User chooses option between $PGRMT, $GPRMC, $GPGGA, $GPGSA and
$GPGSV
This input string is stored in a string named checker
String checker is send to a storing function named gps_input (*checker)
gps_input(*checker) doesnt start storing data if starting is not with $
It stops storing when it gets Carriage Return (\r)
Only one sentence is stored based on user input
So it is efficiently using memory ( 82 Bytes only)
18

Direct Data Read Incoming Sentences


$PGRMT,GPS 18LVC - software ver. 2.90,P,P,R,R,P,C,28,R*77
$GPRMC,070837,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*7A
$GPGGA,070837,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*42
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,05,04,305,00,06,00,000,00,07,67,350,00,08,34,311,00*75
$GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70
$GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72
$GPRMC,070838,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*75
$GPGGA,070838,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*4D
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,05,04,305,00,06,00,000,00,07,67,350,00,08,34,311,00*75
$GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70
$GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72
$GPRMC,070839,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*74
$GPGGA,070839,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*4C
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,05,04,305,00,06,21,044,00,07,67,350,00,08,34,311,00*76
$GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70
$GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72
$GPRMC,070840,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*7A
$GPGGA,070840,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*42

19

Direct Data Read Code


#define MAX_BUFFER 82
...
void gps_input(*checker);
...
strcpy(checker,option_string);
...
gps_input(checker);
Let, $GPRMC

void gps_input(*checker)
{
char c;
char temp[7];
.
while(TRUE)
{
c=fgetc(gps);
if(c=='$')
state=1;
if(state)
{
store_data[i]=c;
if(i<6)
temp[i]=c;
++i;

if (i==6) // i.e Is it $GPRMC ?


{
temp[i]='\0';
if((strcmp(temp,checker))!=0)
{i=0;
state=0;}
}
if(state && c=='\r')
{store_data[i]='\0';
i=0;
state=0;
break;
} } }}

20

Finding Specific Data


To find a specific data, i.e. Time/ Latitude/ Longitude/ Date etc.,
Position of Comma in the sentence has been utilized
Typically Pointer is used which is not effective all the time

$GPRMC Sentence:
$GPRMC,

204331,

V,

3630.0000,N,

09712.0000,W,

$Code
Latitude: DDMM, hemisphere
(GMT+0) HHMMSS

,,,

\r\n

End of sentence

Longitude: DDDMM, hemisphere

Status: A or V

Comma Position = 4

Pointer
21

Finding Specific Data Code


char sub_string[SUB_BUFFER];
..
int comma_position;
..
case 'A':
strcpy(option_string,"UTC Time");
comma_position=1;
strcpy(unit_string,"hhmmss");
break;
.

void sub_string_finder(void)
{
int i,j=0,count=0,store_data_length;
store_data_length=strlen(store_data);
if (comma_position==0)
{
strcpy(sub_string,"Not Available");
return;
}
for (i=0;i<store_data_length;++i)
{
if(store_data[i]==',')
++count;

if (count==comma_position)
{
++i;
.
}
sub_string[j]='\0';
break;
}
}
}
22

Option Selection Strategy

Only one function has been written to show all option in both menus
Parameters like 1 or A or C etc. are sent to this function to display

different options
A switch case function is used to store all the option strings
This makes the code concise and memory efficient
Invalid inputs can be handled
23

Option Selector Code


char option_showing_func(char
start_char,char end_char,char
selector_char)
{
char i,option;
for(;;)
{
for(i=start_char;i<end_char+1;++i)
{
.
if (selector_char=='0')
select_func(i,selector_char); function
else

option=fgetc(pc);
.
fprintf(pc,"Wrong option! Please try
again....\r\n ");
fprintf(lcd,"Wrong option! Please try
again....");

void select_func(char opt1,char opt2)


{
switch(opt1)
{
case '1':
strcpy(option_string,"$GPRMC");
switch(opt2)
{
case 'A':
strcpy(option_string,"UTC Time");
comma_position=1;
strcpy(unit_string,"hhmmss");
break;
case 'B':
strcpy(option_string,"Date");
comma_position=9;
strcpy(unit_string,"ddmmyy");
break;

24

Plan in progress!

Converting UTC time to CST time


Sending data to GPS
Plotting trail of motion etc.

25

Questions?

26

Das könnte Ihnen auch gefallen