GPS and LCD UNITE kinda :/

Hello there im pretty new to arduinos and programing but have been learning a lot lately i have got two bits of code together 1. gets the GPS data from the module that i can see on the serial monitor 2. Puts text on the LCD (Sainsmart 3.2 TFT LCD and shield)

I have a Mega 2560
Heres the link to the screen and shield: http://www.amazon.com/SainSmart-Display-Adjustable-Shield-Arduino/dp/B00J077V06/ref=sr_1_2?s=electronics&ie=UTF8&qid=1396288495&sr=1-2&keywords=sainsmart+3.2+inch+tft+lcd+shield

Heres the GPS code i have so far

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(115200);
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte); 
  }
  
  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte); 
  }
}

And heres the screen:

// UTFT_ViewFont (C)2012 Henning Karlsen
// web: http://www.henningkarlsen.com/electronics
//
// This program is a demo of the included fonts.
//
// This demo was made for modules with a screen resolution 
// of 320x240 pixels.
//
// This program requires the UTFT library.
//

#include <UTFT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];


// Uncomment the next line for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!

void setup()
{
  myGLCD.InitLCD();

  myGLCD.clrScr();
}

void loop()
{
  myGLCD.setColor(0, 255, 0);
  myGLCD.setBackColor(0, 0, 0);

  myGLCD.setFont(BigFont);
  myGLCD.print("Lon:", RIGHT, 16);
  myGLCD.print("Lat:", LEFT, 16);
  myGLCD.print("Time:", RIGHT, 220);
  myGLCD.print("Date:", LEFT, 220);
  

  myGLCD.setFont(SmallFont);
  

  myGLCD.setFont(SevenSegNumFont);
  myGLCD.print("0", CENTER, 80);
  

  while(1) {};
}

Now i have started trying to put these together…its not going great lol

first question would be how do i put them both together with one void setup? i manage to combine the setups but then it fails where i have deleted the second void setup

Thats my first question the next will be how to get the values from the GPS and print to the screen

Thanks in advance

Get a gps library (e.g. tinygps).
This will help u getting the numbers u want to write to your display…

In the first sketch, you are reading from the GPS and writing to the serial port. In the second, presumably you want to read from the GPS and write to the LCD. You have our permission.

knut_ny: Get a gps library (e.g. tinygps). This will help u getting the numbers u want to write to your display..

Have already tried to get my GPS module to work with tinyGPS with no luck

Right I'm really confused with all this, could someone tell me what bits I'm going to need to no e.g char, variable, int so I can look them up and start to figure this out?

Is there some of the GPS code missing? The declarations and includes before setup()?

Everything before setup() wants to be in your new sketch. Everything in BOTH setup() wants to be in the setup() of your new sketch - but you need to sit down and make sure that you aren't trying to use any pins for more than one task, unless that is what you want! I haven't been through the code thoroughly but as I have that screen combo I suspect there will be conflict, and if there is you will need to move Serial1 to other pins.

And then the difficult bit - read the gps, decode the message and output to lcd!

(Whoops - I forgot it was a Mega clone - but the basics are still right!)

Do you get something at all from GPS? ..That is: car you read the lines with NMEA-sentences? (I guess you cant, probably because the GPS doesn't spit out text in that speed.)

dannable: Is there some of the GPS code missing? The declarations and includes before setup()?

Everything before setup() wants to be in your new sketch. Everything in BOTH setup() wants to be in the setup() of your new sketch - but you need to sit down and make sure that you aren't trying to use any pins for more than one task, unless that is what you want! I haven't been through the code thoroughly but as I have that screen combo I suspect there will be conflict, and if there is you will need to move Serial1 to other pins.

And then the difficult bit - read the gps, decode the message and output to lcd!

(Whoops - I forgot it was a Mega clone - but the basics are still right!)

When i upload the GPS code on its own and look at the serial monitor it is receiving the data so the code for the GPS seems to be working and they are separate pins to where the LCD is so that shouldn’t be a problem. I’m at the decode message and display on LCD bit where im stuck haha

And i have an official Arduino mega 2560 its just the shield and screen that are Sainsmart

knut_ny: Do you get something at all from GPS? ..That is: car you read the lines with NMEA-sentences? (I guess you cant, probably because the GPS doesn't spit out text in that speed.)

Ye i am receiving NMEA sentences from the GPS device as that is the right speed for my module just not sure where i have to put that data e.g do i declare chars or variables or int for it to go in?

1.st try out all libraries U can find.. there are more than 'tinygps' If this doesn't help you, you will hav to deal with it yourself:

create an array of chars: char buffer[99] ; // len >max MNEA-sentence read char(s) from GPS until its a '$': set pointer to 0. repeat: read char from gps into buffer[pointer++] until (char='' or pointer>99) // >99 may happen if u miss the ''

now test start of array for 'GPRMC' // this sentence contain most of the interesting part

The sentens (when u got a fix) has fixed positins for time N/S E/W get those substring to numbers (or print then 'as is') ......... if the start indicates 'the wrong sentence' .. start over: search for '$' The GPS send a full info every 1 sec ?.. the code will be blocking for that amount of time

I'd start by looking for a string starting with $GPGGA as that is the one that contains the satellite fix flag. Then once you have that you can either use that string or $GPRMC string for your location.

To parse the string in a simple way to start with just look for 'n' commas before the data you want.

Right i have managed to get the GPS working with tinyGPS now

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;


static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
  Serial.begin(115200);
  

  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");

  Serial1.begin(115200);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  
  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();
  
  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (Serial1.available())
      gps.encode(Serial1.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    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 print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    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 print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

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

Now i need to sort out how to send them inputs to the LCD, any pointers? im going to look into it now

how to send them inputs to the LCD

Which inputs? I'd be wanting to send the outputs of TinyGPS to the LCD.

any pointers?

char *ptr = "This is a pointer";

Right im getting closer have managed to add the LCD into the “simple test” code on the tinyGPS library. Here it is

#include <UTFT.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Uncomment the next line for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!

TinyGPS gps;


void setup()
{
  myGLCD.InitLCD();

  myGLCD.clrScr();
 

  Serial.begin(115200);
  Serial1.begin(115200);
  

}

void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (Serial1.available())
    {
      char c = Serial1.read();
      //Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    
    {
  myGLCD.setColor(0, 255, 0);
  myGLCD.setBackColor(0, 0, 0);

  myGLCD.setFont(BigFont);
    myGLCD.print("Lon:", RIGHT, 16);
    myGLCD.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  
   while(1) {};
}
 // gps.stats(&chars, &sentences, &failed);
 // Serial.print(" CHARS=");
 // Serial.print(chars);
 // Serial.print(" SENTENCES=");
 // Serial.print(sentences);
 // Serial.print(" CSUM ERR=");
 // Serial.println(failed);
 // if (chars == 0)
 //   Serial.println("** No characters received from GPS: check wiring **");
 // }
// }

(Have commented some bits out at the bottom atm as im working down)

When i print normal text to the LCD it works but when i try and print the longitude value it errors, heres a copy of the error.

Any idea how i would go about fixing this? Think its something i have to declare at the top or something along them lines?

I never used LCD UNITE but I was working with Freetonics LCD Shield and it worked with arduino Uno; May you can try to relate the following code and try to solve your problem.

#include <TinyGPS.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );
// Create an instance of the TinyGPS object
TinyGPS gps;
void getgps(TinyGPS &gps);
void setup()
{
Serial.begin(4800);
lcd.begin(16, 2);
}
void getgps(TinyGPS &gps)
// The getgps function will display the required data on the LCD
{
float latitude, longitude;
//decode and display position data
 gps.f_get_position(&latitude, &longitude);
lcd.setCursor(0,0);
lcd.print("Lat:");
lcd.print(latitude,5);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Long:");
lcd.print(longitude,5);
lcd.print(" ");
delay(3000); // wait for 3 seconds
lcd.clear();
}
void loop()
{
byte a;
if ( Serial.available() > 0 ) // if there is data coming into the serial line
{
a = Serial.read(); // get the byte of data
if(gps.encode(a)) // if there is valid GPS data...
{
getgps(gps); // grab the data and display it on the LCD
}
}
}

Syvester_Jonas:
I never used LCD UNITE but I was working with Freetonics LCD Shield and it worked with arduino Uno; May you can try to relate the following code and try to solve your problem.

#include <TinyGPS.h>

#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );
// Create an instance of the TinyGPS object
TinyGPS gps;
void getgps(TinyGPS &gps);
void setup()
{
Serial.begin(4800);
lcd.begin(16, 2);
}
void getgps(TinyGPS &gps)
// The getgps function will display the required data on the LCD
{
float latitude, longitude;
//decode and display position data
gps.f_get_position(&latitude, &longitude);
lcd.setCursor(0,0);
lcd.print(“Lat:”);
lcd.print(latitude,5);
lcd.print(" “);
lcd.setCursor(0,1);
lcd.print(“Long:”);
lcd.print(longitude,5);
lcd.print(” ");
delay(3000); // wait for 3 seconds
lcd.clear();
}
void loop()
{
byte a;
if ( Serial.available() > 0 ) // if there is data coming into the serial line
{
a = Serial.read(); // get the byte of data
if(gps.encode(a)) // if there is valid GPS data…
{
getgps(gps); // grab the data and display it on the LCD
}
}
}

Ok sweet thanks for that, been looking into it and adapting the code just unsure what this line is?

lcd.begin(16, 2);

Any idea how i would go about fixing this?

The class that myGLCD (dumb name; who's else would it be?) derives from is crap. That class really should derive from Print, so that all the Print methods are implemented. They aren't, though. The class expects YOU to convert the values you want displayed to strings. itoa(), ftoa(), and dtostrf() bear investigation.