Diplaying gps data

am trying to get GPS data gained from adafruits ultimate GPS logger shield to display on a screen this is the screen

http://www.maplin.co.uk/p/serial-uart-16x2-lcd-for-arduino-n92dg?gclid=CjwKEAjwru6oBRDDp4jRj4bL_xASJADJ2obyvVgS0S1RTxeVtx701Rq1ybnr4N6QjdXY32tENqaIjxoCjvvw_wcB

since they both use software serial i expected to just be able to print out the gps commands straight to the something like this

LCD.print(examplegpsdatafunction());
However when i do this just a number is shown on the display not relevant to the actual data, i have checked to see if it was the screen but it is not as it accepts other basic functions as input and printing gps functions to the serial console also works so i am confused what i need to do to get this to work below i have put the full code

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define txPin2 2
static const int RXPin = 8, TXPin = 7;
static const uint32_t GPSBaud = 9600;
int gettime = 0;


// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
SoftwareSerial LCD = SoftwareSerial(0, txPin2);
const int LCDdelay=10;
void lcdPosition(int row, int col) {
  LCD.write(0xFE);   //command flag
  LCD.write((col + row*64 + 128));    //position 
  delay(LCDdelay);
}
void clearLCD(){
  LCD.write(0xFE);   //command flag
  LCD.write(0x01);   //clear command.
  delay(LCDdelay);
}
void backlightOn() {  //turns on the backlight
  LCD.write(0x7C);   //command flag for backlight stuff
  LCD.write(157);    //light level.
  delay(LCDdelay);
}
void backlightOff(){  //turns off the backlight
  LCD.write(0x7C);   //command flag for backlight stuff
  LCD.write(128);     //light level for off.
   delay(LCDdelay);
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  LCD.write(0xFE);
}

void setup()
{
    pinMode(txPin2, OUTPUT);
   LCD.begin(9600);
  Serial.begin(115200);
  ss.begin(GPSBaud);
backlightOn() ;
  clearLCD();
  lcdPosition(0,0);




  Serial.println();
  Serial.println(F("Sats HDOP Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum"));
  Serial.println(F("          (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail"));
  Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));
}

void loop()
{

  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);
  //String dt = d.date;
  unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON) / 1000;
  printInt(distanceKmToLondon, gps.location.isValid(), 9);

  double courseToLondon =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON);

  printFloat(courseToLondon, gps.location.isValid(), 7, 2);

  const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);

  printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);

  printInt(gps.charsProcessed(), true, 6);
  printInt(gps.sentencesWithFix(), true, 10);
  printInt(gps.failedChecksum(), true, 9);
  Serial.println(gps.time.value());
  Serial.println(gps.location.lat(), 6);
  Serial.println(gps.hdop.value());
  smartDelay(1000);
 //gettime = Serial.println(gps.time.value());
 // this is the key problem
 LCD.print(gps.time.value());

   delay(6000);
     clearLCD();

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec)
{
  if (!valid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartDelay(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
  char sz[32] = "*****************";
  if (valid)
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  smartDelay(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
  if (!d.isValid())
  {
    Serial.print(F("********** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
    Serial.print(sz);
  }

  if (!t.isValid())
  {
    Serial.print(F("******** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
    Serial.print(sz);
  }

  printInt(d.age(), d.isValid(), 5);
  smartDelay(0);
}

static void printStr(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartDelay(0);
}

gpsandscreen.ino (5.08 KB)

First change this:

SoftwareSerial LCD = SoftwareSerial(0, txPin2);

to this:

SoftwareSerial LCD(0, txPin2);

That’s a C++ thing that can cause unexpected problems.

The next problem is that you’re using two SoftwareSerial instances. They can interfere with each other, and Serial printing can also interfere with them both. You’re in luck because the GPS is all input, and the LCD is all output, so it is possible to coordinate the two with each other, and with Serial printing.

Let’s look at a kind of timing diagram for receiving GPS data, parsing it, and calling other code, like SD.write:

You won’t be calling SD.write to save something to a card. Instead, you’ll be calling LCD.print to display something. The GPS device will spit out a bunch of sentences at once, and then it goes quiet until the next second comes around. Then it spits another batch out and goes quiet, etc.

The key is to wait for that quiet time to do anything else, like printing. As long as those sentences are coming in, the processor will be too busy to handle the GPS input and LCD output with two SoftwareSerial instances.

We can reorder the loop() code to coordinate the quiet time with LCD and Serial printing, like this:

static unsigned long last_rx    = 0L;
static unsigned long last_trace = 0L;
static unsigned long seconds    = 0L

void loop()
{
    bool got_data = false;

    while (ss.available()) {
      got_data = true;

      if (gps.encode( ss.read() )) {

        // We got a complete sentence.
        if (gps.sentence_type() == TinyGPS::_GPS_SENTENCE_GPRMC)
          seconds++;  // Use the RMC as a 1-second pulse

      }
    }

    if (got_data)
      last_rx = millis();  // Remember that we just got some GPS char *now*.

    else if ((millis() - last_rx > 5)  &&  (last_trace != seconds)) {

      // Otherwise, we didn't get any data, and it's been a while since we received GPS chars,
      //    and we haven't printed data for this second yet.
      // We must have entered the quiet time.

      // Do the LCD printing *FIRST*, so that Serial printing doesn't interrupt
      // the LCD SoftwareSerial prints.
      clearLCD();
      LCD.print(gps.time.value());  // ...and show the time

      LCD.flush();  // wait until all the LCD printing is finished!

      //  Now we can do all the Serial printing...
      printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
        .
        .
        .
      Serial.println(gps.hdop.value());

x --->  smartDelay(1000);    <---- delete this line!
x --->   delay(6000);         <---- delete this line!

      // Remember that we've printed the data for this second.
      last_trace = seconds;
  }


  if ((millis() > 5000) && (gps.charsProcessed() < 10))
    Serial.println(F("No GPS data received: check wiring"));

}

That delay(6000) was also a problem, as the Arduino just sat there while the GPS was spitting out chars, most of which were dropped.

Once this is working, I would suggest deleting the smartDelay function and all the calls to it.

This is a very common problem, and I hope this helps.

Cheers,
/dev