GPS output to LCD

Hi all, I'm very much a newbie and asked for some parts for Christmas to display GPS lat and Lon on a standard 2*16 display.

I received a GPS unit and the display and was keen to get it working so tried this build Arduino: showing information from a GPS on a LCD I have taken great care to assemble the wiring and disconnected the GPS unit while uploading the sketch so that the com port is free. One change I did make was the baud rate to 9600 because that's the speed that displays correct sentences in the serial monitor.

When I run the sketch I get the "waiting for gps" message but never anything else. I have used the U-Blox U-Centre to ponitor the GPS unit and it does get a lock ok and sends out good data.

Even if you have no suggestions for this sketch, do you know of a good sketch that you know works. I realise this is all about learning but its becoming more frustrating than anything else thinking I have all the correct kit bbut cant make it work even when I have supposedly known good sketch.

This is the GPS http://www.ebay.co.uk/itm/401237471608?_trksid=p2060353.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

I'm sure the display is wired and working because I do get the message as above.

You need to post your program so we can see what you can see.

And please post your code between [code] [/code] tags so your code looks like thisand is easy to copy to a text editor

...R

Thanks for the reply, here is the code I’m using. Even after getting a lock all get on the LCD is waiting for GPS

/**
 * Code to display the time & date from a GPS receiver on a LCD.
 *
 * This code was inspired by http://arduino.cc/en/Tutorial/LiquidCrystal and
 * http://playground.arduino.cc/Tutorials/GPS
 *
 * For more information, see http://quaxio.com/arduino_gps/
 */

#include <LiquidCrystal.h>
#include <string.h>
#include <ctype.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int rxPin = 0; // RX pin
int txPin = 1; // TX pin
int byteGPS=-1;
char cmd[7] = "$GPRMC";
int counter1 = 0; // counts how many bytes were received (max 300)
int counter2 = 0; // counts how many commas were seen
int offsets[13];
char buf[300] = "";

/**
 * Setup display and gps
 */
void setup() {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  Serial.begin(4800);
  lcd.begin(16, 2);
  lcd.print("waiting for gps");
  offsets[0] = 0;
  reset();
}

void reset() {
  counter1 = 0;
  counter2 = 0;
}

int get_size(int offset) {
  return offsets[offset+1] - offsets[offset] - 1;
}

int handle_byte(int byteGPS) {
  buf[counter1] = byteGPS;
  Serial.print((char)byteGPS);
  counter1++;
  if (counter1 == 300) {
    return 0;
  }
  if (byteGPS == ',') {
    counter2++;
    offsets[counter2] = counter1;
    if (counter2 == 13) {
      return 0;
    }
  }
  if (byteGPS == '*') {
    offsets[12] = counter1;
  }

  // Check if we got a <LF>, which indicates the end of line
  if (byteGPS == 10) {
    // Check that we got 12 pieces, and that the first piece is 6 characters
    if (counter2 != 12 || (get_size(0) != 6)) {
      return 0;
    }

    // Check that we received $GPRMC
    for (int j=0; j<6; j++) {
      if (buf[j] != cmd[j]) {
        return 0;
      }
    }

    // Check that time is well formed
    if (get_size(1) != 10) {
      return 0;
    }

    // Check that date is well formed
    if (get_size(9) != 6) {
      return 0;
    }

    // TODO: compute and validate checksum

    // TODO: handle timezone offset

    // print time
    lcd.clear();
    for (int j=0; j<6; j++) {
      lcd.print(buf[offsets[1]+j]);
      if (j==1) {
        lcd.print("h");
      } else if (j==3) {
        lcd.print("m");
      } else if (j==5) {
        lcd.print("s UTC");
      }
    }

    // print date
    lcd.setCursor(0, 1);
    for (int j=0; j<6; j++) {
      lcd.print(buf[offsets[9]+j]);
      if (j==1 || j==3) {
        lcd.print(".");
      }
    }
    return 0;
  }
  return 1;
}

/**
 * Main loop
 */
void loop() {
  byteGPS=Serial.read();         // Read a byte of the serial port
  if (byteGPS == -1) {           // See if the port is empty yet
    delay(100);
  } else {
    if (!handle_byte(byteGPS)) {
      reset();
    }
  }
}

You have a very strange way of reading data from the GPS. I would read a complete message before trying to interpret any of it.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. The second example should be compatible with the GPS as your code seems to be looking for a newline character.

Reading a complete message also has the advantage that you can print it for debugging purposes.

...R

rsmith21:
When I run the sketch I get the "waiting for gps" message but never anything else. I have used the U-Blox U-Centre to ponitor the GPS unit and it does get a lock ok and sends out good data.

Many NEO-6M GPS modules have a LED which starts blinking when the module is receiving enough GPS satellites to provide a "GPS fix" with position data.

NOTE: LED lighting means working normal but not located yet; LED flashing means located successfully.

Is there a LED on your module?

If yes: Is it lighting steady state or is it blinking/flashing?

I think the delay is probably causing the trouble. At 9600, the delay will cause it to drop ~35 characters.

I would also like to suggest my NeoGPS library. It parses the RMC fields into numbers you can use for date calculations and for offsetting to the local timezone (see the NMEAtimezone example). NeoGPS verifies the checksum, is smaller and faster than all other libraries, merges multiple GPS sentences (RMC, GGA, etc.) into one coherent fix structure, and is configurable to only parse the fields and messages that you really use (it quickly skips everything else).

One of the biggest problems with other libraries and their examples is their program structure. The NeoGPS example programs are structured to take advantage of the GPS device timing. This usually allows you to modify them without breaking them. :wink: Other example programs frequently break when modified.

Here is your program, modified to use the NeoGPS library:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#include <NMEAGPS.h>

NMEAGPS gps;

#define gps_port Serial

/**
 * Setup display and gps
 */
void setup() {
  gps_port.begin( 9600 );
  lcd.begin(16, 2);
  lcd.print( F("waiting for gps") );  // F macro saves RAM
}

/**
 * Main loop
 */
void loop() {

  while (gps.available( gps_port )) {
    gps_fix fix = gps.read();

    lcd.clear();

    // print time
    if (fix.valid.time) {
      if (fix.dateTime.hours < 10)
        lcd.print( '0' );
      lcd.print( fix.dateTime.hours );
      lcd.print( 'h' );
      if (fix.dateTime.minutes < 10)
        lcd.print( '0' );
      lcd.print( fix.dateTime.minutes );
      lcd.print( 'm' );
      if (fix.dateTime.seconds < 10)
        lcd.print( '0' );
      lcd.print( fix.dateTime.seconds );
      lcd.print( F("s UTC") );
    }

    // print date
    if (fix.valid.date) {
      if (fix.dateTime.date < 10)
        lcd.print( '0' );
      lcd.print( fix.dateTime.date );
      lcd.print( '.' );
      if (fix.dateTime.month < 10)
        lcd.print( '0' );
      lcd.print( fix.dateTime.month );
      lcd.print( '.' );
      if (fix.dateTime.year < 10)
        lcd.print( '0' );
      lcd.print( fix.dateTime.year );
    }

  }
}

Many other fields are available in the fix structure (see Data Model page). Notice that it is about half as many lines as the original program.

The original program used 3714 bytes of program space and 586 bytes of RAM.
The NeoGPS version uses 5080 bytes of program space and 246 bytes of RAM.

NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch → Include Library → Manage Libraries. And if you have any questions, I’d be happy to help. Even if you don’t use the library, be sure to read the Troubleshooting page. It will help you understand some of the timing issues and NMEA messages.

Cheers,
/dev

Hi /dev, thank you so much for the example code, at last I have date and time displayed using your example. I see in the code that you have not included the Lat and Lon print code so I will now endeavour to understand how to construct that :).

Thanks to all that replied and read my post its very much appreciated.

Bob.

Super!

NMEAloc.ino has an example of printing the high-resolution lat/lon, if you want the extras digits. If not, the Streamers.cpp shows how to print each piece. Floating-point Lat/lon printing is here.

Cheers,
/dev