Showing posts with label articles. Show all posts
Showing posts with label articles. Show all posts

Sunday, 20 January 2013

Parsing GPS NMEA navigation message

A GPS receiver communicates its navigation solutions to the external world through a standard protocol. This protocol is a subset of the NMEA-0183 standard for interfacing marine electronic devices as defined by National Marine Electronics Association (NMEA). The NMEA reference manual provided along with each GPS receiver provides the details of the standard messages sent out by the particular receiver. Here we give an extract of a few basic messages that are essential for reading the PVT (Position, Velocity, and Time) solution.

Click Here for Introduction to GPS and How does a GPS Receiver Calculate Range from Satellites

The following table lists the entire set of NMEA messages related to GPS receiver and the information that they convey – 

Message Name          
Information Contained      
GGA
Time, Position, and Fix type
GLL
Latitude, Longitude, and UTC time of fix with status                                 
GSA
Receiver operating mode, satellites used, and DOP
GSV
Number of satellites, elevation, azimuth, and SNR
RMC
Time, Date, Position, course, and speed
VTG
Course, and speed relative to ground
ZDA
PPS timing

Most of the receivers provide an option to enable / disable each of these messages depending on the bandwidth and data rate limits.

A typical GPS logs read from the receiver would be similar to this –
............................................................
............................................................
$GPGSV,3,1,12,04,64,168,27,17,50,004,32,28,42,059,40,08,34,149,22*75
$GPGSV,3,2,12,02,28,202,18,27,27,320,22,26,25,235,16,15,13,273,*7B
$GPGSV,3,3,12,09,12,323,26,10,10,163,39,07,08,149,25,20,04,075,*78
$GPRMC,125535.281,A,1908.0906,N,07254.3485,E,000.0,000.0,290611,,,A*6C
$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D
$GPGGA,125536.281,1908.0906,N,07254.3485,E,1,07,1.4,33.2,M,-65.1,M,,0000*4F
$GPGSA,A,3,28,17,07,10,09,27,04,,,,,,2.0,1.4,1.5*33
............................................................
............................................................
In the current discussion, we shall only consider RMC and VTG messages, since these two messages contain the PVT solution required.


RMC – Recommended Minimum Specific GNSS Data:
$GPRMC,125535.281,A,1908.0906,N,07254.3485,E,000.0,000.0,290611,,,A*6C


Name
Example
Unit
Description
Message ID
$GPRMC

RMC protocol header
UTC Time
125535.281

hhmmss.sss
Status
A

A = valid; V = Not Valid
Latitude
1908.0906

ddmm.mmmm
N/S Indicator
N

E = East; W = West
Longitude
07254.3485

dddmm.mmmm
E/W Indicator
E

E = East; W = West
Speed Over Ground
000.0
Knots

Course Over Ground
000.0
Degrees
True
Date
290611

ddmmyy
Magnetic Variation*
12.123
Degrees

E/W Indicator
E

E = East; W = West
Mode
A

A = Autonomous, D = DGPS; E = DR**
Checksum
*6C


<CR><LF>


End of message

VTG – Course Over Ground and Ground Speed

$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D

Name
Example
Unit
Description
Message ID
$GPVTG

VTG  protocol header
Course
000.0
degrees
Measured Heading
Reference
T

True
Course
005.6
degrees
Measured Heading
Reference
M

Magnetic
Speed
00.1
knots
Measured Horizontal Speed
Units
N

Knots
Speed
00.2
km/hr
Measured Horizontal Speed
Units
K

Kilometers per hour
Mode
A

A = Autonomous, D = DGPS; E = DR**
Checksum
*0D


<CR><LF>


End of message
* Magnetic variation data may or may not be supported in all the receivers
** DR = Dead Reackoning

Reading NMEA messages and displaying on LCD:

Two approaches can be taken to read the NMEA message through serial port and displaying them on the LCD screen , each method having its own merits and demerits –

1.  Interrupt based architecture (Process function as a background process)

In this method, we keep filling a global circular buffer, say

Rx_buffer[MAX_GPS_BUFFER_SIZE]

in the ISR. As an example an ISR written for ARM 7 processor reading GPS from UART0 is given here -

void Uart0_ISR(void) __irq
{
     char read_byte = 0;

     read_byte = U0RBR;

     Rx_buffer[Rx_buffer_pntr++] = read_byte;

     if(Rx_buffer_pntr >= MAX_GPS_BUFFER_SIZE)
     {
           Rx_buffer_pntr = Rx_buffer_pntr - MAX_GPS_BUFFER_SIZE;
     }

     VICVectAddr = 0;
}

The value of MAX_GPS_BUFFER_SIZE depends on the processing time of the foreground processes i.e. how often is the Rx_buffer checked for received bytes.

This approach is best suited for environments where many processes need to run in parallel. But it requires relatively large memory space to store the received bytes.

2. Polling based architecture (Processing function as a foreground process)

In this method, no other background process can be run along with message parsing. Here the program keeps polling the interrupt bit after receiving each byte. As an example, let us look at a 8051 based implementation, where the program polls each byte and waits until a $ is received –

while (1)
{

while(RI != 1);RI = 0;
if(ASCII_DOLLAR != SBUF)
{
continue;
}
....
....
....
}

This approach is suitable for small projects where the memory available is very small (e.g. in case of 8051, only 128 bytes is available for data) and GPS message reading is the only process running.

Steps to Parse NMEA messages

i.              Identify “$GP symbol, which signifies the start of the message
ii.             If the characters that follow $GP are “RMC”, then go to the parsing function for RMC. Similarly if it is “VTG” go to the processing function for VTG.
iii.            In each of the messages, use comma (,) as the separator for the values to be extracted.
iv.            The message delimiter is identified as an asterisk symbol (*) which is followed by the checksum. The checksum in the message is an exclusive-or of all the bytes received between $ and *, not including both.
The last two bytes received after * represent the two nibbles of the 1 byte check sum.

Consider the following message –
$GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48

Checksum = (ASCII_G) XOR (ASCII_P) XOR .... so on up to ... (ASCII_K)

If the message is received properly, the Checksum must read 0X48. Once the checksum passes, copy the values of Longitude, latitude, time and Velocity to corresponding buffers for display on LCD. 

Click here for C-code Interfacing 8051 with LCD and Geolocation Tracking with GPS and GSM project


8051 Interfaced with GPS parsing NMEA Messages showing Latitude and Longitude
GPS Interfaced with 8051 showing Latitude and Longitude


8051 Interfaced with GPS parsing NMEA messages showing Velocity and Time
GPS Interfaced with 8051 showing Velocity and Time

Monday, 16 April 2012

LCD Interface with 8051 Microntroller


C Code


#include <regx51.h>
#define LCD_COMMAND 0
#define LCD_DATA 1
#define LCD_RS P0_0       //Edit it per your circuit design
#define LCD_RW P0_1       //Edit it per your circuit design
#define LCD_EN P0_2       //Edit it per your circuit design
#define LCD_PORT P2       //Edit it per your circuit design

char *message_1 = "electronicsprojs";
char *message_2 = ".blogspot.com";

/*Function Prototypes*/

void LCD_delay(unsigned int);
void LCD_putc(int,int);
void LCD_puts(unsigned char*);
void LCD_init();

main()
{
 LCD_init();
 LCD_putc(0x80,LCD_COMMAND); //Write to Row 1
 LCD_puts(message_1);
 LCD_putc(0xC0,LCD_COMMAND); //Write to Row 2
 LCD_puts(message_2);
 LCD_delay(1000);
 while(1);
}

void LCD_init()
{
 LCD_EN = 1;
 LCD_RS = 0;

 LCD_putc(0x38,LCD_COMMAND); //Use 2 lines 5X7 matrix
 LCD_putc(0x0C,LCD_COMMAND); //Display on Cursor on
 LCD_putc(0x01,LCD_COMMAND); //Clear Screen
 LCD_delay(256);
}

void LCD_delay(unsigned int i)
{
 while(i>0)
  i--;
}


void LCD_putc(int character, int type)
{

 LCD_delay(10);
 LCD_RS = type;  //1 : Write Data, 0 : Write Command
 LCD_RW = 0;
 LCD_PORT = character;
 LCD_EN = 0;   //Latch data with a low to high pulse
 LCD_delay(10);
 LCD_EN = 1;
}

void LCD_puts(unsigned char *string)
{

 while (*string)
 {
  LCD_putc(*string++,LCD_DATA);
 }
}


Sunday, 1 April 2012

Infrared Beam Break Detector

This purpose of this article is to design a circuit using Infrared signals to detect a beam break which can be used in multiple real world applications. The IR receiver used is TSOP1738. Below are some of the main requirements of Infrared Transmiter signal properties as described in the datasheet
  • Carrier frequency should be close to the  center frequency of the bandpass (38kHz)
  • Burst length should be 10 cycles/burst or longer
  • After each burst which is between 10 cycles and 70 cycles a gap time of at least 14 cycles is neccessary

Design


1. Carrier Frequency (f1) : The center frequency of TSOP1738 is 38kHz

f1 = 1.44/((Ra1+2Rb1)C)
f1 = 38kHz

Let
Ra1 = 1k
C = 0.01uF

With that Rb1 = 1.394k or
Rb1= 2k variable resistor


2. Burst and Gap frequency (f2) : Let burst cycle equals gap cycle be equal to 40 cycles (burst between 10 and 70 cycles and gap greater than14 cycles)

f2 = 38k/ 40
f2 = 950
f2 = 1.44/((Ra2+2Rb2)C)

Let
Ra2 = 10k
C = 0.01uF

With that
Rb2 = 70.789k or
Rb2 = 100k variable resistor

Note:
1. BC547 is used at the output of transmitter as switching transmitter to boost the voltage increasing the range.

2. When the Infrared beam is broken, the output of TSOP1738 goes high. Using switching transistor 2N2222, the signal is inverted to High to Low which can be directly interfaced to External edge triggered interrupts of 8051 (EXT0 and EXT1)

Infrared beam break detector transmitter receiver circuit

Saturday, 31 March 2012

Global Positioning System – How does the receiver calculate the range from satellites?

It is now clear from the previous discussion that the receiver has to calculate the distance of the GPS antenna (range) w.r.t each of the satellites that it is tracking1.

The GPS satellite signal structure plays a major role in this range estimation. GPS transmissions utilize Direct Sequence Spread Spectrum (DSSS CDMA) modulation technique in which each satellite is associated with a unique code (called the Pseudo-random code or PRN code). The data from each satellite is first encoded using this PRN code and then transmitted using BPSK modulation.

There are two types of codes that a GPS satellite uses – the coarse acquisition or the C/A code and the precise P code. Most of the commercial GPS equipments only utilize the C/A code for position determination (More on the signal structure in future blogs). For the moment let us just note that these codes are a special category of PRN codes called the “Gold codes” which have exceptional auto-correlation and cross-correlation property. These properties mean that –

  • The PRN code of a satellite has very little or no similarity with the shifted version of itself
  • The PRN code of any one satellite has very little or no similarity with the PRN codes (even shifted versions) of all other satellites

Hence in order to decode the data from the satellite, the receiver must produce a replica of the PRN code (which acts like a key to the locked data), which not only matches with the satellite Id but also matches the time shifts incurred due to propagation from satellite t user. Let us see this in more detail.

Consider the following case in which the satellite has transmitted the signal at t = t0 s. But due to the propagation delay, it has reached the receiver after a delay of td seconds –

The task of the receiver is thus to generate the replicas of the PRN code for the satellite with all possible shifts and determine that amount of shift for which the incoming PRN code matches the generated code (i.e. has the&nbsp; maximum correlation).
Now, if the time at which the satellite has transmitter the signal is known (t0) and the satellite clock and receiver clock are in perfect synchronization, then the shift required to match the incoming signal would exactly provide us with the propagation delay td. The range or the distance is immediately determined as this ∆t multiplied by the speed of light c (approximately 3 x 108 m/s).

But, the story is not that simple. The satellite clock is a very high precision atomic clock and the clock at the receiver is a low precision clock. Hence the propagation delay thus obtained suffers from what is called “user clock bias”.  One good thing about this clock bias is that since all the satellites are perfectly synchronized (or in other words, their errors can be estimated to high degree of accuracy), this user clock bias is a common error to all the satellite signals. This clock bias is the fourth variable in the range equations that needs to be estimated.


The range information thus obtained does not truly provide us with the geometric range of the satellite to the user but contains
  1. Geometric range from satellite to user
  2. User clock bias factor
  3. Offset between the system time and satellite clocks
  4. Other delays due to atmospheric errors (ionospheric and tropospheric)
Hence this range is referred to as “Pseudo range” rather than actual range.


Let us assume that the satellite clock bias can be accurately estimated and the atmospheric errors can be neglected (as of now). We can thus construct the range equations from the pseudo-range measurements from (at-least) four satellites as:

R1=√((x1 - xu)2 + (y1 - yu)2) + (z1 - zu)2) + ctu

R2=√((x2 - xu)2 + (y2 - yu)2) + (z2 - zu)2) + ctu

R3=√((x3 - xu)2 + (y3 - yu)2) + (z3 - zu)2) + ctu

R4=√((x4 - xu)2 + (y4 - yu)2) + (z4 - zu)2) + ctu

Where,
  • R1 to R4 are the pseudo-ranges from four satellites being tracked
  • (x1,y1,z1) correspond to the position of satellite 1 in x, y, z coordinates (and similarly for other satellites)
  • (xu,yu,zu) correspond to the position of user in x, y, z coordinates is the range due to user clock bias
Solving these equations for a Least-Square solution yields us the estimations of the user position.
The GPS system not only provides us with accurate position information but also accurate velocity and time information as well. Hence the complete GPS solution is called a PVT solution (Position, Velocity and Time). We shall discuss more on how each of them is extracted in future blogs.
1Tracking is a process of continuously monitoring the satellite signal parameters and extracting information from them

Saturday, 17 March 2012

Sending SMS using AT Commands

This article describes sending a SMS from a Microcontroller through a GSM modem using AT Commands. through RS232. AT commands can be sent to a GSM modem via a computer serial port or from the serial port of a 8051 Microcontroller.

Computer serial port


1. Connect your GSM modem to the computer serial port. New systems nowadays dot not have serial port, hence you would need to buy a USB to serial converter and connect the GSM modem to it.

2. If you are using Windows XP® OS, open Programs -> Accessories -> Communications -> HyperTerminal

3. Select the COM port you have the modem connected to.

4. Check the port settings, make sure that the baud rate matches with that of the GSM modem and and also that the Flow Control is set to "None".

5. Type the AT Commands below in the HyperTerminal Editor

AT+CMGF = 1 and Enter
AT+CMGS="+919449XXXXXX" and Enter
"Electronicprojs.Blogspot.com" and Hit CTRL+Z

6. In Windows 7® OS though, there is no hyperterminal program inbuilt. You will have to download a similar one. There are many good free programs available.

7. You would need to note that in this case we are connecting the serial port cable from Female pin (GSM Modem) to Male pin (Computer). Hence no crossing is required. In other words, we should use a straight cable.

8051 MicroController Serial port


1. 8051 SFR's are programmed for a baud rate of 9600.

2. Send the AT commands in #5 above through code. For Enter use escape character "\r" and for CTRL+Z use ASCII 0x1A.

3. The serial port cable is connecting from Female pin (GSM Modem) to Female (8051 Board). So you need a have a female to male converter. Also, make sure that the Rx and Tx inside in the converter are crossed. In otherwords, the Rx pin of GSM Modem should go to Tx pin of 8051 microntroller. This is called a crossed cable.

4. Below is the C program using Keil® Compiler for 8051. We added infinite while loop after the sendsms() routine because otherwise we found that the code compiled was sending the SMS in a infinite loop.

Note : Beginners always complain about their code working through serial port of a computer but the same not working through chip. It is very essential to understand the difference between crossed cable and straight cable as well as the pins configurations of male and female connectors before starting.

C program

#include <REGX51.H>
#include <AT89X51.H>

unsigned char *command_AT = "AT\r";
unsigned char *command_CMGF = "AT+CMGF=1\r";
unsigned char *command_CMGS = "AT+CMGS=\"+919449XXXXX\"\r";
unsigned char *message = "electronicprojs.blogspot.com";
unsigned char CTRLZ = 0x1A;

void puts(unsigned char* ptr);
void putc(unsigned char chr);
void sendsms(void);
void initialize();

main()
{
initialize();
sendsms();
while(1);
}

void initialize()
{
SCON  = 0x50;   /*SCON: mode 1, 8-bit UART, enable receive      */
TMOD |= 0x20;   /*TMOD: timer 1, mode 2, 8-bit                  */
TH1   = 0xFD;   /*TH1:  for 9600 baud                           */
TR1   = 1;      /*TR1:  timer 1 run                             */

}

void sendsms()
{
puts(command_AT);
puts(command_CMGF);
puts(command_CMGS);
puts(message);
putc(CTRLZ);
}

void puts(char* p)
{
char *temp = p;  /*temp pointer so that the actual pointer is not displaced */
while(*temp != 0x00)
{
putc(*temp);
temp++;
}
}

void putc(unsigned char chr)
{
SBUF = chr;
while(TI==0);  /*Wait until the character is completely sent */
TI=0;                    /*Reset the flag */
}