Venus838FLPx GPS module at 50Hz

Hi everyone, i'm working on a project with the aim of making an high performance GPS chrometer.
The aforementioned GPS is the only one that can give me the maximum update rate that i need for civilian use without a license.

In this Forum we have already talked about this module but only to make it works at 20Hz update rate.
Here the code..

/***************************************************
 *  This code turns updates the refresh rate of the
 *  Venus838FLPx GPS from 1 Hz to 20 Hz. I would
 *  like to thank -dev from the Arduino.org forums
 *  for the code he uploaded here:
 * 
 *  https://forum.arduino.cc/index.php?topic=438394.0
 *  Post #1
 * 
 *  This code that I have written just adds a few
 *  things and parses the data
 * 
 *  There is no error checking in the set-up. I may
 *  add that later. As of now, it assumes no error
 *  will occur and everything will work flawless.
 * 
 *                              11/23/17 DGrullon
 *                       
 *  PS. I know the code is sloppy
 ***************************************************/

// Include ////////////////////////////////////////////
#include <TinyGPS++.h>

// Definitions ////////////////////////////////////////
#define GPS_PORT        Serial2
#define SERIAL_BAUDRATE 9600
#define NEW_BAUDRATE    115200


// Function Prototypes ////////////////////////////////
void sendCommand(uint8_t*, uint8_t);
void readUpdate(void);


// Venus Commands /////////////////////////////////////
uint8_t refreshRateCmd[10] = {0xA0, 0xA1, 0x00, 0x03, 0x0E, 0x14, 0x00, 0x1A, 0x0D, 0x0A};    // 20 Hz Refresh Rate
uint8_t baudRateCmd[11] = {0xA0, 0xA1, 0x00, 0x04, 0x05, 0x00, 0x05, 0x00, 0x00, 0x0D, 0x0A}; // 115200 Baud Rate

// Objects ////////////////////////////////////////////
TinyGPSPlus gps;

// Initalizer /////////////////////////////////////////
void setup()
{
  // Start serial ports
  Serial.begin(NEW_BAUDRATE);
  GPS_PORT.begin(SERIAL_BAUDRATE); 

  // Update Venus838FLPx baud rate to 115200
  sendCommand(baudRateCmd, sizeof(baudRateCmd));
  GPS_PORT.begin(NEW_BAUDRATE);
   
  // Send Update Refresh Rate Command
  sendCommand(refreshRateCmd, sizeof(refreshRateCmd));

  return;
}


// Main Loop /////////////////////////////////////////
void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (GPS_PORT.available() > 0)
    if ( gps.encode( GPS_PORT.read() ) )
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }

  return;
}


// Functions /////////////////////////////////////////
void sendCommand(uint8_t* Command, uint8_t sizeOfArray)
{
  GPS_PORT.write(Command, sizeOfArray);
  GPS_PORT.flush();
  delay(10);
 
  return;
}

void displayInfo()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
    Serial.print(F(","));
    Serial.print(gps.altitude.meters(),6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

This is the program given by "OhSoCurious" in 2017 about a similar topic.
I have read all the discussion and learned a lot, thanks to you all. Now i would like to understand how to make it work at 50Hz (The maximum possible), and i think i need to rewrite a different bytes in this line :

uint8_t refreshRateCmd[10] = {0xA0, 0xA1, 0x00, 0x03, 0x0E, 0x14, 0x00, 0x1A, 0x0D, 0x0A};

I searched about the update configuration in the component datasheet but i could not find anything that led back to me.

All the adivices , links, documents, are appreciate.

Thanks you all.

According to the manual of the commands possible for that device, you must not only change the update rate but also the baudrate for all values above 20Hz.

The refresh rate command should be:

uint8_t refreshRateCmd[10] = {0xA0, 0xA1, 0x00, 0x03, 0x0E, 0x32, 0x00, 0x3C, 0x0D, 0x0A};

The byte at index 5 is the refresh rate value, at index 7 is the checksum.

The baudrate command for 230400 baud is:

uint8_t baudRateCmd[11] = {0xA0, 0xA1, 0x00, 0x04, 0x05, 0x00, 0x06, 0x00, 0x03, 0x0D, 0x0A}; // 230400 Baud Rate

Thanks pylon, after giving a first reading it's all more clear and i can follow you in the reasoning. I still have a doubt about "CS" CheckSum, is supposed to be CS = CS^<Payload # n>, in our case it should be CS = 0x0E^<0x0E+0x32 # n> for the rate command line ..? Am i wrong?

Alfio99:
In this Forum we have already talked about this module but only to make it works at 20Hz update rate.

Considering that an Arduino can divide a second into 1000 millisecs I can't imagine why an update rate faster than once per second is needed.

How accurate do you want your chronometer to be?

...R

Robin2, a motorcycle or a car when cross over the finish line of a racing track, it has more or less a speed beetwen 80-90 m/s, that mean if i have a standard GPS with an update rate of 1 Hz, i have an error of <=90 meters, not acceptable at all. Increasing the refreshing rate to 50Hz i can decrease the time beetwen readings up to 20ms instead of 1 sec, this means that a motorcycle at its maximum speed has an update of its position every 1.5 meters more or less, instead of 90 meters, Huge difference!
By the way, online you can find a good explanation of what i'm saying.
Im trying to reproduce it with arduino because the same products on the market cost at least 250 euros.

Alfio

Alfio99:
Robin2, a motorcycle or a car when cross over the finish line of a racing track, it has more or less a speed beetwen 80-90 m/s, that mean if i have a standard GPS with an update rate of 1 Hz, i have an error of <=90 meters, not acceptable at all

I understand that.

If I were to use millis() to interpolate between two GPS times 1 second apart I could reduce the error from 90m to 90 millimeters. Wouldn't that be good enough?

...R

Robi2, that's an interesting thing that i considered and tried to reason with it.
I'm sure that the products on the market use this technique to reach the 50Hz speed as they claim.
With Arduino i'm just afraid it will be complicated to maintain the Time clock of each GPS, if i fail to read a measure in time, i fail the precision of the system by a lot.

90 millimiters would be very good, but how to do it? With two GPS of 1 Hz each you can reach a periodic signal every 45 meters and with two GPS at 50 Hz every 90 centimeters..

This method is very cool mostly because it's very difficoult to find this CHIP Venus nowadays, and seems very nice on two 20 Hz GPS, the error would be acceptable anyway instead 50 Hz.

I would save the value of millis() to a variable (let's call it mostRecentGpsTime) every time a 1 second signal comes from the GPS.

Then at any instant I could calculate how many millisecs had elapsed since the most recent GPS signal with code like this

millisecsElapsed = millis() - mostRecentGpsTime;

...R

Robin2, we were thinking the same thing i presume.
I have in my mind a program like this :

unsigned long mostRecentGpsTime = 0; //First reading
int i = 0;  //Simple Variable to comand from which GPS read

millisecsElapsed = millis() - mostRecentGpsTime;
if (millisecsElapsed >= 500) { //500 millis
  if (i % 2 == 0)
    ReadFrom(GPS1);
  else
    ReadFrom(GPS2);
  i++;
  mostRecentGpsTime = millisecsElaples;
}

In this way you can read from 2 GPS at 1Hz but i think it will not work because any computational time more in the program would create interferences, the nicest thing to do is an analyis of the time used by the rest of the program in polling mode (To know exactly how much time is take in the worst case), than update the value of 500ms(2Hz) to a precise new interval, probabily a bit less than 2Hz.
With Interference i mean that a possible code below the GPSs control may slow down the program and the periodic tasks wuold stop to be read every 500 ms but every 600-650 ms for example. (All depends by the dimension of the program and the clock of our micro).
it's not impossible, but requires a bit of time, i'll try to figure out this as soon as i can.

Alfio99:
Robin2, we were thinking the same thing i presume.
I have in my mind a program like this :

I wasn't thinking of that, but what you have suggested probably has the same effect and is probably simpler.

However you need to record the GPS time as well as the value of millis() because the time of an even that happens during the second (between GPS times) will be the previous GPS time + the number of millis() since the GPS time was obtained.

Something like this

if (millis() - timeOfPreviousGpsRead >= 1000) { // read every second
   gpsTime = code to get time from GPS
   timeOfPreviousGpsRead = millis();
}

if (endOfRaceDetected == true) {
  elapsedMillis = millis() - timeOfPreviousGpsRead;
  timeAtEndOfRace = gpsTime + elapsedMillis;
}

...R

Robin2, you are right, i forgot about the time, your seems a good implementation.
Thanks for all the suggestions, helpufull to me.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.