NEO-GPS sketch no-longer displays number of satellites..

Brief history… About a month ago; I upgraded from Arduino 1.6.4 to 1.8.4 I had trouble with it, so I copied all my sketches to a backup folder. Then deleted 1.6.4, followed by installing 1.8.4

I have several sketches for the GPS, oled display. I went on a cruise back in the beginning of Sept. So I uploaded the boat sketch to my Trinket. Last week, I decided to copy my GPS Speedometer sketch back to the Trinket.

The fonts are not the same as before(larger). No big deal, I figured out how to change the fonts, move the data around to fit the screen.

I can’t figure out why the sketch no-longer displays the number of satellites. Was there a change in the Library/header files?

/*
   Motorcycle (GPS) Speedometer
*/


#include <TinyWireM.h>
#include <USI_TWI_Master.h>
#include <Wire.h>
#include <NeoGPS_cfg.h>
#include <NMEAGPS_cfg.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>
#include <Fonts/FreeSansBold18pt7b.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <NeoSWSerial.h>

NeoSWSerial gps_port(4, 3);  // ASSIGNS PINS 3, 4 FOR GPS RX/TX

#include "NMEAGPS.h"

static NMEAGPS  gps; // This parses the GPS characters

// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


void setup() {
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars

  gps_port.begin(9600);

  // request RMC and GGA only
  gps_port.println( F("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28") );

  display.begin(SSD1306_SWITCHCAPVCC);


  display.clearDisplay();
  display.setFont(&FreeSerif9pt7b);
  //display.setTextSize(1);

  display.setTextColor(WHITE);
  display.setCursor(27, 22);
  display.println( F("Mini-GPS"));
  display.display(); // SEND SPLASH SCREEN
  delay(2000);       // WAIT 2 SECONDS

  display.clearDisplay();
  display.setFont(&FreeSerif9pt7b);
  //display.setTextSize(0.8);
  display.setCursor(55, 12);
  display.print( F("By"));


  display.setTextSize(0.8);
  display.setCursor(15, 26);
  display.print( F("Nick Sebring"));
  display.display(); // SEND SPLASH SCREEN
  delay(5000);       // WAIT 10 SECONDS


  //  Insert text when no GPS signal received... ***********************
  //display.clearDisplay();
  //display.setCursor(2, 50);
  //display.print( F("Serching satellites."));
  //display.display(); // SEND SPLASH SCREEN
}



void loop()    // run over and over again
{


  while (gps_port.available()) {

    if (gps.decode( gps_port.read() ) == NMEAGPS::DECODE_COMPLETED) {

      if (gps.nmeaMessage == NMEAGPS::NMEA_RMC) {
        //  If your device emits a GGA then an RMC each second,
        //    change the above GGA to RMC.  Or if you don't get all
        //    the attributes (e.g., alt, heading, speed and satellites)
        //    try changing the above test.  NMEAorder.ino can be
        //    used to determine which one is last (should be used above).

        //  BTW, this is the safest place to do any time-consuming work,
        //    like updating the display.  Doing it elsewhere will cause GPS
        //    characters to be lost, and some fix data won't be available/valid.
        //    And if you take too long here, you could still lose characters.


        display.clearDisplay(); //CLEAR THE OLED BUFFER, THUS CLEARING THE SCREEN:  GOT IT!

        const gps_fix & fix = gps.fix();

        //  construct data to be sent to the OLED *****************************

        display.setFont();  //reset font to default

        display.setTextSize(1);
        display.setTextColor(WHITE);
        display.setCursor(0, 0);
        display.print( F("Sat: "));

        if (fix.valid.satellites) {
          display.setCursor(60, 20);
          display.println( fix.satellites );
        }


        if (fix.valid.date && fix.valid.time) {
          display.setCursor(95, 0);
          NeoGPS::clock_t seconds = (NeoGPS::clock_t) fix.dateTime;     // convert pieces to seconds

          // Calculate DST changeover times just once per year
          static NeoGPS::clock_t springTime, fallTime;
          static NeoGPS::time_t  changeover;

          if ((springTime == 0) || (changeover.year != fix.dateTime.year)) {

            changeover.year    = fix.dateTime.year;
            changeover.month   = 3;
            changeover.date    = 14; // latest 2nd Sunday
            changeover.hours   = 2;
            changeover.minutes = 0;
            changeover.seconds = 0;
            changeover.set_day();
            // Step back to the 2nd Sunday, if day != SUNDAY
            changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
            springTime = (NeoGPS::clock_t) changeover;

            changeover.month   = 11;
            changeover.date    = 7; // latest 1st Sunday
            changeover.set_day();
            // Step back to the 1st Sunday, if day != SUNDAY
            changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
            fallTime = (NeoGPS::clock_t) changeover;
          }

          NeoGPS::clock_t tz = 5;  //  THIS IS WHERE YOU PUT IN YOUR LOCAL TIME ZONE
          if ((springTime <= seconds) && (seconds < fallTime))
            tz--;
          seconds -= tz * 60 * 60;                                      // offset seconds to local timezone, including DST
          NeoGPS::time_t localTime( seconds );                        // convert seconds back to pieces                     // convert seconds back to pieces
          if (localTime.hours < 10) {
            display.print( '0' );
          }
          display.print( localTime.hours ); display.print( ':' ); // use pieces
          if (localTime.minutes < 10) {
            display.print( '0' );
          }
          display.print( localTime.minutes);
        }


        if (fix.valid.speed) {
          display.setFont(&FreeSansBold18pt7b);
          display.setTextSize(1);
          display.setCursor(38, 30);
          display.println( fix.speed_mph(), 0);
        }

        //        display.setTextSize(1);
        //        display.setCursor(10, 57);
        //        if (fix.valid.location) {
        //          display.print(fix.latitude(), 4);
        //          display.print( F(", ") );
        //          display.print(fix.longitude(), 4);
      }

      display.display();
    }
  }
}

Admins: should I just tack this on to my previous thread (https://forum.arduino.cc/index.php?topic=390330.90)? Or is this ok?

marine_hm:
I can’t figure out why the sketch no-longer displays the number of satellites.

Did you get new versions of the libraries?

If you did, you need to review the NeoGPS config files. I don’t remember what your final config was, so you may need to run your sketch (to send the PMTK command), then run NMEAorder.ino to verify that you selected the correct LAST_SENTENCE (edit if necessary). Then try your sketch again.

If that doesn’t work, attach your config files so I can review them.

BTW, you don’t need to include the config files like this:

#include <NeoGPS_cfg.h>
#include <NMEAGPS_cfg.h>

The only NeoGPS include file you should use is:

#include <NMEAGPS.h>

It includes all the other files it needs.

Welcome back!

Just tried compiling that(NMEAorder.ino) with the following errors:

Arduino: 1.8.4 (Windows 7), Board: "Pro Trinket 5V/16MHz (USB)"

In file included from C:\Program Files (x86)\Arduino\libraries\NeoGPS\examples\NMEAorder\NMEAorder.ino:37:0:

C:\Users\User\Documents\Arduino\libraries\NeoGPS\src/GPSport.h:160:76: fatal error: AltSoftSerial.h: No such file or directory

   #include <AltSoftSerial.h>    // <-- DEFAULT.  Two specific pins required

                                                                            ^

compilation terminated.

Multiple libraries were found for "NMEAGPS.h"
 Used: C:\Users\User\Documents\Arduino\libraries\NeoGPS
 Not used: C:\Program Files (x86)\Arduino\libraries\NeoGPS
 Not used: C:\Program Files (x86)\Arduino\libraries\NeoGPS
 Not used: C:\Program Files (x86)\Arduino\libraries\NeoGPS
 Not used: C:\Program Files (x86)\Arduino\libraries\NeoGPS
Multiple libraries were found for "NeoSWSerial.h"
 Used: C:\Users\User\Documents\Arduino\libraries\NeoSWSerial
 Not used: C:\Program Files (x86)\Arduino\libraries\NeoSWSerial
exit status 1
Error compiling for board Pro Trinket 5V/16MHz (USB).

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

NeoGPS_cfg.h:

#ifndef NEOGPS_CFG
#define NEOGPS_CFG

//  Copyright (C) 2014-2017, SlashDevin
//
//  This file is part of NeoGPS
//
//  NeoGPS is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  NeoGPS is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with NeoGPS.  If not, see <http://www.gnu.org/licenses/>.

//------------------------------------------------------------------------
// Enable/disable packed data structures.
//
// Enabling packed data structures will use two less-portable language
// features of GCC to reduce RAM requirements.  Although it was expected to slightly increase execution time and code size, the reverse is true on 8-bit AVRs: the code is smaller and faster with packing enabled.
//
// Disabling packed data structures will be very portable to other
// platforms.  NeoGPS configurations will use slightly more RAM, and on
// 8-bit AVRs, the speed is slightly slower, and the code is slightly
// larger.  There may be no choice but to disable packing on processors 
// that do not support packed structures.
//
// There may also be compiler-specific switches that affect packing and the
// code which accesses packed members.  YMMV.

#ifdef __AVR__
  #define NEOGPS_PACKED_DATA
#endif

//------------------------------------------------------------------------
// Based on the above define, choose which set of packing macros should
// be used in the rest of the NeoGPS package.  Do not change these defines.

#ifdef NEOGPS_PACKED_DATA

  // This is for specifying the number of bits to be used for a 
  // member of a struct.  Booleans are typically one bit.
  #define NEOGPS_BF(b) :b

  // This is for requesting the compiler to pack the struct or class members
  // "as closely as possible".  This is a compiler-dependent interpretation.
  #define NEOGPS_PACKED __attribute__((packed))

#else

  // Let the compiler do whatever it wants.

  #define NEOGPS_PACKED
  #define NEOGPS_BF(b)

#endif

//------------------------------------------------------------------------
//  Accommodate C++ compiler and IDE changes.
//
//  Declaring constants as class data instead of instance data helps avoid
//  collisions with #define names, and allows the compiler to perform more
//  checks on their usage.
//
//  Until C++ 10 and IDE 1.6.8, initialized class data constants 
//  were declared like this:
//
//      static const <valued types> = <constant-value>;
//
//  Now, non-simple types (e.g., float) must be declared as
//
//      static constexpr <nonsimple-types> = <expression-treated-as-const>;
//
//  The good news is that this allows the compiler to optimize out an
//  expression that is "promised" to be "evaluatable" as a constant.
//  The bad news is that it introduces a new language keyword, and the old
//  code raises an error.
//
//  TODO: Evaluate the requirement for the "static" keyword.
//  TODO: Evaluate using a C++ version preprocessor symbol for the #if.
//
//  The CONST_CLASS_DATA define will expand to the appropriate keywords.
//

#if (ARDUINO < 10606) | ((10700 <= ARDUINO) & (ARDUINO <= 10799)) | ((107000 <= ARDUINO) & (ARDUINO <= 107999))

  #define CONST_CLASS_DATA static const
  
#else

  #define CONST_CLASS_DATA static constexpr
  
#endif

//------------------------------------------------------------------------
// The PROGMEM definitions are not correct for Zero and MKR1000

#if !defined(__AVR__)
  // TODO: use the Zero/MKR1000-specific symbols
  #undef pgm_read_ptr
  #define pgm_read_ptr(addr) (*(const void **)(addr))
#endif


#endif

NMEAGPScfg.h: I had to split the file

#ifndef NMEAGPS_CFG_H
#define NMEAGPS_CFG_H

//  Copyright (C) 2014-2017, SlashDevin
//
//  This file is part of NeoGPS
//
//  NeoGPS is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  NeoGPS is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with NeoGPS.  If not, see <http://www.gnu.org/licenses/>.

#include "GPSfix_cfg.h"

//------------------------------------------------------
// Enable/disable the parsing of specific sentences.
//
// Configuring out a sentence prevents it from being recognized; it
// will be completely ignored.  (See also NMEAGPS_RECOGNIZE_ALL, below)
//
// FYI: Only RMC and ZDA contain date information.  Other
// sentences contain time information.  Both date and time are 
// required if you will be doing time_t-to-clock_t operations.

#define NMEAGPS_PARSE_GGA
//#define NMEAGPS_PARSE_GLL
//#define NMEAGPS_PARSE_GSA
//#define NMEAGPS_PARSE_GSV
//#define NMEAGPS_PARSE_GST
#define NMEAGPS_PARSE_RMC
//#define NMEAGPS_PARSE_VTG
//#define NMEAGPS_PARSE_ZDA

//------------------------------------------------------
// Select which sentence is sent *last* by your GPS device
// in each update interval.  This can be used by your sketch
// to determine when the GPS quiet time begins, and thus
// when you can perform "some" time-consuming operations.

#define LAST_SENTENCE_IN_INTERVAL NMEAGPS::NMEA_RMC

// NOTE: For PUBX-only configs, use
//          (NMEAGPS::nmea_msg_t)(NMEAGPS::NMEA_LAST_MSG+1)
//
// If the NMEA_LAST_SENTENCE_IN_INTERVAL is not chosen 
// correctly, GPS data may be lost because the sketch
// takes too long elsewhere when this sentence is received.
// Also, fix members may contain information from different 
// time intervals (i.e., they are not coherent).
//
// If you don't know which sentence is the last one,
// use NMEAorder.ino to list them.  You do not have to select
// the last sentence the device sends if you have disabled
// it.  Just select the last sentence that you have *enabled*.

//------------------------------------------------------
// Choose how multiple sentences are merged into a fix:
//   1) No merging
//        Each sentence fills out its own fix; there could be 
//        multiple sentences per interval.
//   2) EXPLICIT_MERGING
//        All sentences in an interval are *safely* merged into one fix.
//        NMEAGPS_FIX_MAX must be >= 1.
//        An interval is defined by NMEA_LAST_SENTENCE_IN_INTERVAL.
//   3) IMPLICIT_MERGING
//        All sentences in an interval are merged into one fix, with 
//        possible data loss.  If a received sentence is rejected for 
//        any reason (e.g., a checksum error), all the values are suspect.
//        The fix will be cleared; no members will be valid until new 
//        sentences are received and accepted.  This uses less RAM.
//        An interval is defined by NMEA_LAST_SENTENCE_IN_INTERVAL.
// Uncomment zero or one:

#define NMEAGPS_EXPLICIT_MERGING
//#define NMEAGPS_IMPLICIT_MERGING

#ifdef NMEAGPS_IMPLICIT_MERGING
  #define NMEAGPS_MERGING NMEAGPS::IMPLICIT_MERGING

  // Nothing is done to the fix at the beginning of every sentence...
  #define NMEAGPS_INIT_FIX(m)

  // ...but we invalidate one part when it starts to get parsed.  It *may* get
  // validated when the parsing is finished.
  #define NMEAGPS_INVALIDATE(m) m_fix.valid.m = false

#else

  #ifdef NMEAGPS_EXPLICIT_MERGING
    #define NMEAGPS_MERGING NMEAGPS::EXPLICIT_MERGING
  #else
    #define NMEAGPS_MERGING NMEAGPS::NO_MERGING
    #define NMEAGPS_NO_MERGING
  #endif

  // When NOT accumulating (not IMPLICIT), invalidate the entire fix 
  // at the beginning of every sentence...
  #define NMEAGPS_INIT_FIX(m) m.valid.init()

  // ...so the individual parts do not need to be invalidated as they are parsed
  #define NMEAGPS_INVALIDATE(m)

#endif

#if ( defined(NMEAGPS_NO_MERGING) + \
    defined(NMEAGPS_IMPLICIT_MERGING) + \
    defined(NMEAGPS_EXPLICIT_MERGING) )  > 1
  #error Only one MERGING technique should be enabled in NMEAGPS_cfg.h!
#endif

//------------------------------------------------------
// Define the fix buffer size.  The NMEAGPS object will hold on to
// this many fixes before an overrun occurs.  This can be zero,
// but you have to be more careful about using gps.fix() structure,
// because it will be modified as characters are received.

#define NMEAGPS_FIX_MAX 1

#if defined(NMEAGPS_EXPLICIT_MERGING) && (NMEAGPS_FIX_MAX == 0)
  #error You must define FIX_MAX >= 1 to allow EXPLICIT merging in NMEAGPS_cfg.h
#endif

//------------------------------------------------------
// Define how fixes are dropped when the FIFO is full.
//   true  = the oldest fix will be dropped, and the new fix will be saved.
//   false = the new fix will be dropped, and all old fixes will be saved.

#define NMEAGPS_KEEP_NEWEST_FIXES true

//------------------------------------------------------
// Enable/Disable interrupt-style processing of GPS characters
// If you are using one of the NeoXXSerial libraries,
//   to attachInterrupt, this must be defined.
// Otherwise, it must be commented out.

//#define NMEAGPS_INTERRUPT_PROCESSING

#ifdef  NMEAGPS_INTERRUPT_PROCESSING
  #define NMEAGPS_PROCESSING_STYLE NMEAGPS::PS_INTERRUPT
#else
  #define NMEAGPS_PROCESSING_STYLE NMEAGPS::PS_POLLING
#endif

//------------------------------------------------------
// Enable/disable the talker ID, manufacturer ID and proprietary message processing.
//
// First, some background information.  There are two kinds of NMEA sentences:
//
// 1. Standard NMEA sentences begin with "$ttccc", where
//      "tt" is the talker ID, and
//      "ccc" is the variable-length sentence type (i.e., command).
//
//    For example, "$GPGLL,..." is a GLL sentence (Geographic Lat/Long) 
//    transmitted by talker "GP".  This is the most common talker ID.  Some
//    devices may report "$GNGLL,..." when a mix of GPS and non-GPS
//    satellites have been used to determine the GLL data.
//
// 2. Proprietary NMEA sentences (i.e., those unique to a particular
//    manufacturer) begin with "$Pmmmccc", where
//      "P" is the NMEA-defined prefix indicator for proprietary messages,
//      "mmm" is the 3-character manufacturer ID, and
//      "ccc" is the variable-length sentence type (it can be empty).
//
// No validation of manufacturer ID and talker ID is performed in this
// base class.  For example, although "GP" is a common talker ID, it is not
// guaranteed to be transmitted by your particular device, and it IS NOT
// REQUIRED.  If you need validation of these IDs, or you need to use the
// extra information provided by some devices, you have two independent
// options:
//

Second half…

// 1. Enable SAVING the ID: When /decode/ returns DECODE_COMPLETED, the
// /talker_id/ and/or /mfr_id/ members will contain ID bytes.  The entire
// sentence will be parsed, perhaps modifying members of /fix/.  You should
// enable one or both IDs if you want the information in all sentences *and*
// you also want to know the ID bytes.  This adds two bytes of RAM for the
// talker ID, and 3 bytes of RAM for the manufacturer ID.
//
// 2. Enable PARSING the ID:  The virtual /parse_talker_id/ and
// /parse_mfr_id/ will receive each ID character as it is parsed.  If it
// is not a valid ID, return /false/ to abort processing the rest of the
// sentence.  No CPU time will be wasted on the invalid sentence, and no
// /fix/ members will be modified.  You should enable this if you want to
// ignore some IDs.  You must override /parse_talker_id/ and/or
// /parse_mfr_id/ in a derived class.
//

//#define NMEAGPS_SAVE_TALKER_ID
//#define NMEAGPS_PARSE_TALKER_ID

//#define NMEAGPS_PARSE_PROPRIETARY
#ifdef NMEAGPS_PARSE_PROPRIETARY
  //#define NMEAGPS_SAVE_MFR_ID
  #define NMEAGPS_PARSE_MFR_ID
#endif

//------------------------------------------------------
// Enable/disable tracking the current satellite array and,
// optionally, all the info for each satellite.
//

//#define NMEAGPS_PARSE_SATELLITES
//#define NMEAGPS_PARSE_SATELLITE_INFO

#ifdef NMEAGPS_PARSE_SATELLITES
  #define NMEAGPS_MAX_SATELLITES (20)

  #ifndef GPS_FIX_SATELLITES
    #error GPS_FIX_SATELLITES must be defined in GPSfix.h!
  #endif

#endif

#if defined(NMEAGPS_PARSE_SATELLITE_INFO) & \
    !defined(NMEAGPS_PARSE_SATELLITES)
  #error NMEAGPS_PARSE_SATELLITES must be defined!
#endif

//------------------------------------------------------
// Enable/disable gathering interface statistics:
// CRC errors and number of sentences received

#define NMEAGPS_STATS

//------------------------------------------------------
// Configuration item for allowing derived types of NMEAGPS.
// If you derive classes from NMEAGPS, you *must* define NMEAGPS_DERIVED_TYPES.
// If not defined, virtuals are not used, with a slight size (2 bytes) and 
// execution time savings.

//#define NMEAGPS_DERIVED_TYPES

#ifdef NMEAGPS_DERIVED_TYPES
  #define NMEAGPS_VIRTUAL virtual
#else
  #define NMEAGPS_VIRTUAL
#endif

//-----------------------------------
// See if DERIVED_TYPES is required
#if (defined(NMEAGPS_PARSE_TALKER_ID) | defined(NMEAGPS_PARSE_MFR_ID)) &  \
           !defined(NMEAGPS_DERIVED_TYPES)
  #error You must define NMEAGPS_DERIVED_TYPES in NMEAGPS.h in order to parse Talker and/or Mfr IDs!
#endif

//------------------------------------------------------
//  Becase the NMEA checksum is not very good at error detection, you can 
//    choose to enable additional validity checks.  This trades a little more 
//    code and execution time for more reliability.
//
//  Validation at the character level is a syntactic check only.  For 
//    example, integer fields must contain characters in the range 0..9, 
//    latitude hemisphere letters can be 'N' or 'S'.  Characters that are not 
//    valid for a particular field will cause the entire sentence to be 
//    rejected as an error, *regardless* of whether the checksum would pass.
#define NMEAGPS_VALIDATE_CHARS false

//  Validation at the field level is a semantic check.  For 
//    example, latitude degrees must be in the range -90..+90.
//    Values that are not valid for a particular field will cause the 
//    entire sentence to be rejected as an error, *regardless* of whether the 
//    checksum would pass.
#define NMEAGPS_VALIDATE_FIELDS false

//------------------------------------------------------
// Some devices may omit trailing commas at the end of some 
// sentences.  This may prevent the last field from being 
// parsed correctly, because the parser for some types keep 
// the value in an intermediate state until the complete 
// field is received (e.g., parseDDDMM, parseFloat and 
// parseZDA).
//
// Enabling this will inject a simulated comma when the end 
// of a sentence is received and the last field parser 
// indicated that it still needs one.

#define NMEAGPS_COMMA_NEEDED

//------------------------------------------------------
//  Some applications may want to recognize a sentence type
//  without actually parsing any of the fields.  Uncommenting
//  this define will allow the nmeaMessage member to be set
//  when *any* standard message is seen, even though that 
//  message is not enabled by a NMEAGPS_PARSE_xxx define above.
//  No valid flags will be true for those sentences.

#define NMEAGPS_RECOGNIZE_ALL

//------------------------------------------------------
// Sometimes, a little extra space is needed to parse an intermediate form.
// This config items enables extra space.

//#define NMEAGPS_PARSING_SCRATCHPAD

//------------------------------------------------------
// If you need to know the exact UTC time at *any* time,
//   not just after a fix arrives, you must calculate the
//   offset between the Arduino micros() clock and the UTC 
//   time in a received fix.  There are two ways to do this:
//
// 1) When the GPS quiet time ends and the new update interval begins.  
//    The timestamp will be set when the first character (the '

) of
//    the new batch of sentences arrives from the GPS device.  This is fairly
//    accurate, but it will be delayed from the PPS edge by the GPS device’s
//    fix calculation time (usually ~100us).  There is very little variance
//    in this calculation time (usually < 30us), so all timestamps are
//    delayed by a nearly-constant amount.
//
//    NOTE:  At update rates higher than 1Hz, the updates may arrive with
//    some increasing variance.

//#define NMEAGPS_TIMESTAMP_FROM_INTERVAL

// 2) From the PPS pin of the GPS module.  It is up to the application
//    developer to decide how to capture that event.  For example, you could:
//
//    a) simply poll for it in loop and call UTCsecondStart(micros());
//    b) use attachInterrupt to call a Pin Change Interrupt ISR to save
//       the micros() at the time of the interrupt (see NMEAGPS.h), or
//    c) connect the PPS to an Input Capture pin.  Set the
//       associated TIMER frequency, calculate the elapsed time
//       since the PPS edge, and add that to the current micros().

//#define NMEAGPS_TIMESTAMP_FROM_PPS

#if defined( NMEAGPS_TIMESTAMP_FROM_INTERVAL ) &  
   defined( NMEAGPS_TIMESTAMP_FROM_PPS )
 #error You cannot enable both TIMESTAMP_FROM_INTERVAL and PPS in NMEAGPS_cfg.h!
#endif

#endif

Thank you BTW for helping me. I was able to track the boat's movement. I took readings three times a day. MOST gratifying! Laughing at the map company. The only legend for distance was 1"=3.# million inches. I had to make my own line and do the math for miles/inch. Then drew a six-inch line with 1-inch increments.

-dev:
Did you get new versions of the libraries?

Just downloaded the latest version-> GitHub - SlashDevin/NeoGPS: NMEA and ublox GPS parser for Arduino, configurable to use as few as 10 bytes of RAM

Replaced the folder with the new library.

marine_hm:
Just tried compiling that(NMEAorder.ino) with the following errors:

Arduino: 1.8.4 (Windows 7), Board: "Pro Trinket 5V/16MHz (USB)"

In file included from C:\Program Files (x86)\Arduino\libraries\NeoGPS\examples\NMEAorder\NMEAorder.ino:37:0:

fatal error: AltSoftSerial.h: No such file or directory

#include <AltSoftSerial.h>    // ← DEFAULT.  Two specific pins required

compilation terminated.

I didn’t want you to get a new version. I was asking if you were trying to use a new version. :frowning: Well, since you have a new version now…

AltSoftSerial is the new default port for the NeoGPS examples. You have to edit GPSport.h to specify which port you want them all to use if the GPS is not connected to the AltSoftSerial pins. In your case, you should have this in Arduino/Libraries/NeoGPS/src/GPSport.h:

#ifndef GPSport_h
#define GPSport_h

#include <NeoSWSerial.h>
NeoSWSerial gpsPort(4, 3);  // ASSIGNS PINS 3, 4 FOR GPS RX/TX (slightly different name!)

#define GPS_PORT_NAME "NeoSWSerial(4,3)"
#define DEBUG_PORT NeoSerial

#endif

Then NMEAorder should build, upload and listen to the GPS on pins 4 and 3.

The NMEAGPS_cfg file you embedded shows that the program expected RMC and GGA sentences, with RMC selected as the LAST_SENTENCE. That seems ok, but you have to confirm it with NMEAorder. That file is from a fairly recent version of NeoGPS.

I had to split the file

LOL, I guess you’ve never used the Attachments and other options in the lower-left corner of the full post editor (appears after you Preview the Quick Reply at the bottom of this page). Please attach NMEAGPS_cfg.h and GPSfix_cfg.h to your next post. I do not need to see NeoGPS_cfg.h.

Now that you have a new version, you should verify that it still does not a satellite count.

Here are the 2 files you requested(attached). Thanks

Nick

GPSfix_cfg.h (1.61 KB)

NMEAGPS_cfg.h (13.6 KB)

Wow, that sketch was pretty old. The new way of getting a fix from the gps object is to call gps.read(), not gps.fix(). With the old code, it was always using just the RMC, which does not have the fix.satellites value.

Here is your sketch with that mod:

/*
   Motorcycle (GPS) Speedometer
*/


#include <TinyWireM.h>
#include <USI_TWI_Master.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>
#include <Fonts/FreeSansBold18pt7b.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <NeoSWSerial.h>

NeoSWSerial gps_port(4, 3);  // ASSIGNS PINS 3, 4 FOR GPS RX/TX

#include <NMEAGPS.h>

static NMEAGPS  gps; // This parses the GPS characters

// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


void setup() {

  gps_port.begin(9600);

  // request RMC and GGA only
  gps_port.println( F("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28") );

  display.begin(SSD1306_SWITCHCAPVCC);

  display.clearDisplay();
  display.setFont(&FreeSerif9pt7b);
  //display.setTextSize(1);

  display.setTextColor(WHITE);
  display.setCursor(27, 22);
  display.println( F("Mini-GPS"));
  display.display(); // SEND SPLASH SCREEN
  delay(2000);       // WAIT 2 SECONDS

  display.clearDisplay();
  display.setFont(&FreeSerif9pt7b);
  //display.setTextSize(0.8);
  display.setCursor(55, 12);
  display.print( F("By"));


  display.setTextSize(0.8);
  display.setCursor(15, 26);
  display.print( F("Nick Sebring"));
  display.display(); // SEND SPLASH SCREEN
  delay(5000);       // WAIT 10 SECONDS


  //  Insert text when no GPS signal received... ***********************
  //display.clearDisplay();
  //display.setCursor(2, 50);
  //display.print( F("Serching satellites."));
  //display.display(); // SEND SPLASH SCREEN
}



void loop()
{

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

    display.clearDisplay(); //CLEAR THE OLED BUFFER, THUS CLEARING THE SCREEN:  GOT IT!

    //  construct data to be sent to the OLED *****************************

    display.setFont();  //reset font to default

    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0, 0);
    display.print( F("Sat: "));

    if (fix.valid.satellites) {
      display.setCursor(60, 20);
      display.println( fix.satellites );
    }

    if (fix.valid.date && fix.valid.time) {
      NeoGPS::clock_t seconds = (NeoGPS::clock_t) fix.dateTime;     // convert pieces to seconds

      // Calculate DST changeover times just once per year
      static NeoGPS::clock_t springTime, fallTime;
      static NeoGPS::time_t  changeover;

      if ((springTime == 0) || (changeover.year != fix.dateTime.year)) {

        changeover.year    = fix.dateTime.year;
        changeover.month   = 3;
        changeover.date    = 14; // latest 2nd Sunday
        changeover.hours   = 2;
        changeover.minutes = 0;
        changeover.seconds = 0;
        changeover.set_day();
        // Step back to the 2nd Sunday, if day != SUNDAY
        changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
        springTime = (NeoGPS::clock_t) changeover;

        changeover.month   = 11;
        changeover.date    = 7; // latest 1st Sunday
        changeover.set_day();
        // Step back to the 1st Sunday, if day != SUNDAY
        changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
        fallTime = (NeoGPS::clock_t) changeover;
      }

      NeoGPS::clock_t tz = 5;  //  THIS IS WHERE YOU PUT IN YOUR LOCAL TIME ZONE
      if ((springTime <= seconds) && (seconds < fallTime))
        tz--;
      seconds -= tz * 60 * 60;                    // offset seconds to local timezone, including DST
      NeoGPS::time_t localTime( seconds );        // convert seconds back to pieces

      display.setCursor(95, 0);
      if (localTime.hours < 10) {
        display.print( '0' );
      }
      display.print( localTime.hours ); display.print( ':' ); // use pieces
      if (localTime.minutes < 10) {
        display.print( '0' );
      }
      display.print( localTime.minutes);
    }


    if (fix.valid.speed) {
      display.setFont(&FreeSansBold18pt7b);
      display.setTextSize(1);
      display.setCursor(38, 30);
      display.println( fix.speed_mph(), 0);
    }

    //        display.setTextSize(1);
    //        display.setCursor(10, 57);
    //        if (fix.valid.location) {
    //          display.print(fix.latitude(), 4);
    //          display.print( F(", ") );
    //          display.print(fix.longitude(), 4);

    display.display();
  }
}

It compiles for me, but I could only test a version without the display code.

Cheers,
/dev

Retyping it out, I'll have a better appreciation of your hard work.

Thank you sir! That worked great. I had some issues where I miss typed a line and misplaced a bracket but I got it.

I can't thank you enough. Now I need to update my other sketches

Nick

/dev

Just curious. Looking back at when I first started this project. I noticed a slight change in serial data speed:

Last year:
// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
Serial.begin(115200);

Now:
gps_port.begin(9600);

Are they two different things? My understanding is that this is the speed at which the Pro Trinket communicates with the GPS receiver.

If they are different, can you explain the difference?

Thanks.

Last year:
// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
Serial.begin(115200);

Now:
gps_port.begin(9600);

Are they two different things?

Yes. Serial is for printing debug messages to the Serial Monitor window (you can pick any baud rate, as long the Serial.begin number matches the choice in the Serial Monitor window). gps_port is for reading characters from the GPS device (usually 9600, but you can send commands to change its baud rate).

Other GPS libraries (and their examples) do not coordinate the sketch with the GPS quiet time. It is very common for those sketches to print too much information, use delay, or test if just one GPS field has updated. This causes them to lose GPS characters.

Your first sketch used Adafruit_GPS. It tries to work around the problem by printingreallyfast (to Serial @ 115200), in the hopes that the printing will complete before the sketch loses GPS characters. It doesn’t always work, especially when users modify their example. :-/

Since you are using the correct loop structure (as encouraged by the NeoGPS examples), you do not have to worry about the Serial baud rate. You don’t even print debug messages, so there’s no reason to start the Serial port. This saves some RAM and program space, too.

BTW, you don’t need these includes for the Pro Trinket:

    #include <TinyWireM.h>
    #include <USI_TWI_Master.h>

Cheers,
/dev