Novice with GPS venus Sparkfun Venus638FLPx

Hello,

I have recently bought a Venus GPS manufactured by Sparkfun https://www.sparkfun.com/products/10920

I am novice with GPS device and I try to understand how it works. Maybe someone could help me about the meaning of the different pins: 24,2,1,PPS and VBAT.

In a sending time, I would like acquire GPS position, UTC Time and speed with a 20 Hz sample rate (not 1 Hz which is the default setting). Does someone have an example?

Thank you in advance, Pm

I can't tell you about the pins, except the 1PPS is a one pulse-per-second square wave. The spec says it is high for 4ms. You would only use it if you need to synchronize two clocks, or if your clock must "tick" very accurately each second.

with a 20 Hz sample rate

It looks like you have to use the Venus 6 binary protocol to send a configuration command. I think these are the HEX bytes to send:

    A0 A1 00 03 0E 14 00 1A 0D 0A

You will have to set the baud rate to 115200 to be able to receive the data quickly enough. That's another binary command:

    A0 A1 00 04 05 00 05 00 00 0D 0A

You'll have to change the Arduino baud rate after this command goes out to the GPS. In setup:

 gps_port.begin( 9600 ); // default GPS baudrate
  gps_port.write( baudrateCmd, sizeof(baudrateCmd) ); // tell GPS to change baudrate
  gps_port.flush(); // wait for command to go out
  delay( 10 );
  gps_port.begin( 115200 ); // match the GPS' new baud
  gps_port.write( updateRateCmd, sizeof(updateRateCmd) );

For parsing the UTC, lat/lon and speed from the GPS characters, my NeoGPS library can help. It is smaller, faster, more reliable and more accurate than all other libraries. At 20Hz, the extra speed may be important. NeoGPS can also parse the information during the RX character interrupt (requires NeoHWSerial or NeoICSerial).

If you do not have a Mega (or you are not hooking it to Serial RX pin 0), you should use AltSoftSerial. It only works on two specific pins (8 & 9 for an UNO). At 115200, a HardwareSerial port is strongly recommended (i.e., Serial, Serial1, Serial2 or Serial3).

Using SoftwareSerial is not recommended at these rates. It may not be reliable, and it blocks interrupts for long periods of time every time a character is received. At the 20Hz update rate, SoftwareSerial will really slow down your sketch.

Cheers, /dev

Hello,

Thank you very much for your answer! I have taken a look to your library and you did an awesome work!

What I have undersand about this GPS is:

  • it works with NMEA protocol: each period it send the different $GP… messages.
  • Native Serial library is not adequat for this GPS I have to use one of your library

I have download NeoGPS and NeoHWSerial libraries. I try to execute one of your example which is NMEA but it doesn’t work. It seems to be an error in library functions as you can see on the screenshot.

Have a good day and thank you again,
Pm

Next time, just select the error text in the IDE or Serial Monitor and

[code]   
      paste it into a
          code block
[/code]
...so it looks like this.

This is described on the How To Use the Forum page, steps 9 and 11.

Here is your image, embedded for our convenience:

c8d18a8c05f83cb49d7687a65b37848424f18e99.png

Technique described here. Now you can see why copy and paste of the text is better… :-/

It looks like you are using a version of the Arduino IDE before 1.0.6, so you should probably upgrade. Versions 1.6.8 and 1.6.13 do not generate any errors.

Cheers,
/dev

Hello,

Sorry I am not enough familiar with the forum. The error is the following:

Arduino : 1.7.11 (Windows 7), Carte : "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

In file included from C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/GPSfix.h:22:0,

                 from C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/NMEAGPS.h:29,

                 from NMEA.ino:2:

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/NeoGPS_cfg.h:81:35: error: 'constexpr' does not name a type

   #define CONST_CLASS_DATA static constexpr

                                   ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/Location.h:33:5: note: in expansion of macro 'CONST_CLASS_DATA'

     CONST_CLASS_DATA float LOC_SCALE = 1.0e-7;

     ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/NeoGPS_cfg.h:81:35: note: C++11 'constexpr' only available with -std=c++11 or -std=gnu++11

   #define CONST_CLASS_DATA static constexpr

                                   ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/Location.h:33:5: note: in expansion of macro 'CONST_CLASS_DATA'

     CONST_CLASS_DATA float LOC_SCALE = 1.0e-7;

     ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/NeoGPS_cfg.h:81:35: error: 'constexpr' does not name a type

   #define CONST_CLASS_DATA static constexpr

                                   ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/Location.h:55:5: note: in expansion of macro 'CONST_CLASS_DATA'

     CONST_CLASS_DATA float EARTH_RADIUS_KM = 6371.0088;

     ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/NeoGPS_cfg.h:81:35: note: C++11 'constexpr' only available with -std=c++11 or -std=gnu++11

   #define CONST_CLASS_DATA static constexpr

                                   ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/Location.h:55:5: note: in expansion of macro 'CONST_CLASS_DATA'

     CONST_CLASS_DATA float EARTH_RADIUS_KM = 6371.0088;

     ^

C:\Program Files (x86)\Arduino\libraries\NeoGPS\src/NeoGPS_cfg.h:81:35: error: 'constexpr' does not name a type

   #define CONST_CLASS_DATA static constexpr

                                   ^
ETC....

I have the IDE version 1.7.11 maybe I have to downgrade?

Thank you, Pm

I have the IDE version 1.7.11 maybe I have to downgrade?

1.6.13 is the latest version offered here, Arduino.cc (see Downloads link above).

I'll try it with the 1.7.11 version (from Arduino.org). Another casualty of the Arduino civil war...

Grrr, /dev

Yes, there are several odd things about the Arduino.org version. I would not recommend that version; use the Arduino.cc 1.6.13 version instead (from the Download link above).

For those that really want to use 1.7.x from Arduino.org, I have just checked in a NeoGPS update that accommodates this quirk. Only NeoGPS_cfg.h changed.

Cheers, /dev

Hello /dev,

I have downgraded to the 1.6.13 and it works perfectly. I have changed GPS sample and baud rates and it seems working. Please just take a look to the code extract from setup function of the NMEA example:

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

  DEBUG_PORT.print( F("NMEA.INO: started\n") );
  DEBUG_PORT.print( F("  fix object size = ") );
  DEBUG_PORT.println( sizeof(gps.fix()) );
  DEBUG_PORT.print( F("  gps object size = ") );
  DEBUG_PORT.println( sizeof(gps) );
  DEBUG_PORT.println( F("Looking for GPS device on " USING_GPS_PORT) );

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

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

  #if !defined( NMEAGPS_PARSE_GGA ) & !defined( NMEAGPS_PARSE_GLL ) & \
      !defined( NMEAGPS_PARSE_GSA ) & !defined( NMEAGPS_PARSE_GSV ) & \
      !defined( NMEAGPS_PARSE_RMC ) & !defined( NMEAGPS_PARSE_VTG ) & \
      !defined( NMEAGPS_PARSE_ZDA ) & !defined( NMEAGPS_PARSE_GST )

    DEBUG_PORT.println( F("\nWARNING: No NMEA sentences are enabled: no fix data will be displayed.") );

  #else
    if (gps.merging == NMEAGPS::NO_MERGING) {
      DEBUG_PORT.print  ( F("\nWARNING: displaying data from ") );
      DEBUG_PORT.print  ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
      DEBUG_PORT.print  ( F(" sentences ONLY, and only if ") );
      DEBUG_PORT.print  ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
      DEBUG_PORT.println( F(" is enabled.\n"
                            "  Other sentences may be parsed, but their data will not be displayed.") );
    }
  #endif

  DEBUG_PORT.print  ( F("\nGPS quiet time is assumed to begin after a ") );
  DEBUG_PORT.print  ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
  DEBUG_PORT.println( F(" sentence is received.\n"
                        "  You should confirm this with NMEAorder.ino\n") );

  trace_header( DEBUG_PORT );

  DEBUG_PORT.flush();

  // Start the UART for the GPS device
  
gps_port.begin( 9600 );

byte updateRateCmd[] = {0xA0, 0xA1, 0x00, 0x03, 0x0E, 0x14, 0x00, 0x1A, 0x0D, 0x0A}; //
byte baudrateCmd[] = {0xA0, 0xA1, 0x00, 0x04, 0x05, 0x00, 0x05, 0x00, 0x00, 0x0D, 0x0A}; //

gps_port.write( baudrateCmd, sizeof(baudrateCmd) ); // tell GPS to change baudrate
gps_port.flush(); // wait for command to go out

delay( 10 );

gps_port.begin( 115200 ); // match the GPS' new baud
gps_port.write( updateRateCmd, sizeof(updateRateCmd) );

}

I don't understand because when I use your Hex messages it works but in datasheet (https://www.sparkfun.com/datasheets/GPS/Modules/AN0003_v1.4.14_FlashOnly.pdf) the setup messages is a little bit different. Maybe you can explain me the difference?

Thank you for your help, Pm

I used v1.4.19, dated Oct 26, 2011. The "Configure Serial Port" example shows setting 4800 baud, not 115200. The "Configure Position Update Rate" example shows 1Hz, not 20Hz. With different field values from the examples, the checksum byte is also different.

Is that what you're asking?

Hello,

Thank you for your help. I am a little bit lost to understand how to compute the check sum. I know that only the payload trame is included in the checksum computing. Could you explain me how to compute the checksum for an arbitrary payload trame like the following one:

37 01 00

Thank you, Pm

I am a little bit lost to understand how to compute the check sum.

Have you looked at the spec?

AN003, pg. 3:
Checksum

Checksum (CS) field is transmitted in all messages. The checksum field is the last field in a message before the end of sequence field. The checksum is the 8-bit exclusive OR of only the payload bytes which start from Message ID until the last byte prior to the checksum byte. A reference to the calculation of CS is provided below,

    CS = 0, N=PL;

For n = 0 to N
        CS = CS ^ <Payload Byte # n>

The “^” operator in C is EXCLUSIVE-OR, a bitwise operation. A calculator app sometimes has a “programmer’s” mode with hexadecimal and binary displays and bitwise operators.

The XOR operation for two bits is 1 when the two bits are different (0 ^ 1 or 1 ^ 0), and 0 when the two bits are the same (0 ^ 0 or 1 ^ 1). In a byte, just XOR each of the corresponding bits. Start with a CS of zero, then

    CS ^byte=                              new CS
    00 ^ 37 = 00000000 ^ 00110111 = 00110111 = 37, then
    37 ^ 01 = 00110111 ^ 00000001 = 00110110 = 36, then
    36 ^ 00 = 00110110 ^ 00000000 = 00110110 = 36.

36 is the XOR checksum for those three bytes.

Cheers,
/dev

Before attempting to help with the checksum, OP crossposted the question here

Pete

@powergravity, please do not cross-post.

hello,

I didn't understand the EXCLUSIVE-OR procedure. Now it is more clear with your example.

Thank you again, PM

Hello,

Maybe it could help someone who will have the same question about Venus638FLPx GPS setup,

Initialisation du port 3 à 9600 Bd

====================================================================================================================================================
====================================================================================================================================================
Débit du port en RAM:
4800    : 160 161 00 04 05 00 00 00 05 13 10 // A0 A1 00 04 05 00 00 00 05 0D 0A 
9600    : 160 161 00 04 05 00 01 00 04 13 10 // A0 A1 00 04 05 00 01 00 04 0D 0A 
19200   : 160 161 00 04 05 00 02 00 07 13 10 // A0 A1 00 04 05 00 02 00 07 0D 0A
38400   : 160 161 00 04 05 00 03 00 06 13 10 // A0 A1 00 04 05 00 03 00 06 0D 0A
57600   : 160 161 00 04 05 00 04 00 01 13 10 // A0 A1 00 04 05 00 04 00 01 0D 0A 
115200  : 160 161 00 04 05 00 05 00 00 13 10 // A0 A1 00 04 05 00 05 00 00 0D 0A

Débit du port en flash:
4800    : 160 161 00 04 05 00 00 01 03 13 10 // A0 A1 00 04 05 00 00 01 03 0D 0A
9600    : 160 161 00 04 05 00 01 01 05 13 10 // A0 A1 00 04 05 00 01 01 05 0D 0A
19200   : 160 161 00 04 05 00 02 01 06 13 10 // A0 A1 00 04 05 00 02 01 06 0D 0A 
38400   : 160 161 00 04 05 00 03 01 07 13 10 // A0 A1 00 04 05 00 03 01 07 0D 0A
57600   : 160 161 00 04 05 00 04 01 00 13 10 // A0 A1 00 04 05 00 04 01 00 0D 0A
115200  : 160 161 00 04 05 00 05 01 01 13 10 // A0 A1 00 04 05 00 05 01 01 0D 0A
====================================================================================================================================================
Fréquence en RAM:
 1Hz    : 160 161 00 03 14 01 00 15 13 10 // A0 A1 00 03 0E 01 00 0F 0D 0A
 2Hz    : 160 161 00 03 14 02 00 12 13 10 // A0 A1 00 03 0E 02 00 0C 0D 0A
 4Hz    : 160 161 00 03 14 04 00 10 13 10 // A0 A1 00 03 0E 04 00 0A 0D 0A 
 5Hz    : 160 161 00 03 14 05 00 11 13 10 // A0 A1 00 03 0E 05 00 0B 0D 0A
 8Hz    : 160 161 00 03 14 08 00 06 13 10 // A0 A1 00 03 0E 08 00 06 0D 0A
10Hz    : 160 161 00 03 14 10 00 04 13 10 // A0 A1 00 03 0E 0A 00 04 0D 0A
20Hz    : 160 161 00 03 14 20 00 26 13 10 // A0 A1 00 03 0E 14 00 1A 0D 0A

Fréquence, en flash:
 1Hz    : 160 161 00 03 14 01 01 14 13 10 // A0 A1 00 03 0E 01 01 0E 0D 0A
 2Hz    : 160 161 00 03 14 02 01 13 13 10 // A0 A1 00 03 0E 02 01 0D 0D 0A
 4Hz    : 160 161 00 03 14 04 01 11 13 10 // A0 A1 00 03 0E 04 01 0B 0D 0A
 5Hz    : 160 161 00 03 14 05 01 10 13 10 // A0 A1 00 03 0E 05 01 0A 0D 0A
 8Hz    : 160 161 00 03 14 08 01 07 13 10 // A0 A1 00 03 0E 08 01 07 0D 0A
10Hz    : 160 161 00 03 14 10 01 05 13 10 // A0 A1 00 03 0E 0A 01 05 0D 0A
20Hz    : 160 161 00 03 14 20 01 27 13 10 // A0 A1 00 03 0E 14 01 1B 0D 0A
====================================================================================================================================================
Activation du WAAS en RAM:
ON  : 160 161 00 03 55 01 00 54 13 10 // A0 A1 00 03 37 01 00 36 0D 0A 
OFF    : 160 161 00 03 55 00 00 55 13 10 // A0 A1 00 03 37 00 00 37 0D 0A 

Activation du WAAS en Flash:
ON  : 160 161 00 03 55 01 01 55 13 10  // A0 A1 00 03 37 01 01 37 0D 0A
OFF    : 160 161 00 03 55 00 01 54 13 10  // A0 A1 00 03 37 00 01 36 0D 0A 
====================================================================================================================================================
Restart:
Hot : 160 161 00 15 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13 10 // A0 A1 00 0F 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 0A
Warm    : 160 161 00 15 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 03 13 10 // A0 A1 00 0F 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 03 0D 0A 
Cold    : 160 161 00 15 01 03 00 00 00 00 00 00 00 00 00 00 00 00 00 02 13 10 // A0 A1 00 0F 01 03 00 00 00 00 00 00 00 00 00 00 00 00 00 02 0D 0A
Factory : 160 161 00 02 04 01 05 13 10 // A0 A1 00 02 04 01 05 0D 0A 
====================================================================================================================================================
Type de messages de sortie, en RAM:
aucun   : 160 161 00 03 09 00 00 09 13 10 // A0 A1 00 03 09 00 00 09 0D 0A
NMEA    : 160 161 00 03 09 01 00 08 13 10 // A0 A1 00 03 09 01 00 08 0D 0A
Binary  : 160 161 00 03 09 02 00 11 13 10 // A0 A1 00 03 09 02 00 0B 0D 0A

Type de messages de sortie, en Flash:
aucun   : 160 161 00 03 09 00 01 08 13 10 // A0 A1 00 03 09 00 01 08 0D 0A 
NMEA    : 160 161 00 03 09 01 01 09 13 10 // A0 A1 00 03 09 01 01 09 0D 0A
Binary  : 160 161 00 03 09 02 01 10 13 10 // A0 A1 00 03 09 02 01 0A 0D 0A 
====================================================================================================================================================
====================================================================================================================================================

I have translated the decimal trame to hex (easier to understand with the data sheet) and add the 20 Hz trame setting with the correct checksum.

What is the difference between RAM and flash settings?

Thank you, Pm

Storing the new configuration (baud rate or update rate) in RAM means the GPS module will revert to the default configuration when it is reset or powered off.

Storing the new configuration in FLASH means that it is permanent. The next time the GPS resets/powers on, it will load its configuration from the non-volatile FLASH memory. In your case, it would start running at the faster baud rate and update rate.

Some people store the configuration in FLASH so they can run it once, and then remove the configuration commands from the sketch. You can also use a utility to configure the GPS permanently (i.e., in FLASH). I've never been a fan of that, because it requires the same extra steps for anyone else using your sketch. If you replace the GPS module, it would have to be reconfigured. Just leave the configuration commands in your sketch, unless you really need the program space. It's probably less than 100 bytes.

Cheers, /dev

Hello,

Ok I have understood and I will follow your advises.

Now I am trying to save GPS data on SD card. Regarding NMEA.ino sketch I guess the code to save data has to be in doSomeWork() function. I am not able to write the whole of fix_data structure on the card with the function SDCard.println(). Did you have a solution?

One time again thank you, Pm

Just write the individual pieces that you want to save, in the order that you want:

if (fix.valid.location)
  SDCard.print( fix.latitude(), 6 );
SDCard.print( ',' );
if (fix.valid.location)
  SDCard.print( fix.longitude(), 6 );
SDCard.print( ',' );

if (fix.valid.time) {
  SDCard.print( fix.dateTime.hours );
  SDCard.print( ':' );
  if (fix.dateTime.minutes < 10)
    SDCard.print( '0' ); // leading 0
  SDCard.print( fix.dateTime.minutes );
  SDCard.print( ':' );
  if (fix.dateTime.seconds < 10)
    SDCard.print( '0' ); // leading 0
  SDCard.print( fix.dateTime.seconds );
  SDCard.print( '.' );
  if (fix.dateTime_cs < 10)
    SDCard.print( '0' ); // leading 0
  SDCard.print( fix.dateTime_cs );
}

if (fix.valid.date) {
   ...

Notice how it checks to make sure the values are valid. It just prints the separating commas if the field is not valid (i.e., an empty field). NMEAloc.ino and Streamers.cpp have more examples for printing.

For logging at a 20Hz rate, you will have to use the technique in NMEASDlog.ino, which requires one of the NeoxxSerial libraries. SD writes occasionally take ~100ms, which is two complete updates from the GPS. They will be lost if you don’t use one of the NeoxxSerial libraries to handle the GPS data (in the interrupt routine) while the SD write is busy (in doSomeWork).

Cheers,
/dev

Hello,

I am trying to logging at 20 Hz.

For logging at a 20Hz rate, you will have to use the technique in NMEASDlog.ino, which requires one of the NeoxxSerial libraries. SD writes occasionally take ~100ms, which is two complete updates from the GPS. They will be lost if you don’t use one of the NeoxxSerial libraries to handle the GPS data (in the interrupt routine) while the SD write is busy (in doSomeWork).

First as you have explained I have opened NMEASDlog.ino. Then I have uncommented the line
#define NMEAGPS_INTERRUPT_PROCESSING in NMEAGPS_cfg.

Next I have changed GPS settings in NMEASDlog.ino (20 Hz and 115200 baud rate) and run the code. I was expecting to get a problem with over runed data and it was the case. So I have modified the FIX_MAX value to 4 in NMEAGPS_cfg. The over running problem is avoided but I have another problem:

-Considering a simulated SD Card I am not able to find the right way to get a frequency at 20 Hz and constant:

fix size = 31
4 GPS updates can be buffered.
Simulating SD.
Waiting for GPS fix…
48.6084433,2.4133383,10:05:16.40,0
48.6084433,2.4133383,10:05:16.95,626
48.6084433,2.4133383,10:05:19.35,2442
48.6083167,2.4132633,10:05:20.80,1336
48.6083167,2.4132617,10:05:22.05,1337
48.6083167,2.4132617,10:05:22.15,122
48.6083167,2.4132617,10:05:22.80,627
48.6082967,2.4133200,10:05:25.15,2402
48.6082967,2.4133200,10:05:26.45,1338
48.6082967,2.4133200,10:05:27.90,1336
48.6082967,2.4133200,10:05:30.30,2442
48.6082967,2.4133200,10:05:30.45,122
48.6082967,2.4133200,10:05:30.55,83
48.6083150,2.4133583,10:05:31.20,627
48.6083150,2.4133583,10:05:31.70,625

-Trying with a real SD card the code is locked in “waiting for GPS fix”

fix size = 31
4 GPS updates can be buffered.
Initializing SD card…
SD card initialized.
Writing to data_04.txt
Waiting for GPS fix…

I have this Micro SD card : SDCARD

Maybe it is to slow to write data at 20 Hz?

Thank you and have a good Sunday,
Pm

Re,

My question was not intelligent because it works perfectly.

Next days I would try to complete the code to log an IMU (Adafruit BNO055) and two hall effect sensors with a sample frequency of 100 Hz. I would try also to display actual data on a TFT screen.

Starting with the code of the GPS data logging I guess I have to work with your serial library NeoSWSerial.h ? Did you have some advices before begining the next step?

Juste some words about the objective. I am PhD student at University in France. I work on motorcycle active safety systems and I am trying to developp a data logger for a scooter to validate theorical results. I am not a programmer that is why I have some difficulties and sometimes my questions seem to be a little bit stupid.

Thank you for your patience and your help, Pm