Using Arduino and GPS module to show speed

I have a number of UNO's and a Mega plus a NEO-GPS module. Can anyone point me in the right direction to produce a GPS speed indicator for use in my car?

Not sure what you're asking. Do you need help calculating the speed?- the only GPS library I've used, adafruit's, already does that. I'd be surprised if other libraries don't all do so. Or do you mean you need help displaying the value?- if so, what sort of display do you want? Number on an LCD, a mechanical gauge, an electronic gauge on a graphic display?

At this stage I am looking for the best library to use, what connections to make and display. I have several types of electronic display hardware (digit readouts, 2 line and 4 line screens.) I thought that either the 4 digit Nixie tube or the 2 line graphic screen would be best. A circuit diagram could be helpful too.

My NeoGPS library is smaller, faster, more accurate and more reliable than all other libraries. If you'd like to try it, NeoGPS is available from the Ardino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.

Some speedometer projects that use it:

GPS Nixie Speedometer
Gps speedometer
GPS Speedometer, problems when still
[GPS Speedometer] Slow display updates on Mode 3 Fix.
Adafruit Ultimate GPS, SSD1306 0.96" 128x64 OLED (Lengthy! Mostly timezone work after that post.)
GPS 7 Segment Speedometer

Pay special attention to Choosing Your Serial Port connection and the required level-shifting for safely connecting the 3.3V NEO-6M to your 5V Arduino.

Cheers,
/dev

Thanks Dev, I shall follow that up and let you know how it goes.

I have now a sketch that gives me all the data from the GPS. All I want from this is the speed (in KMH) and to display it of a seven segment display. Any suggestions as to how this is achieved?

you need to use Haversine Formula

bazzlance:
I have now a sketch that gives me all the data from the GPS. All I want from this is the speed (in KMH)

As I said before, the only library I've used already gives the speed. Why not just use a library? Or are you?

bazzlance:
display it of a seven segment display.

Have you tried a sketch which just gets your display working? There's a library for that in the Playground. Once you have the value (and as I said, I think any gps library will give you that anyway), displaying it assuming you have the 7-segment display set up and tested,is trivial.

bazzlance:
All I want from this is the speed... Any suggestions as to how this is achieved?

A 7-segment example was suggested in reply #3. It shows how to display just the speed. Do you have questions about that example or some other program?

Do you have the 7-segment display hardware?

Which Arduino are you using?

Do you have a schematic?

mudassir9999:
you need to use Haversine Formula

No. Even when you are not moving, GPS jitter will make it look like you are moving. Using distance to calculate speed will also reflect the jitter (try the NeoGPS example NMEAaverage.ino). The GPS device provides a speed that is a better estimate, because it may use other data besides apparent location. Here's how the above example gets and displays the speed:

    if (fix.valid.speed) {

      int speed_mph = (fix.spd.whole * 115) / 100;  // integer MPH from knots...
      //float speed_mph = fix.speed_mph();          // ... or floating point MPH from knots
      //speed_mph = random( 0, 100 ); // uncomment this for testing

      clockDisplay.println( speed_mph );

Also, GPS is not very good below 5kph, so I would blank the display or display a zero. Some GPS devices allow you to set a threshold for the speed.

I have now developed an accurate GPS speed indicator (in Kmph) with help from -Dev and others in the forum. I will solder the wiring to make a permanent structure instead of the jumper leads and put it in a box. I have used a UNO board with a prototype shield. I have pruned the program to bare essentials and greatly shortened the queries to the satellites in order to get a good readout on the Sevseg LED with little flicker. I shall attempt to attach the Sketch to this post.
/******************************************************************************
*A0 to GPS Module TX: A1 to GPS Module RX: 5v to GPS Module VCC: Gnd to GPS Module Gnd *
*Digital pins 2,3 4.5 go through 330 ohm resistors to sevseg pins 12,9,8 & 6 respectively *
*Digital pins 6, 7, 8, 9, 10, 11, 12, 13 go to sevseg pins 11, 7, 4, 2, 1, 10, 5, 3 respectively *

  • 12 11 10 9 8 7 *
  • ___ ___ ___ ___ *
  • [][][][] *
  • []{][][]o *
  • 1 2 3 4 5 6 *
    *My thanks to Mikal Hart for TinyGPS library and -Dev for his advice. Bazzlance *
    ******************************************************************************/

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <SevSeg.h>
int Speed=0;
void gpsdump(TinyGPS &gps);
void printFloat(double f, int digits = 0);

SevSeg sevseg; //Instantiate a seven segment object
SoftwareSerial mySerial(A0,A1);
TinyGPS gps;

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);

byte numDigits = 4;
byte digitPins[] = {2, 3, 4, 5};
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
//Note the use of analogue pins A0 & A1 for the Module Tx & Rx respectively
sevseg.begin(COMMON_ANODE, numDigits, digitPins, segmentPins);
sevseg.setBrightness(15);
}

void loop()
{
bool newdata = false;
unsigned long start = millis();
// Every .001 seconds we print an update
while (millis() - start <1)
{
if (mySerial.available())
{
char c = mySerial.read();
//Serial.print(c); // uncomment to see raw GPS data
if (gps.encode(c))
{
newdata = true;
}
}
}
if (newdata)
{
gpsdump(gps);
}
// Serial.print(Speed);Serial.print(" kmh");Serial.println();//Uncomment to view results on Serial Monitor
sevseg.setNumber(Speed,0);
sevseg.refreshDisplay();
}

void gpsdump(TinyGPS &gps)
{
printFloat(gps.f_speed_kmph()); Serial.println();
}

void printFloat(double number, int digits)
{
// Handle negative numbers
if (number < 0.0)
{
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;

number += rounding;

// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
Speed = int_part; //This what we will display on SevSeg
}

Please edit that post to use code tags for the code.

bazzlance:
I have now developed an accurate GPS speed indicator (in Kmph)... I have pruned the program to bare essentials and greatly shortened the queries to the satellites in order to get a good readout on the Sevseg LED with little flicker.

Too much code! :smiley:

Here's the NeoGPS/NeoSWSerial version:

/******************************************************************************
 *A0 to GPS Module TX: A1 to GPS Module RX:   5v to GPS Module VCC: Gnd to GPS Module Gnd *
 *Digital pins 2,3 4.5 go through 330 ohm resistors to sevseg pins 12,9,8 & 6 respectively           *
 *Digital pins 6, 7, 8, 9, 10, 11, 12, 13 go to sevseg pins 11, 7, 4, 2, 1, 10, 5, 3 respectively       *
 *                                                                                                                                         *
 *                         12 11 10 9  8  7                                                                                         *
 *                       ___  ___  ___  ___                                                                                      *
 *                      [___][___][___][___]                                                                                   *
 *                      [___]{___][___][___]o                                                                                 *
 *                         1  2  3  4  5  6                                                                                            *
 ******************************************************************************/

#include <NeoSWSerial.h>
#include <NMEAGPS.h>
#include <SevSeg.h>

int Speed=0;

SevSeg sevseg; //Instantiate a seven segment object
NeoSWSerial gpsPort(A0,A1);
NMEAGPS gps;

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // set the data rate for the software serial port
  gpsPort.begin(9600);

  byte numDigits = 4;
  byte digitPins[] = {2, 3, 4, 5};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  //Note the use of analogue pins A0 & A1 for the Module Tx & Rx respectively
  sevseg.begin(COMMON_ANODE, numDigits, digitPins, segmentPins);
  sevseg.setBrightness(15); 
}

void loop()
{
  if (gps.available( gpsPort )) {
    gps_fix fix = gps.read();
    Speed = (int) ((uint32_t)fix.spd.whole * 1852UL)/1000UL; // avoids floating-point
    Serial.print(Speed);Serial.println( F(" kmh") );
    sevseg.setNumber(Speed,0);
    sevseg.refreshDisplay();
  } 
}

Your original sketch uses 8760 bytes of program space and 599 bytes of RAM.
The NeoGPS version uses 7082 bytes of program space and 440 bytes of RAM.

You may notice that the NeoGPS version has no flicker. If you'd like to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.

Thank you Karma. You mention the NeoGPS library which I already have but in the sketch you include NMEAGPS and not NeoGPS. Therefore it will not compile. Please advise.

bazzlance:
You mention the NeoGPS library which I already have but in the sketch you include NMEAGPS and not NeoGPS. Therefore it will not compile. Please advise.

NeoGPS supports several different protocols: NMEA standard, ublox proprietary $PUBX and ublox binary UBX.

Since your sketch only needs the standard NMEA parsing (e.g., RMC sentence), you only include "NMEAGPS.h". There is no "NeoGPS.h" file.

If you are getting a compile error, either you do not have the NeoGPS library, or it is not installed correctly. Please review the Installation instructions. Post the error message you are getting if you are still having trouble.

Thank you Karma. The compile error seems to related to NeoSerialGPS

C:\Program Files (x86)\Arduino\libraries\NeoSWSerial\src/NeoSWSerial.h:62:1: error: expected unqualified-id before 'class'

class NeoSWSerial : public Stream

^

C:\Program Files (x86)\Arduino\libraries\NeoSWSerial\src/NeoSWSerial.h:62:1: error: expected constructor, destructor, or type conversion before 'class'

Using library NeoSWSerial at version 3.0.5 in folder: C:\Program Files (x86)\Arduino\libraries\NeoSWSerial
Using library NeoGPS at version 4.2.2 in folder: C:\Program Files (x86)\Arduino\libraries\NeoGPS
Using library SevSeg at version 3.3.0 in folder: C:\Program Files (x86)\Arduino\libraries\SevSeg
exit status 1
Error compiling for board Arduino/Genuino Uno.

Did you copy the exact code from reply #11? Is it possible you missed something? Perhaps you accidentally typed something before the first include?

Please attach the INO file you are compiling.

/*********************************************************
*A0 to GPS Module TX: A1 to GPS Module RX: 5v to GPS Module VCC: Gnd to GPS Module Gnd *
*Digital pins 2,3 4.5 go through 330 ohm resistors to sevseg pins 12,9,8 & 6 respectively *
*Digital pins 6, 7, 8, 9, 10, 11, 12, 13 go to sevseg pins 11, 7, 4, 2, 1, 10, 5, 3 respectively. *

  • 12 11 10 9 8 7 *
  • ___ ___ ___ ___ *
  • [][][][] *
  • []{][][]o *
  • 1 2 3 4 5 6 *
    **************************************************************************************************/
    //My thanks to Karma for this version.
    #include <NeoSWSerial.h>
    #include <NMEAGPS.h>
    #include <SevSeg.h>

int Speed=0;

SevSeg sevseg; //Instantiate a seven segment object
NeoSWSerial gpsPort(A0,A1);
NMEAGPS gps;

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
// set the data rate for the software serial port
gpsPort.begin(9600);

byte numDigits = 4;
byte digitPins[] = {2, 3, 4, 5};
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
//Note the use of analogue pins A0 & A1 for the Module Tx & Rx respectively
sevseg.begin(COMMON_ANODE, numDigits, digitPins, segmentPins);
sevseg.setBrightness(15);
}

void loop()
{
if (gps.available( gpsPort )) {
gps_fix fix = gps.read();
Speed = (int) ((uint32_t)fix.spd.whole * 1852UL)/1000UL; // avoids floating-point
Serial.print(Speed);Serial.println( F(" kmh") );
sevseg.setNumber(Speed,0);
sevseg.refreshDisplay();
}
}

bazzlance:
//My thanks to Karma for this version.

Karma's not a member's name, unless we're all called Karma? :wink:

My mistake, I guess that should have been -Dev

It's missing the first character, a slash: '/'. This is required to start the big comment block at the top. You get a weird error message that appears to be in NeoSWSerial, but it's actually a problem in the code that included NeoSWSerial.h (the INO file).

Also, use code tags around your code: [code] ...code in here...  [/code]

 ... so it looks 
   like this...

...or attach the file, like I requested.

You can either type those tags in, before and after your code.

Or you can select all the code with your mouse (or SHIFT+arrow keys), then press the "Code" button in the upper left. It looks like "</>".

Or, press "Preview" on your reply to get to the full post editor window. Then open the Attachments and other options in the lower left. Then choose your INO file, and it will be uploaded with your post.

These are both described in How to use this forum.