SlashDevin / NeoGPS

NMEA and ublox GPS parser for Arduino, configurable to use as few as 10 bytes of RAM
GNU General Public License v3.0
709 stars 195 forks source link

Ublox.ino compile errors on Mega 2560 #11

Closed mjs513 closed 7 years ago

mjs513 commented 7 years ago

Getting the following errors during compile:

Arduino: 1.6.10 (Windows 10), TD: 1.30-beta3, Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Users\CyberPalin\Documents\Arduino\libraries\NeoGPS-master\ubxGPS.cpp: In member function 'bool ubloxGPS::parseNavPosLLH(uint8_t)':

C:\Users\CyberPalin\Documents\Arduino\libraries\NeoGPS-master\ubxGPS.cpp:597:11: error: 'U1' was not declared in this scope

       U1[ chrCount-20 ] = chr;

       ^

C:\Users\CyberPalin\Documents\Arduino\libraries\NeoGPS-master\ubxGPS.cpp:599:31: error: 'U4' was not declared in this scope

         uint16_t err_cm = U4/100;

                           ^

C:\Users\CyberPalin\Documents\Arduino\libraries\NeoGPS-master\ubxGPS.cpp:620:32: error: 'U4' was not declared in this scope

         m_fix.alt_err_cm = U4/100;

                            ^

exit status 1 Error compiling for board Arduino/Genuino Mega or Mega 2560.

Not sure if it is me or there is an error in the lib. I did change the beginning part of the sketch since I am using Serial2

#include <Arduino.h>
#include "ubxGPS.h"

//======================================================================
//  Program: ublox.ino
//
//  Prerequisites:
//     1) You have a ublox GPS device
//     2) PUBX.ino works with your device
//     3) You have installed the ubxGPS.* and ubxmsg.* files.
//     4) At least one UBX message has been enabled in ubxGPS.h.
//     5) Implicit Merging is disabled in NMEAGPS_cfg.h.
//
//  Description:  This program parses UBX binary protocal messages from
//     ublox devices.  It shows how to acquire the information necessary
//     to use the GPS Time-Of-Week in many UBX messages.  As an offset
//     from midnight Sunday morning (GPS time), you also need the current 
//     UTC time (this is *not* GPS time) and the current number of GPS 
//     leap seconds.
//
//  Serial is for debug output to the Serial Monitor window.
//
//======================================================================

    #include <NeoHWSerial.h>

#include "Streamers.h"

  #define DEBUG_PORT NeoSerial
#define gps_port NeoSerial2

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

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

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

#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.print( F("enable TIMEGPS failed!\n") );

          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.print( F("disable TIMEGPS failed!\n") );

          #if defined(UBLOX_PARSE_TIMEUTC)
            if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC ))
              DEBUG_PORT.print( F("enable TIMEUTC failed!\n") );
            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(GPS_FIX_LOCATION) | \
           defined(GPS_FIX_LOCATION_DMS) | \
           defined(GPS_FIX_ALTITUDE)) & \
          defined(UBLOX_PARSE_POSLLH)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_POSLLH ))
          DEBUG_PORT.print( F("enable POSLLH failed!\n") );

        enabled_msg_with_time = true;
      #endif

      #if (defined(GPS_FIX_SPEED) | defined(GPS_FIX_HEADING)) & \
          defined(UBLOX_PARSE_VELNED)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_VELNED ))
          DEBUG_PORT.print( F("enable VELNED failed!\n") );

        enabled_msg_with_time = true;
      #endif

      #if (defined(GPS_FIX_SATELLITES) | defined(NMEAGPS_PARSE_SATELLITES)) & \
          defined(UBLOX_PARSE_SVINFO)
        if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_SVINFO ))
          DEBUG_PORT << PSTR("enable SVINFO failed!\n");

        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.print( F("disable TIMEUTC failed!\n") );

        #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.print( F("enable TIMEUTC failed!\n") );
        #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( &gps_port );

#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 );
}

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

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 " USING_GPS_PORT) );
  DEBUG_PORT.flush();

  // Start the UART for the GPS device
  #ifdef NMEAGPS_INTERRUPT_PROCESSING
    gps_port.attachInterrupt( GPSisr );
  #endif
  gps_port.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( gps_port ))
      gps.read();
}

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

void loop()
{
  if (gps.available( gps_port ))
    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 (Serial.available()) {
    do { Serial.read(); } while (Serial.available());
    DEBUG_PORT.println( F("Stopping...") );

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

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

Thanks again Mike

SlashDevin commented 7 years ago

It's complaining because this needs to be uncommented in NMEAGPS_cfg.h:

#define NMEAGPS_PARSING_SCRATCHPAD

There is a check in ubxGPS.cpp, line 16, that should have emitted this error:

In file included from ...build1a60db5dae6248244897ff617f036cf2.tmp\sketch\ubxGPS.cpp:1:0:

ubxGPS.cpp:16: error: #error You must enable NMEAGPS_PARSING_SCRATCHPAD in NMEAGPS_cfg.h

   #error You must enable NMEAGPS_PARSING_SCRATCHPAD in NMEAGPS_cfg.h

    ^

If you didn't get that error, please show me your GPSfix_cfg.h and NMEAGPS_cfg.h files.

mjs513 commented 7 years ago

NeoGPS-master.zip

Only message I received was what I sent. Scratchpad is enabled.

SlashDevin commented 7 years ago

Confirmed, fixed by latest commit e4ad94ea8df50872c7f7c472eb275ef73461f3f7. You just need the changes in ubxGPS.cpp and ublox.ino.

Thanks!

mjs513 commented 7 years ago

Just tested both pubx and ublox sketches. Both work no problem. However, did notice that you do not have a line for Galileo satellites to filter out. If I may ask one more question, how do you get individual elements in the ublox example such as print only hdop, pdop, sog, cog, etc,

SlashDevin commented 7 years ago

Can it filter out Galileo satellites?

That's a great forum question! I'll respond in my NeoGPS thread, and update here when they're ready. There might be a problem with NMEA GSV sentences that's related to different talkers, still investigating.

how do you... print only hdop, pdop, sog, cog, etc,

Please see the Data Model page, or look at the Streamers.cpp file. It shows how to access every piece, for printing. For example, accessing Speed (Over Ground) from a fix is here. There are other speed-related methods in a fix, which can be found in the gps_fix class, here.

mjs513 commented 7 years ago

That's what I thought. However, DOP values are not being returned either by the UBX command or the fix method. Here is a sample line from the trace all:

3,2016-09-24 11:40:39.60,407746042,-738146466,40 46' 28.574" N 073 48' 52.727" W,14626,2546,1932,,,,87,87,173,,25,[1 53/142@0,7 59/192@22,8 44/50@10,10 2/41@0,80 0/0@0,38 0/0@0,3 0/0@0,13 0/0@0,70 0/0@107,54 0/0@0,3 0/8552@0,1 33/1049@104,1 0/0@14,4 0/296@64,3 0/56427@50,1 0/0@41,0 0/30800@1,3 0/18214@1,18 0/56323@1,14 23/9229@3,],68,96,16499,,

Here is the fix elements HDOP, PDOP 0, 0, 2.55, 146.26, 407746042, -738146466, 25, 2016-09-24 11:40:39.60, t

You want me to open a another issue or move this to the forum? There is question I will post to forum on polling UBX

Mike

SlashDevin commented 7 years ago

DOP values are not being returned by the UBX command or the fix method.

I'm not sure what you mean. A "UBX command" is a binary message that you send to a ublox GPS device. UBX is the name of their binary protocol. ublox GPS devices can also emit proprietary NMEA messages (text format), and they start with "$PUBX,".

The NMEAGPS class has a fix() method that returns the gps_fix structure that is currently being assembled, and it is not usually safe to call that method. Most of the examples declare a fix variable (of type gps_fix), and assign the return from gps.read() to that variable.

I think you might be saying that your program never gets an HDOP or PDOP value, or it's zero if you print out the variable from some fix structure.

You want me to open a another issue or move this to the forum?

Yes, that would be another issue. I can suggest a few things that you should check first:

It looks like HDOP and PDOP are enabled in GPSfix_cfg.h, because there are commas after the altitude field. Because the trace_all has empty fields, the values are not valid (i.e., they have never been parsed from a sentence). You can test fix.valid.hdop. Really, you should always test the valid flags, because printing a "default" value can be misleading. What if the GPS device really reports an altitude of zero? You wouldn't be able to distinguish between "really at zero" and "don't know". I would suggest printing either an empty field (like Streamers.CPP), a dash character ('-'), or a ridiculous value (-999).

If the valid flags are always false, it could mean that the sentence(s) that contain HDOP and PDOP fields are not enabled (they won't be parsed even if the GPS sends them), OR that the GPS device never sends a GSA (the only sentence that contains PDOP, see this table).

For the former, check that NMEAGPS_PARSE_GSA is uncommented in NMEAGPS_cfg.h. For the latter, check that the GPS device is actually sending a GSA by running NMEAorder.ino. You may also need to change LAST_SENTENCE to match what is reported.

If you still have trouble, open another issue and be sure to attach your configs: GPSfix_cfg, NMEAGPS_cfg and (if you're using ublox.ino) ubx_cfg.

mjs513 commented 7 years ago

Think I figured out the issue based on your comments above. Since I am running the ublox.ino example it uses the ubxGPS.cpp to parse the UBX messages (I can it commands previously) so I checked the ubxCFG file and ubxGPS.h/.cpp and there is no parsing option for the UBX-NAV-DOP message that contains those fields. I will go ahead and open another issue.

SlashDevin commented 7 years ago

Can it filter out Galileo satellites?

I have updated my NeoGPS thread with an answer, here.