Changing Baud Rate of GPS using neoGPS Library

Hello, I have made an "analog style" speedometer using the Adafruit Ultimate GPS Module, an Arduino Uno, and a Switec/Juken X25 stepper motor (to move the needle).
I have it working, but the movement of the needle is very jerky. It looks like it only "updates" its position at a rate of about 1hz, despite knowing it's actually updating at a rate of 10hz.

I contribute this to the GPS not sending knots data fast enough, though I read the datasheet and got more confused. I think the issue will be solved by increasing the baud rate (serial between GPS and Arduino), but I can't seem to get it to run at all at anything other than 9600kbps.

Here is my current code:

//using this module https://www.adafruit.com/product/746
#include <SoftwareSerial.h>
#include <NMEAGPS.h>
#include "SwitecX25.h"

int GPSb = 0;
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 100;  //the value is a number of milliseconds
float speed_mph = 0;

SoftwareSerial gpsSerial(8, 7); //connect digital 8 to tx and digital 7 to rx
NMEAGPS gps;

SwitecX25 motor1(315*3, 3,4,5,6); //create instance of first stepper

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) //creating a map function that works with floats but still returns an int
{
  return round( (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min );
}

const unsigned char SET_BAUD_38400[] PROGMEM = {
      0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x23, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x70
    }; // This is an example for 38400 baud, checksum included.

    void sendUBX(const unsigned char *progmemBytes, size_t len) {
      for (size_t i = 0; i < len; i++) {
        gpsSerial.write(pgm_read_byte(progmemBytes + i));
      }
    }

void setup()
{
  gpsSerial.begin(9600);
  //IF I UNCOMMENT THE BELOW LINES, IT DOESN'T WORK. THE NEEDLE DOES NOT MOVE.
  // sendUBX(SET_BAUD_38400, sizeof(SET_BAUD_38400));
  //   delay(100); // Give the module time to process
  // gpsSerial.end();
  // gpsSerial.begin(38400); // Change to the new baud rate
  // gps.send_P( &gpsSerial, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only
  gps.send_P( &gpsSerial, F("PMTK220,50") ); //set update rate
  motor1.zero(); //zero the needle
}

void loop()
{
  motor1.update(); //send motor to the last poisition determined by motor1.setPosition
  // Process GPS chars
  while (gps.available( gpsSerial ))
  {
    //  A new fix has been assembled from processed chars
    gps_fix fix = gps.read();
    if (fix.valid.speed) {
      //get the floating point (with decimals) MPH like this:
      float speed_mph = fix.speed_mph();
      //float speed_mph_filtered = adcFilter1.filter(speed_mph);
      GPSb = mapfloat(speed_mph, 0, 120, 0, 945); //scale the voltage to represent steps of the motor instead
    } 
  }
  currentMillis = millis();
  if (currentMillis - startMillis >= period) { 
   startMillis = currentMillis;
   motor1.setPosition(GPSb); //update the motor's target position
  }
}

Note the section that's commented out, which is supposed to increase the baud rate.
I read through other topics similar to this, and none of the advice in those has worked for me. Please help!

Is it the baud rate that you need to change or the update period ? The latter is usually set to 1Hz for GPS modules

The datasheet surely tells useful facts. Please post a link to it if You don’t feel comfortable reading it.

Any code that uses SoftwareSerial will experience timing problems due to the receive interrupts. The solution to that is to use an Arduino with more than one hardware serial port, as most of the modern ones do, and a better library, like TinyGPS++.

Most modern GPS modules offer higher serial baud rates as well.

I will try TinyGPS++, thank you for the tip!
I don't understand why having just one serial port is bad in this case though?

Right, that was the default for this module, but I have changed it to a bunch of different value up to 10hz (max for the gps chip) with no change unfortunately.

On Arduino Uno R3, Classic Nano, Mega, etc. the one available hardware serial port is used for the serial monitor, debugging and program upload.

I think this is a silly question, so sorry in advance if it is, but why would that affect performance when I'm running the device with no debugger connected, and no other serial instances besides the gps?

The code you posted does not use a hardware serial port. It uses SoftwareSerial, which causes timing problems.

Here is ispa1616s
I must admit despite playing with code for a long time I'm still very much a novice and understanding datasheets is my weakest area. I would appreciate very much if you wanted to take the time to read it as well!!

Oh duh. I misunderstood your first answer. Sorry and thanks so much. I think I have a mega sitting around that I can try hardwareSerial out and will update this with any findings!

With the Mega you can use Serial1, 2 or 3 with TinyGPS++. Make sure to connect the GPS module to the correct Arduino pins for the serial port you select.

You may need to use 5V to 3.3V logic level shifters for the GPS, unless it has them built in. Otherwise you will damage the GPS module, so be sure to check the module data sheet.

Regards

I wired it up to an arduino Mega using Serial1 (D17,D18) for the communication with the GPS module. I wanted to keep using the NeoGPS library because it is more efficient and faster than any other one I've tried, though I havent tried TinyGPS++.
With a few additional tweaks here and there I was able to smooth out the needle's motion somewhat.
I tried the EWMA library to "artificially" smooth out the needle's motion, but that introduced too much latency to its movement.
I still suspect that the serial baud rate is too slow at 9600, due to the other stuff sent by the GPS module in the same packet that contains "Knots" (the only one I care about). I remain unable to increase the baud rate. I KNOW it's possible to do using the neoGPS library, I just don't understand why it's not working.
Here is my code as of right now:

//using this module https://www.adafruit.com/product/746 (Yes it is 5V)

#include <NMEAGPS.h>
#include <GPSport.h> //this file was altered to make sure Serial1 (HW) is being used
#include "SwitecX25.h"
#include "Ewma.h"

int GPSb = 0;
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 10;  //the value is a number of milliseconds
int speed_mph = 0;

NMEAGPS gps;

SwitecX25 motor1(315*3, 2,3,4,5); //create instance of first stepper

void setup()
{
  gpsPort.begin(9600);
  //IF I UNCOMMENT THE BELOW LINES, IT DOESN'T WORK. THE NEEDLE DOES NOT MOVE.
  ////sendUBX(SET_BAUD_38400, sizeof(SET_BAUD_38400));
  ////  delay(100); // Give the module time to process
  // gps.send_P( &gpsPort, F("$PMTK251,38400*27") );
  // delay(1000);
  // Serial1.end();
  // gpsPort.begin(38400); // Change to the new baud rate
  gps.send_P( &gpsPort, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only
  gps.send_P( &gpsPort, F("PMTK220,100*2F\r\n") ); //set update rate
  motor1.zero(); //zero the needle
}

void loop()
{
  // Process GPS chars
  while (gps.available( gpsPort ))
  {
    //  A new fix has been assembled from processed chars
    gps_fix fix = gps.read();
    if (fix.valid.speed) {
      int speed_mph = fix.speed_mph();
      GPSb = map(speed_mph, 0, 120, 0, 945); //scale the mph to represent steps of the motor instead
      motor1.setPosition(GPSb); //update the motor's target position
    } 
  }
   currentMillis = millis();
   if (currentMillis - startMillis >= period) { 
     startMillis = currentMillis;
     motor1.update();
   
   }
}