gps to lcd

Hi I'm trying to get info from Haicom bluetooth gps to an arduino and then have the long and lat displayed on a 16x2 lcd.. (same type used in the liquidcrystal examples in the ide)

now the hardware isnt a prob.. hence why im in the software section :slight_smile:

My gps outputs ttl from a port on the back and that fires out these packets:

$GPGGA,000301.042,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72
$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C
$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76
$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
$GPRMC,000301.042,V,0000.0000,N,00000.0000,E,0.0,0.00,291006,,,N*4E
$GPVTG,0.00,T,,M,0.0,N,0.0,K,N*32
$GPGGA,000302.032,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76
$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C
$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76
$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
$GPRMC,000302.032,V,0000.0000,N,00000.0000,E,0.0,0.00,291006,,,N*4A
$GPVTG,0.00,T,,M,0.0,N,0.0,K,N*32
$GPGGA,000303.032,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77
$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C
$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76
$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
$GPRMC,000303.032,V,0000.0000,N,00000.0000,E,0.0,0.00,291006,,,N*4B
$GPVTG,0.00,T,,M,0.0,N,0.0,K,N*32

what i want to know is (before it gives me a headache trying to find out) how can i get the arduino to isolate the long and lat, then display them on the lcd..

also can I use another pin for the ttl input so i can still use the main serial pins for debug?..

thnx in advance :3

This is a basic string parsing problem. Look up an NMEA reference to see what the various sentences mean; IIRC both the $GPGGA and $GPRMC sentences contain the lat/long. The fields are comma delimited, so counting commas is an easy way to skip to the fields you want.

Alternatively, you may want to take a look at TinyGPS, from the author of NewSoftSerial (which may be useful in saving the hardware UART for other purposes, like debugging).

-j

oh i forgot to mention XD i cant program worth a dang XD

a friend threw this bit of code at me...

/* The char offset apparently: 1st line of packet..read down for offset
 * 18, 26, 30, 39
 * $GPGGA,000301.042,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72
 *                   1       2   3        3
 *                   8       6   0        9
 */

int c;
int n = 0;
int packet_len = 396;   /* better check */

char lat[10];
float lat_f;

while(1) {
        c = Serial.read();
        if(n == packet_len) {
                n = 0;
                continue;
        }
        if(n >= 18 && n <= 26) {
                lat[n - 18] = c;
                if(n == 26) {
                        lat[9] = 0;
                        lat_f = float(lat);
                }
        }
        /* and similar for long */
}

hopefully i can workout what to do with it XD

bTw thnx for the links kg4wsv :wink:

so far i have this, that a friend helped me cobble together:

/* gps to lcd 0.00.0
 * to read a packet from the gps, need nmea.h ?
  * take the required data, then print it to the lcd
 */
#include <NewSoftSerial.h>
#include "TinyGPS.h"
TinyGPS gps;

// Use NewSoftSerial for greater reliability
#define RXPIN 3
#define TXPIN 2

long lat, lon;
unsigned long fix_age, time, date, speed, course;
unsigned long chars;
unsigned short sentences, failed_checksum;

NewSoftSerial nss(RXPIN, TXPIN);

void setup() 
{
  Serial.begin(38400);
  Serial.print("Ready..");
}

void loop()
{
  while (nss.available())
  {
    int c = nss.read();
    if (gps.encode(c))
    {
      // process new gps info here
      // retrieves +/- lat/long in 100000ths of a degree
      gps.get_position(&lat, &lon, &fix_age);

    }
 
  }
      Serial.print("lat");
      Serial.print(lat);

      delay(500);
      Serial.print("Long");
      Serial.print(lon);

      delay(500);
}

but due to not being able to get a fix on a single satellite while indoors i dont know if i am getting any info from the gps unit, so all i get on the serial monitor is "0" for long and lat..

im not sure but i may be able to use the hardware serial RX for the gps and the TX for debug to the pc?

once i know i am getting the info from the gps and can output that as i want, then i can work out how to get it onto an lcd..
no doubt there are any things i have done wrong so far XD

I am grateful for any help i can get on this :slight_smile:

(EDIT)

Really in need of some help here..

I been messing with trying to not use the soft serial cos my gps outs at 38400 baud. and im not sure newsoftserial works at that speed..

here is the code:

/* gps to lcd 0.00.0
 * to read a packet from the gps, need nmea.h ?
  * take the required data, then print it to the lcd
 */
#include <LiquidCrystal.h>
//#include <NewSoftSerial.h>
#include "TinyGPS.h"
TinyGPS gps;

// Use NewSoftSerial for greater reliability
// #define RXPIN 7
// #define TXPIN 6

long lat, lon;
unsigned long fix_age, time, date, speed, course;
unsigned long chars;
unsigned short sentences, failed_checksum;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// NewSoftSerial nss(RXPIN, TXPIN);

void setup() 
{
 Serial.begin(38400);
 // Serial.print("Ready..");
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  // Print a message to the LCD.

}

void loop()
{
  while (Serial.available())
  {
    int c = Serial.read();
    if (gps.encode(c))
    {
      // process new gps info here
      // retrieves +/- lat/long in 100000ths of a degree
      gps.get_position(&lat, &lon, &fix_age);

    }
 
  }
      // set the cursor to column 0, line 1
      // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(0, 0);
      // print the number of seconds since reset:
      lcd.print("lat"), lcd.print(lat);
    //  Serial.print("lat");
    //  Serial.print(lat);
      delay(500);
      
      // set the cursor to column 0, line 1
      // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(0, 1);
      // print the number of seconds since reset:
      lcd.print("Long"), lcd.print(lon);
    //  Serial.print("Long");
    //  Serial.print(lon);
      delay(500);
}

i commented out bits instead of deleting them

using soft serial and no hard serial my lcd looked like this:

lat0
long0

good cos thats the layout i was after.. but no gps data getting thru..

so i used hard serial and commented out all nss bit as in the code above and i get this in lcd:

latplong0
long0

why is hardware serial doing that?

and what am i doing wrong to not get the gps to either decode or display..

everything is wired up correctly.. hence why im posting in the software section..