Global variables won't update in loop. GPS speed stays the same.

Hello!
I am trying to make a GPS speedometer with a servo output. I have Arduino UNO, NEO-6M gps module, a small servo and a breadboard power supply.

So far, Arduino gets GPS signal and drives the servo good. However, variables that contain speed or servo angle do not update after they get an initial value. Once there is a speed reading, it does not change anymore. Also it takes about 10 minutes to get a reading sometimes.

I tried ending and starting Serial at the end of the loop in case there is a buffer overflow, no result. Also tried declaring variables inside the loop for them to be discarded, nothing. I tried replacing while with if as well. Tried having no arduino TX>gpsRX wire, no impact. Also experimented with delay and millis to slow down the loop.

Also, I can’t upload code to the Arduino until I switch off the breadboard power supply that powers GPS and servo. Somehow it seems related to me.

Here is the code:

#include <TinyGPS++.h>
#include <Servo.h>

double spd;//variable for gps speed with decimals
int servoPosition;//variable for servo degrees
int intspeed;//speed as a whole number
static const int RXPin = 0, TXPin = 3; //gps pins (leftover from SoftwareSerial)
static const uint32_t GPSBaud = 9600;

Servo myservo;  // create servo object to control a servo
TinyGPSPlus gps; // The TinyGPS++ object

void setup() {
  Serial.begin(GPSBaud);
  Serial.println("power on");//test serial
   myservo.attach(9);  // attaches the servo on pin 9 to the servo object
   myservo.write(180);//move servo to the leftmost position
}
void loop() {
  
  while (Serial.available()>0){
    gps.encode(Serial.read());

    if (gps.location.isUpdated()){  //when gps connects
     spd = gps.speed.mph();//get gps speed 
      Serial.println("Speed= "); 
      Serial.println(spd);//print gps speed to serial
      intspeed = spd;//make speed an integer, so servo can take it
       Serial.println(intspeed);//test the int 
      
      servoPosition = map(intspeed, 0, 180, 180, 0);//map gps speed into a whole number of degrees from 180 to 0. (180 is the leftmost position on my servo, 0 is rightmost)
      servoPosition--;//test if the value can change with each run; it does not
      Serial.println(servoPosition);//print servo position to serial
      myservo.write(servoPosition); //move needle according to speed
      
    }
  }
}

I attached a wiring diagram as well as a screenshot of a typical output. Notice how servo degrees don’t change even though there is – in the loop.

Anyone has any experience with this?
Thank you all in advance!

output.jpg

You are using hardware serial (Serial) for the GPS and serial monitor at the same time? That is why you have to disconnect the GPS to upload. You can connect only one thing to a serial port. Most people use a software serial port for the GPS and Serial for program upload, output and debug if there is only one hardware serial port

groundFungus:
You are using hardware serial (Serial) for the GPS and serial monitor at the same time? That is why you have to disconnect the GPS to upload. You can connect only one thing to a serial port. Most people use a software serial port for the GPS and Serial for program upload, output and debug if there is only one hardware serial port

Can Serial Monitor be the cause of the problem? Should I disconnect it for testing? It's weird that even simple arithmetic operation like ++ does not work in this setup.
Thank you for the input!
I use Hardware Serial because SS is not compatible with servos, makes them tick like a clock because of timers and interrupts. Even ServoTimer2.h did not help with that, so I switched to Hardware Serial and it solved the problem.
Thanks again!

The Servo library and SoftwareSerial both use Timer1. You could use the ServoTimer2 library (instead of the Servo library) for the servo to resolve the conflict

I would suggest that you get the GPS to work and output the values that you want by itself using a software serial library. Get the servo to work with the ServoTimer2 library by itself and then merge the two codes. That is how I would do it.

Thank you, I will try that again!

You could use the NeoGPS library. I use it as well with the same kind of GPS. It's highly customizable, much faster and requires way less program memory. And if you customize the library files itself, you can turn off gps parsing for things you don't need. For example, you could drop the time if you don't need it in your project. Faster parsing and faster libraries mean faster updates on your speedometer, although I'm not quite sure if a GPS is any good for that kind of use, especially if it needs to be realtime and precise.

Also, like mentioned before, you can't connect 2 things to the serial pins on most arduino boards. I would still advice you to use TX/RX for the GPS because it is faster.