GPS Neo-M6 with Adafruit or NEO GPS library

Hi,

I really like the way Paul McWorther sets up his Adafruit GPS sensor in this tutorial.

Mainly because he only parses 2 NMEA strings instead of all other thing that you might not need.

However, I do not have an Adafruit but a NEO-M6.

I tried the Adafruit library but my Neo ignores commands like this:

GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);

So, I went searching for other libraries but NEO GPS is very complex (doesnt even compile with Nano/Uno, how much I google or search for documents.

With TinyGPS++ I cant find the option like adafruit has.

What I would like is as little information as needed:

Location
speed
(Maybe time because of speed calc)

I already tried various examples from the lib's.

What can you recommend I use and how? (it has to be logged), Just like HERE

The TinyGPS++ library example UseCustomFields shows how to get particular data from the NEO 6M GPS.

But I think it still reads all the sentences. I have used the Ublox Ucenter utility to change which sentences are transmitted. Some other libraries (NeoGPS?) allows you to set which sentences are read.

NEO GPS should but I cant get it to compile :frowning:

Sareno:
NEO GPS should but I cant get it to compile :frowning:

Please post "it" and the full text of the error messages

Just fresh install?!

Arduino: 1.8.10 (Windows 7), Board: "Arduino Nano, ATmega328P"

Multiple libraries were found for "NeoGPS_cfg.h"
Used: \Arduino\libraries\NeoGPS-master
In file included from Documents\Arduino\libraries\NeoGPS-master\examples\ublox\ublox.ino:43:0:

\Arduino\libraries\NeoGPS-master\src/GPSport.h:160:12: fatal error: AltSoftSerial.h: No such file or directory

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

^~~~~~~~~~~~~~~~~

compilation terminated.

exit status 1
Error compiling for board Arduino Nano.

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

#include <NeoGPS_cfg.h>
#include <ublox/ubxGPS.h>



#include <GPSport.h>

#include <Streamers.h>

//------------------------------------------------------------
// Check that the config files are set up properly

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

#if !defined(UBLOX_PARSE_STATUS)  & !defined(UBLOX_PARSE_TIMEGPS) & \
    !defined(UBLOX_PARSE_TIMEUTC) & !defined(UBLOX_PARSE_POSLLH)  & \
    !defined(UBLOX_PARSE_DOP)     & !defined(UBLOX_PARSE_PVT)     & \
    !defined(UBLOX_PARSE_VELNED)  & !defined(UBLOX_PARSE_SVINFO)  & \
    !defined(UBLOX_PARSE_HNR_PVT)

  #error No UBX binary messages enabled: no fix data available.

#endif

#ifndef NMEAGPS_RECOGNIZE_ALL
  //  Resetting the messages with ublox::configNMEA requires that
  //    all message types are recognized (i.e., the enum has all
  //    values).
  #error You must "#define NMEAGPS_RECOGNIZE_ALL" in NMEAGPS_cfg.h!
#endif

//-----------------------------------------------------------------
//  Derive a class to add the state machine for starting up:
//    1) The status must change to something other than NONE.
//    2) The GPS leap seconds must be received
//    3) The UTC time must be received
//    4) All configured messages are "requested"
//         (i.e., "enabled" in the ublox device)
//  Then, all configured messages are parsed and explicitly merged.

class MyGPS : public ubloxGPS
{
public:

    enum
      {
        GETTING_STATUS, 
        GETTING_LEAP_SECONDS, 
        GETTING_UTC, 
        RUNNING
      }
        state NEOGPS_BF(8);

    MyGPS( Stream *device ) : ubloxGPS( device )
    {
      state = GETTING_STATUS;
    }

    //--------------------------

    void get_status()
    {
      static bool acquiring = false;

      if (fix().status == gps_fix::STATUS_NONE) {
        static uint32_t dotPrint;
        bool            requestNavStatus = false;

        if (!acquiring) {
          acquiring = true;
          dotPrint = millis();
          DEBUG_PORT.print( F("Acquiring...") );
          requestNavStatus = true;

        } else if (millis() - dotPrint > 1000UL) {
          dotPrint = millis();
          DEBUG_PORT << '.';

          static uint8_t requestPeriod;
          if ((++requestPeriod & 0x07) == 0)
            requestNavStatus = true;
        }

        if (requestNavStatus)
          // Turn on the UBX status message
          enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_STATUS );

      } else {
        if (acquiring)
          DEBUG_PORT << '\n';
        DEBUG_PORT << F("Acquired status: ") << (uint8_t) fix().status << '\n';

        #if defined(GPS_FIX_TIME) & defined(GPS_FIX_DATE) & \
            defined(UBLOX_PARSE_TIMEGPS)

          if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEGPS ))
            DEBUG_PORT.println( F("enable TIMEGPS failed!") );

          state = GETTING_LEAP_SECONDS;
        #else
          start_running();
          state = RUNNING;
        #endif
      }
    } // get_status

    //--------------------------
 void get_leap_seconds()
    {
      #if defined(GPS_FIX_TIME) & defined(GPS_FIX_DATE) & \
          defined(UBLOX_PARSE_TIMEGPS)

        if (GPSTime::leap_seconds != 0) {
          DEBUG_PORT << F("Acquired leap seconds: ") << GPSTime::leap_seconds << '\n';

          if (!disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEGPS ))
            DEBUG_PORT.println( F("disable TIMEGPS failed!") );

          #if defined(UBLOX_PARSE_TIMEUTC)
            if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC ))
              DEBUG_PORT.println( F("enable TIMEUTC failed!") );
            state = GETTING_UTC;
          #else
            start_running();
          #endif
        }
      #endif

    } // get_leap_seconds

    //--------------------------

    void get_utc()
    {
      #if defined(GPS_FIX_TIME) & defined(GPS_FIX_DATE) & \
          defined(UBLOX_PARSE_TIMEUTC)

        lock();
          bool            safe = is_safe();
          NeoGPS::clock_t sow  = GPSTime::start_of_week();
          NeoGPS::time_t  utc  = fix().dateTime;
        unlock();

        if (safe && (sow != 0)) {
          DEBUG_PORT << F("Acquired UTC: ") << utc << '\n';
          DEBUG_PORT << F("Acquired Start-of-Week: ") << sow << '\n';

          start_running();
        }
      #endif

    } // get_utc

    //--------------------------

    void start_running()
    {
      bool enabled_msg_with_time = false;

      #if defined(UBLOX_PARSE_POSLLH)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_POSLLH ))
          DEBUG_PORT.println( F("enable POSLLH failed!") );

        enabled_msg_with_time = true;
      #endif

      #if defined(UBLOX_PARSE_PVT)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_PVT ))
          DEBUG_PORT.println( F("enable PVT failed!") );

        enabled_msg_with_time = true;
      #endif

      #if defined(UBLOX_PARSE_VELNED)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_VELNED ))
          DEBUG_PORT.println( F("enable VELNED failed!") );

        enabled_msg_with_time = true;
      #endif

      #if defined(UBLOX_PARSE_DOP)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_DOP ))
          DEBUG_PORT.println( F("enable DOP failed!") );
        else
          DEBUG_PORT.println( F("enabled DOP.") );

        enabled_msg_with_time = true;
      #endif

      #if defined(UBLOX_PARSE_SVINFO)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_SVINFO ))
          DEBUG_PORT.println( F("enable SVINFO failed!") );
        
        enabled_msg_with_time = true;
      #endif

      #if defined(UBLOX_PARSE_TIMEUTC)

        #if defined(GPS_FIX_TIME) & defined(GPS_FIX_DATE)
          if (enabled_msg_with_time &&
              !disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC ))
            DEBUG_PORT.println( F("disable TIMEUTC failed!") );

        #elif defined(GPS_FIX_TIME) | defined(GPS_FIX_DATE)
          // If both aren't defined, we can't convert TOW to UTC,
          // so ask for the separate UTC message.
          if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC ))
            DEBUG_PORT.println( F("enable TIMEUTC failed!") );
        #endif

      #endif

      state = RUNNING;
      trace_header( DEBUG_PORT );

    } // start_running

    //--------------------------

    bool running()
    {
      switch (state) {
        case GETTING_STATUS      : get_status      (); break;
        case GETTING_LEAP_SECONDS: get_leap_seconds(); break;
        case GETTING_UTC         : get_utc         (); break;
      }

      return (state == RUNNING);

    } // running

} NEOGPS_PACKED;

// Construct the GPS object and hook it to the appropriate serial device
static MyGPS gps( &gpsPort );

#ifdef NMEAGPS_INTERRUPT_PROCESSING
  static void GPSisr( uint8_t c )
  {
    gps.handle( c );
  }
#endif

//--------------------------

static void configNMEA( uint8_t rate )
{
  for (uint8_t i=NMEAGPS::NMEA_FIRST_MSG; i<=NMEAGPS::NMEA_LAST_MSG; i++) {
    ublox::configNMEA( gps, (NMEAGPS::nmea_msg_t) i, rate );
  }
}

//--------------------------

static void disableUBX()
{
  gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEGPS );
  gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC );
  gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_VELNED );
  gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_POSLLH );
  gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_DOP );
}

//--------------------------

void setup()
{
  // Start the normal trace output
  DEBUG_PORT.begin(9600);
  while (!DEBUG_PORT)
    ;

  DEBUG_PORT.print( F("ublox binary protocol example started.\n") );
  DEBUG_PORT << F("fix object size = ") << sizeof(gps.fix()) << '\n';
  DEBUG_PORT << F("ubloxGPS object size = ") << sizeof(ubloxGPS) << '\n';
  DEBUG_PORT << F("MyGPS object size = ") << sizeof(gps) << '\n';
  DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME) );
  DEBUG_PORT.flush();

  // Start the UART for the GPS device
  #ifdef NMEAGPS_INTERRUPT_PROCESSING
    gpsPort.attachInterrupt( GPSisr );
  #endif
  gpsPort.begin(9600);

  // Turn off the preconfigured NMEA standard messages
  configNMEA( 0 );

  // Turn off things that may be left on by a previous build
  disableUBX();

  #if 0
    // Test a Neo M8 message -- should be rejected by Neo-6 and Neo7
    ublox::cfg_nmea_v1_t test;

    test.always_output_pos  = false; // invalid or failed
    test.output_invalid_pos = false;
    test.output_invalid_time= false;
    test.output_invalid_date= false;
    test.use_GPS_only       = false;
    test.output_heading     = false; // even if frozen
    test.__not_used__       = false;

    test.nmea_version = ublox::cfg_nmea_v1_t::NMEA_V_4_0;
    test.num_sats_per_talker_id = ublox::cfg_nmea_v1_t::SV_PER_TALKERID_UNLIMITED;

    test.compatibility_mode = false;
    test.considering_mode   = true;
    test.max_line_length_82 = false;
    test.__not_used_1__     = 0;

    test.filter_gps    = false;
    test.filter_sbas   = false;
    test.__not_used_2__= 0;
    test.filter_qzss   = false;
    test.filter_glonass= false;
    test.filter_beidou = false;
    test.__not_used_3__= 0;

    test.proprietary_sat_numbering = false;
    test.main_talker_id = ublox::cfg_nmea_v1_t::MAIN_TALKER_ID_GP;
    test.gsv_uses_main_talker_id = true;
    test.beidou_talker_id[0] = 'G';
    test.beidou_talker_id[1] = 'P';

    DEBUG_PORT << F("CFG_NMEA result = ") << gps.send( test );
  #endif

  while (!gps.running())
    if (gps.available( gpsPort ))
      gps.read();
}

//--------------------------

void loop()
{
  if (gps.available( gpsPort ))
    trace_all( DEBUG_PORT, gps, gps.read() );

  // If the user types something, reset the message configuration
  //   back to a normal set of NMEA messages.  This makes it
  //   convenient to switch to another example program that
  //   expects a typical set of messages.  This also saves
  //   putting those config messages in every other example.

  if (DEBUG_PORT.available()) {
    do { DEBUG_PORT.read(); } while (DEBUG_PORT.available());
    DEBUG_PORT.println( F("Stopping...") );

    configNMEA( 1 );
    disableUBX();
    gpsPort.flush();
    gpsPort.end();

    DEBUG_PORT.println( F("STOPPED.") );
    for (;;);
  }
}

Now with Show Verbose

Arduino: 1.8.10 (Windows 7), Board: "Arduino Nano, ATmega328P"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Sander\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328 -ide-version=10810 -build-path C:\Users\Sander\AppData\Local\Temp\arduino_build_947224 -warnings=none -build-cache C:\Users\Sander\AppData\Local\Temp\arduino_cache_395899 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Sander\Documents\Arduino\libraries\NeoGPS-master\examples\ublox\ublox.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Sander\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328 -ide-version=10810 -build-path C:\Users\Sander\AppData\Local\Temp\arduino_build_947224 -warnings=none -build-cache C:\Users\Sander\AppData\Local\Temp\arduino_cache_395899 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Sander\Documents\Arduino\libraries\NeoGPS-master\examples\ublox\ublox.ino
Using board 'nano' from platform in folder: C:\Program
Using core 'arduino' from platform in folder: C:\Program
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "C:\Users\Sander\AppData\Local\Temp\arduino_build_947224\sketch\ublox.ino.cpp" -o nul
Alternatives for NeoGPS_cfg.h: [NeoGPS-master@4.2.9]
ResolveLibrary(NeoGPS_cfg.h)
-> candidates: [NeoGPS-master@4.2.9]
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "-IC:\Users\Sander\Documents\Arduino\libraries\NeoGPS-master\src" "C:\Users\Sander\AppData\Local\Temp\arduino_build_947224\sketch\ublox.ino.cpp" -o nul
Alternatives for AltSoftSerial.h: []
ResolveLibrary(AltSoftSerial.h)
-> candidates: []
In file included from C:\Users\Sander\Documents\Arduino\libraries\NeoGPS-master\examples\ublox\ublox.ino:43:0:

\Arduino\libraries\NeoGPS-master\src/GPSport.h:160:12: fatal error: AltSoftSerial.h: No such file or directory

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

^~~~~~~~~~~~~~~~~

compilation terminated.

Multiple libraries were found for "NeoGPS_cfg.h"
Used: \Documents\Arduino\libraries\NeoGPS-master
Using library NeoGPS-master at version 4.2.9 in folder: \Documents\Arduino\libraries\NeoGPS-master
exit status 1
Error compiling for board Arduino Nano.

Browsing and browsing.. Found this:

https://forum.arduino.cc/index.php?topic=346555.0

I'll dig through that one later on.

Sareno:
However, I do not have an Adafruit but a NEO-M6.

I tried the Adafruit library but my Neo ignores commands like this:

GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);

One of the symptoms of a fake Ublox GPS is that it does not accept the Ublox commands.

srnet:
One of the symptoms of a fake Ublox GPS is that it does not accept the Ublox commands.

Bold Statement. How can I check if it is fake? I bought it locally in a shop.

But, should a neo accept adafruit commands?

Sareno:
Bold Statement.

Not bold at all, like I said its a symptom;

https://portal.u-blox.com/s/question/0D52p00008JMr32CAD/cant-seem-to-change-the-settings-of-neo6m-module-using-ucenter-1901

The Adafruit software of course just uses the Ublox commands ............................

Ok, I will do a check.

If mine is fake, is it useless for GPS tracking/logging?

What kind should I buy?

Sareno:
If mine is fake, is it useless for GPS tracking/logging?

You would need to check its reliably giving the correct postion.

\Arduino\libraries\NeoGPS-master\src/GPSport.h:160:12: fatal error: AltSoftSerial.h: No such file or directory

You need to install the AltSoftSerial library.

I've got NeoGPS working, after a lot of reading and googling.

I know that the author is a member of this forum and being a starter, I reaaally would like to ask him some questions. A lot of text that is quite stiff for a beginner, I wish I could delete 99% of it (and yes, that should be possible).

Bit afraid I messed up IDE by now by installing al those new libs.

BTW, is SDFat better than the standard SD support?

Yes, SDFat is better.

CrossRoads:
Yes, SDFat is better.

Might be true but certainly not right out of the box.

I do learn a lot from this but neither NEO or SD fat work out of the box.

neither NEO or SD fat work out of the box.

What do you mean by that ?

UKHeliBob:
What do you mean by that ?

NEOGPS required a lot of reading to do some configurations in the config files. You have to manually enable/disable certain software serial ports etc. On the other hand, in the examples he uses quite a bit of advanced coding and since there are no tutorials to be found, it is hard.

SDFat is also hard to get. I am used to set my on Chipselect pin. It took me a while to find out that SDFat requires pin 10 to be CS. I cannot find where to change that.