neogps - elevation and speed

Hi All

This will be my first post to this forum.

I’m stuck with the Speed and Elevation not display correct values. Longitude, Latitude, Date and Time works 100% and data is displayed on screen and written to sd.
My coding might not be the best and I know SD.h can be replased with SDFat, but first I need to get the gps functional.

Hardware:
3.5inch 8bit MAR3501 - ILI9486 display
Arduino Mega
ublox NEO6MV2 GPS

#include <NMEAGPS.h>

#include <LCDWIKI_GUI.h> //Core graphics library
#include <LCDWIKI_KBV.h> //Hardware-specific library

#include <SD.h>
#include <SPI.h>

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
#define LCD_CS A3   // Chip Select goes to Analog 3
#define LCD_CD A2  // Command/Data goes to Analog 2
#define LCD_WR A1  // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

LCDWIKI_KBV mylcd(ILI9486, LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); //model,cs,cd,wr,rd,reset

//define some colour values
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

NMEAGPS  gps;

gps_fix  fix;

#include <GPSport.h>
//------------------------------------------------------------

#if !defined( NMEAGPS_PARSE_RMC )
#error You must uncomment NMEAGPS_PARSE_RMC in NMEAGPS_cfg.h!
#endif

#if !defined( GPS_FIX_TIME )
#error You must uncomment GPS_FIX_TIME in GPSfix_cfg.h!
#endif

#if !defined( GPS_FIX_LOCATION )
#error You must uncomment GPS_FIX_LOCATION in GPSfix_cfg.h!
#endif

#if !defined( GPS_FIX_SPEED )
#error You must uncomment GPS_FIX_SPEED in GPSfix_cfg.h!
#endif

#if !defined( GPS_FIX_SATELLITES )
#error You must uncomment GPS_FIX_SATELLITES in GPSfix_cfg.h!
#endif

#ifdef NMEAGPS_INTERRUPT_PROCESSING
#error You must *NOT* define NMEAGPS_INTERRUPT_PROCESSING in NMEAGPS_cfg.h!
#endif

#ifndef NMEAGPS_PARSE_GSV
#error You must define NMEAGPS_PARSE_GSV in NMEAGPS_cfg.h!
#endif

#ifndef NMEAGPS_PARSE_SATELLITES
#error You must define NMEAGPS_PARSE_SATELLITE in NMEAGPS_cfg.h!
#endif

#ifndef NMEAGPS_PARSE_SATELLITE_INFO
#error You must define NMEAGPS_PARSE_SATELLITE_INFO in NMEAGPS_cfg.h!
#endif

File dataFile;
String dataString = "";

/*--------------------------------------------------------------------------------------------------------------------------------------------------------------
     doSomeWork()
  -------------------------------------------------------------------------------------------------------------------------------------------------------------- */
static void doSomeWork()
{
  //trace_all( DEBUG_PORT, gps, fix );
  String dataStringDate = "";
  String dataStringTime = "";
  dataString = "";
  /*----------------------------------------------*/

  if (fix.valid.time) {
    enum {BufSizeTime = 3};

    int date = fix.dateTime.date;
    char daychar[BufSizeTime];
    snprintf (daychar, BufSizeTime, "%d", date);
    dataStringDate = "";
    dataStringDate = "Date ";
    if (date < 10)
    {
      dataStringDate += "0";
      dataStringDate += daychar;
    } else {
      dataStringDate += daychar;
    }
    dataStringDate += "/";

    int month = fix.dateTime.month;
    char monthchar[BufSizeTime];
    snprintf (monthchar, BufSizeTime, "%d", month);
    if (month < 10)
    {
      dataStringDate += "0";
      dataStringDate += monthchar;
    } else {
      dataStringDate += monthchar;
    }
    dataStringDate += "/";

    int year = fix.dateTime.year;
    char yearchar[BufSizeTime];
    snprintf (yearchar, BufSizeTime, "%d", year);
    dataStringDate += "20";
    dataStringDate += yearchar;

    mylcd.Set_Text_Size(2);
    mylcd.Print_String(dataStringDate, 0, 450);
    dataString += dataStringDate;
    dataString += " | ";

    int hour = fix.dateTime.hours + 2;
    int minute = fix.dateTime.minutes;

    char hourchar[BufSizeTime];
    char minutechar[BufSizeTime];
    snprintf (hourchar, BufSizeTime, "%d", hour);
    snprintf (minutechar, BufSizeTime, "%d", minute);
    if ( hour < 10 )
    {
      snprintf (hourchar, BufSizeTime, "%02d", hour);
    }
    if ( minute < 10 )
    {
      snprintf (minutechar, BufSizeTime, "%02d", minute);
    }
    dataStringTime = "";
    dataStringTime = "Time ";
    dataStringTime += hourchar;
    dataStringTime += ":";
    dataStringTime += minutechar;

    mylcd.Set_Text_Size(2);
    mylcd.Print_String(dataStringTime, 0, 420);
    dataString += dataStringTime;
    dataString += " | ";
  }

  /*----------------------------------------------*/
  if (fix.valid.location) {
    char latchar[17]; // Buffer big enough for 9-character float
    dtostrf(fix.latitude(), 10, 7, latchar); // Leave room for large numbers
    mylcd.Set_Text_Size(2);
    mylcd.Set_Text_colour(WHITE);
    mylcd.Print_String("Latitude", 10, 160);
    mylcd.Set_Text_Size(3);
    mylcd.Set_Text_colour(RED);
    mylcd.Print_String(latchar, 60, 180);

    dataString += latchar;
    dataString += " | ";

    char longchar[17];
    dtostrf(fix.longitude(), 10, 7, longchar);
    mylcd.Set_Text_Size(2);
    mylcd.Set_Text_colour(WHITE);
    mylcd.Print_String("Longitude", 10, 210);
    mylcd.Set_Text_Size(3);
    mylcd.Set_Text_colour(RED);
    mylcd.Print_String(longchar, 60, 230);

    dataString += longchar;
    dataString += " | ";

    char altchar[8];
    dtostrf(fix.altitude_cm(), 6, 1, altchar);
    mylcd.Set_Text_Size(2);
    mylcd.Set_Text_colour(WHITE);
    mylcd.Print_String("Altitude", 10, 260);
    mylcd.Set_Text_Size(3);
    mylcd.Set_Text_colour(RED);
    mylcd.Print_String(altchar, 60, 280);
    
    int kmh = 0;
    char speedchar[4];
    if (fix.valid.speed && (fix.spd.whole > 5)) {
      kmh = (fix.spd.whole * 185) / 100;
      dtostrf(kmh, 4, 0, speedchar);
    }
    mylcd.Set_Text_Size(2);
    mylcd.Set_Text_colour(WHITE);
    mylcd.Print_String("Speed", 10, 330);
    mylcd.Set_Text_Size(3);
    mylcd.Set_Text_colour(RED);
    mylcd.Print_String(speedchar, 60, 350);

    char satchar[3];
    snprintf (satchar, 3, "%d", gps.sat_count);
    mylcd.Set_Text_Size(2);
    mylcd.Print_String(satchar, 10, 100);

    dataString += satchar;
    dataString += " | ";

    dataFile.println(dataString);
    dataFile.flush();
  }
}

/* --------------------------------------------------------------------------------------------------------------------------------------------------------------
     GPSloop() - This is the main GPS parsing loop.
   -------------------------------------------------------------------------------------------------------------------------------------------------------------- */
static void GPSloop()
{
  while (gps.available( gpsPort ))
    fix = gps.read();
  doSomeWork();
}

/* --------------------------------------------------------------------------------------------------------------------------------------------------------------
     setup()
   -------------------------------------------------------------------------------------------------------------------------------------------------------------- */
void setup()
{
  Serial.begin(9600);
  mylcd.Init_LCD();
  Serial.println(mylcd.Read_ID(), HEX);
  mylcd.Fill_Screen(BLACK);

  mylcd.Set_Text_Mode(0);
  //display 1 times string
  mylcd.Fill_Screen(0x0000);
  mylcd.Set_Text_colour(RED);
  mylcd.Set_Text_Back_colour(BLACK);
  mylcd.Set_Text_Size(2);

  mylcd.Print_String("Initializing SD card...", 10, 100);
  delay(1000);
  pinMode(53, OUTPUT);

  if (!SD.begin(53)) {
    mylcd.Print_String("SD Initialization failed!", 10, 100);
    return;
  }
  mylcd.Print_String("SD Initialization done.", 10, 100);
  delay(1000);

  dataFile = SD.open("Test.txt", FILE_WRITE);
  if (dataFile) {
    mylcd.Print_String("Test.txt - ready", 10, 100);
  }
  else {
    mylcd.Print_String("Error opening Test.txt", 10, 100);
  }
  delay(1000);

  mylcd.Fill_Screen(0x0000);

  DEBUG_PORT.begin(9600);
  while (!DEBUG_PORT);
  DEBUG_PORT.print( F("fix object size = ") );
  DEBUG_PORT.println( sizeof(gps.fix()) );
  DEBUG_PORT.print( F("NMEAGPS object size = ") );
  DEBUG_PORT.println( sizeof(gps) );

  //trace_header( DEBUG_PORT );
  DEBUG_PORT.flush();
  gpsPort.begin(9600);
}

/* --------------------------------------------------------------------------------------------------------------------------------------------------------------
     loop()
   -------------------------------------------------------------------------------------------------------------------------------------------------------------- */
void loop()
{
  GPSloop();
}

Thank you

I use TinyGps for a NEO-6M. That library gives me speed, altitude etc. as numerical values. No baking of strings.
Altitude is a bit fluctuating. Nothing to do about ut as I understand.

What are typical "not correct" values, and what are you expecting?
GPS altitude is so bad that pilots navigating by GPS rely on the pressure altimeter to stay at legal altitudes.

Thanks Railroader and SteveMann for the reply.

SteveMann

Speed - 9 all the time.
Elevation - 0 expecting about 1500

for elevation i tested the library without the string creation using dtostrf, only sending the data to the serial monitor as per neogps examples and in the test I get the correct elevation.

I’ve been reading several warnings regarding the use of strings. They are suspect in my mind.
Take a look at the easy way used down here. The libs used are

#include <SoftwareSerial.h>
#include <TinyGPS++.h>

An example of getting its data:

void loop()
{
  int tmp, tmpa;
  float ftmp;

  while (mySerial.available())
    gps.encode(mySerial.read());
  if (true)
  {
    //                                                                 speed
    if (gps.speed.isValid() && ((millis() - speed_print) > 300))
    {
      tmp = int(gps.speed.kmph() + 0.5);
      if (tmp != last_speed)
      {
        mylcd.setCursor(7, 0);

        if (tmp < 100)mylcd.print(" ");
        if (tmp < 10)mylcd.print(" ");
        mylcd.print(tmp);