Maybe it's smart enough to know that a speed inside the margin of error is fake so prints 0. Until you put it in a car it's a guess. I would remove that guess.
That would be a really frustrating feature, but I suppose it might be plausible. This whole debacle started because I noticed the Adafruit Ultimate GPS was "smoothing" the speed readings it sent out. For use in a car speedometer, this led to extremely slow responsiveness when accelerating to say 40mph from a stop; the GPS would start giving a 40mph reading about 5 to 7 seconds after the car actually hit 40mph.
your code snippet appears to be echoing what is received from the GPS before TinyGPS++ does anything with it. So the GPS is reporting a 0 speed over ground. Even if you have code that you haven't shown that does parse the GPS output, all it can do it report what the GPS outputs: in this case, a speed over ground of 0.
OK now I understand this statement better. Yes that make sense, the GPS sends the sentence with the "0.00" speed, so perhaps this is a GPS issue rather than a TinyGPS++ issue.
For information on how to customize the data that TinyGPS++ collects and interprets, see this page: TinyGPS++ | Arduiniana
Thanks, this was an interesting read but I didn't spot anything in there that seemed like an explanation for what I am seeing. Full code is below though, in case it unlocks any other ideas or thoughts. Thanks again for taking the time to read/respond!
// MODE: CHOOSE WHICH GPS IS CONNECTED
//#define Adafruit
//#define NEO6M
#define NEOM8N
#include <SoftwareSerial.h>
#include <Wire.h>
#include <TinyGPS++.h>
#define rxPin 5
#define txPin 4
SoftwareSerial neogps(rxPin, txPin);
TinyGPSPlus gps;
int currentSpeed = 0;
int accuracyAdjustment = 0;
uint8_t speedSmoothingFactor = 3; // 0 = no speed smoothing. non-zero indicates the most recent data point is weighted by (1 / speedSmoothingFactor)
int GPSknots;
float trailingAverageKnots;
bool newGPSdata = false;
// need this funky code method to send 5hz command to the NEO GPS; there seems to be no $PUBX way to do it
const unsigned char ubxRate5Hz[] PROGMEM = { 0x06, 0x08, 0x06, 0x00, 200, 0x00, 0x01, 0x00, 0x01, 0x00 };
const unsigned char ubxRate10Hz[] PROGMEM = { 0x06, 0x08, 0x06, 0x00, 100, 0x00, 0x01, 0x00, 0x01, 0x00 }; // totally guessing based on the above
void setup() {
#ifdef Adafruit
Serial.begin(57600);
#endif
#ifdef NEO6M
Serial.begin(38400);
#endif
#ifdef NEOM8N
Serial.begin(38400);
#endif
// SPEEDOMETER GPS data feed
neogps.begin(9600);
delay(50);
#ifdef Adafruit
neogps.println("$PMTK251,57600*2C"); //set baud rate to 57600
//neogps.println("$PMTK251,115200*1F"); //set baud rate to 115200
//neogps.println("$PMTK251,74880*2B"); //set baud rate to 74880
//neogps.println("$PMTK251,38400*27"); //set baud rate to 38400
#endif
#ifdef NEO6M
//neogps.println("$PUBX,41,1,3,3,38400,0*38\r\n"); // 38400 baud rate
#endif
#ifdef NEOM8N
// defaults to 9600 and I don't yet know how to change it
#endif
delay(50);
neogps.end();
delay(50);
#ifdef Adafruit
// for Adafruit GPS
neogps.begin(57600);
neogps.println("$PMTK220,100,0,0,0,0*2F"); //NMEA update 10hz
//neogps.println("$PMTK220,1000,0,0,0,0*1F"); //NMEA update 1hz
//neogps.println("$PMTK300,200,0,0,0,0*2F"); //NMEA update 5hz
neogps.println("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); // I think this should print out only RMC sentences
#endif
#ifdef NEO6M
neogps.begin(9600);
// for ublox NEO 6M: https://gist.github.com/laroo/346674840c25db9d86e532c33e255cc3
neogps.println("$PUBX,40,GLL,0,0,0,0*5C\r\n"); // Disable GLL
neogps.println("$PUBX,40,ZDA,0,0,0,0*44\r\n"); // Disable ZDA
neogps.println("$PUBX,40,VTG,0,0,0,0*5E\r\n"); // Disable VTG
neogps.println("$PUBX,40,GSV,0,0,0,0*59\r\n"); // Disable GSV
neogps.println("$PUBX,40,GSA,0,0,0,0*4E\r\n"); // Disable GSA
neogps.println("$PUBX,40,GGA,0,0,0,0*5A\r\n"); // Disable GGA
//sendUBX( ubxRate5Hz, sizeof(ubxRate5Hz) ); // 5hz updates - supposed to be the max
sendUBX( ubxRate10Hz, sizeof(ubxRate10Hz) ); // 10hz updates - ACTUALLY WORKS!!!
#endif
#ifdef NEOM8N
neogps.begin(9600);
// for ublox NEO M8N: https://gis.stackexchange.com/questions/198846/enabling-disabling-nmea-sentences-on-u-blox-gps-receiver
byte GGAoff[] = {0xb5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, 0xb5, 0x62, 0x06, 0x01, 0x02, 0x00, 0xf0, 0x00, 0xf9, 0x11}; //GGA OFF
byte GLLoff[] = {0xb5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2b, 0xb5, 0x62, 0x06, 0x01, 0x02, 0x00, 0xf0, 0x01, 0xfa, 0x12}; //GLL OFF
byte GSAoff[] = {0xb5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xf0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, 0xb5, 0x62, 0x06, 0x01, 0x02, 0x00, 0xf0, 0x02, 0xfb, 0x13}; //GSA OFF
byte GSVoff[] = {0xb5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39, 0xb5, 0x62, 0x06, 0x01, 0x02, 0x00, 0xf0, 0x03, 0xfc, 0x14}; //GSV OFF
byte VTGoff[] = {0xb5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xf0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05, 0x47, 0xb5, 0x62, 0x06, 0x01, 0x02, 0x00, 0xf0, 0x05, 0xfe, 0x16}; //VTG OFF
byte ZDAoff[] = {0xb5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5b}; //ZDA OFF
byte disableGLONASS[] = {0xB5, 0x62, 0x06, 0x3E, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x01, 0x06, 0x08, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB2}; // GLONASS satellites ignored
neogps.write(GGAoff, sizeof(GGAoff));
neogps.write(GLLoff, sizeof(GLLoff));
neogps.write(GSAoff, sizeof(GSAoff));
neogps.write(GSVoff, sizeof(GSVoff));
neogps.write(VTGoff, sizeof(VTGoff));
neogps.write(ZDAoff, sizeof(ZDAoff));
neogps.write(disableGLONASS, sizeof(disableGLONASS));
// end NEO M8N
#endif
}
void loop() {
feedGPS();
}
void feedGPS() {
while (neogps.available()) {
int c = neogps.read();
Serial.write(c);
if (gps.encode(c)) {
newGPSdata = true;
}
}
if (newGPSdata == true) {
newGPSdata = false;
if (gps.location.isValid()) {
if (gps.speed.isUpdated()) {
GPSknots = gps.speed.knots();
}
}
if (speedSmoothingFactor == 0) {
currentSpeed = gps.speed.mph();
}
else {
trailingAverageKnots = (trailingAverageKnots * (speedSmoothingFactor - 1)) + gps.speed.knots();
trailingAverageKnots = trailingAverageKnots / speedSmoothingFactor;
currentSpeed = (trailingAverageKnots * 115) / 100 + accuracyAdjustment;
}
if (currentSpeed <= 1) {
currentSpeed = 0;
}
else {
currentSpeed = currentSpeed + accuracyAdjustment;
}
}
}
void sendUBX( const unsigned char *progmemBytes, size_t len )
{
neogps.write( 0xB5 ); // SYNC1
neogps.write( 0x62 ); // SYNC2
uint8_t a = 0, b = 0;
while (len-- > 0) {
uint8_t c = pgm_read_byte( progmemBytes++ );
a += c;
b += a;
neogps.write( c );
}
neogps.write( a ); // CHECKSUM A
neogps.write( b ); // CHECKSUM B
}