GPS not getting any fix. Why?

Sun spots.
Your wiring is wrong.
The satellites have been knocked out of orbit by gravitational anomalies.

I like being silly for guessing games. :wink:

But this one is so common with GPS units. We work with a LOT of satellite communication where I work.
Some units work at the developer's desk.
Some need to be used by a south facing window.
And a whole bunch need to be taken out on the roof.

It is the nature of the beast.

Metal will block GPS reception. Make sure no metal is between your GPS and the sky.

Have you verified that you're seeing the output, and it's just not getting a fix (vs your library just saying there's no fix - because it's not hearing anything from the GPS at all)

Yes. I am printing the GPS sentence directly (no parsing at all). It just gives me zeroes for all values... (and the no fix message)

I've soldered it onto a board with a lot of metal on it---What could possible reasons be?

Perhaps the soldering needs looked at with goggles on. That board is perf-board, not exactly a ground plane. It is easy to have a bad connection. If you plugged another in and it worked, check your pins on the gps module. Make sure you didn't burn a trace.

Most places test their products before shipping, some are less trustworthy. It is possible it was a bad unit. It is possible it got zapped by static. It's possible someone else hooked it up to 5v and cooked it and then returned it.

Your chance of getting a fix on one of those GPSs, with the ceramic stick antenna, indoors are remote indeed.

The antenna just does not have enough gain.

They struggle out of doors in some cases too, bu they work OK in their intended application, high altitude balloons.

See some details on the comparative performance of some types of GPS antenna on those Ubloxes GPSs here.

Oh, and use static precautions when handling those Ubloxes GPSs the antenna input is extremely sensitive to static damage, they can go low signal or simply stop working.

Oh, and those GPSs start up in GLONASS mode, so if your 'code' does not recognise this or configure the GPS out of GLONASS mode, the 'code' may never report a fix.

But then, you did not say which 'code' you are using or what the 'another' GPS was so we can only guess.

A unit that has lost battery backup has no almanac (meaning it has no idea what time it is or approximately where in the world it is). That forces it to do a different, lengthy search algorithm that can take up to 15 minutes to get a first fix. Some units have batteries that can drain if it isn't powered in a while. So those have to be powered and placed outdoors at least the first time before they will work indoors.

Ok good news. Seems the inside testing was the problem. I have finally got a fix. I didn't realize that the antenna is so weak.

Anyway: Here's the code I use:

#include <SoftwareSerial.h>
SoftwareSerial GPS(3, 5);
byte gps_set_sucess = 0 ;
char gpssentence[66];

void setup()
{
  GPS.begin(9600); 
  // START OUR SERIAL DEBUG PORT
  Serial.begin(9600);
  Serial.println("GPS Level Convertor Board Test Script");
  Serial.println("03/06/2012 2E0UPU");
  Serial.println("Initialising....");
  //
  // THE FOLLOWING COMMAND SWITCHES MODULE TO 4800 BAUD
  // THEN SWITCHES THE SOFTWARE SERIAL TO 4,800 BAUD
  //
  GPS.print("$PUBX,41,1,0007,0003,4800,0*13\r\n"); 
  GPS.begin(4800);
  GPS.flush();
 
  //  THIS COMMAND SETS FLIGHT MODE AND CONFIRMS IT 
  Serial.println("Setting uBlox nav mode: ");
  uint8_t setNav[] = {
    0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 
    0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC };
  while(!gps_set_sucess)
  {
    sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t));
    gps_set_sucess=getUBX_ACK(setNav);
  }
  gps_set_sucess=0;
 
//ADDED THIS//////////////////////////////////////////////////////////////////////////////////////  
GPS.println("$PUBX,40,GLL,0,0,0,0*5C");
GPS.println("$PUBX,40,GGA,0,0,0,0*5A");
GPS.println("$PUBX,40,GSA,0,0,0,0*4E");
GPS.println("$PUBX,40,RMC,0,0,0,0*47");
GPS.println("$PUBX,40,GSV,0,0,0,0*59");
GPS.println("$PUBX,40,VTG,0,0,0,0*5E");
////////////////////////////////////////////////////////////////////////////////////////////////////

}
 
void loop()
{
  //ADDED THIS////////////////////////////////////////////////////////////////////////////////////

  
  GPS.println(F("$PUBX,00*33"));
   
   unsigned long previousMillis = millis();
   unsigned long currentMillis = millis(); 
  while (currentMillis - previousMillis <= 3000) {
    
    // wait for GPS sentence to arrive
    
     currentMillis = millis();
  }


  while (GPS.available())
{
    for (int i=0; i <66 ; i++)
    {   
      gpssentence[i] = GPS.read();
    }
}
}   
 
 
// Send a byte array of UBX protocol to the GPS
void sendUBX(uint8_t *MSG, uint8_t len) {
  for(int i=0; i<len; i++) {
    GPS.write(MSG[i]);
    Serial.print(MSG[i], HEX);
  }
  GPS.println();
}
 
 
// Calculate expected UBX ACK packet and parse UBX response from GPS
boolean getUBX_ACK(uint8_t *MSG) {
  uint8_t b;
  uint8_t ackByteID = 0;
  uint8_t ackPacket[10];
  unsigned long startTime = millis();
  Serial.print(" * Reading ACK response: ");
 
  // Construct the expected ACK packet    
  ackPacket[0] = 0xB5;  // header
  ackPacket[1] = 0x62;  // header
  ackPacket[2] = 0x05;  // class
  ackPacket[3] = 0x01;  // id
  ackPacket[4] = 0x02;  // length
  ackPacket[5] = 0x00;
  ackPacket[6] = MSG[2];  // ACK class
  ackPacket[7] = MSG[3];  // ACK id
  ackPacket[8] = 0;   // CK_A
  ackPacket[9] = 0;   // CK_B
 
  // Calculate the checksums
  for (uint8_t i=2; i<8; i++) {
    ackPacket[8] = ackPacket[8] + ackPacket[i];
    ackPacket[9] = ackPacket[9] + ackPacket[8];
  }
 
  while (1) {
 
    // Test for success
    if (ackByteID > 9) {
      // All packets in order!
      Serial.println(" (SUCCESS!)");
      return true;
    }
 
    // Timeout if no valid response in 3 seconds
    if (millis() - startTime > 3000) { 
      Serial.println(" (FAILED!)");
      return false;
    }
 
    // Make sure data is available to read
    if (GPS.available()) {
      b = GPS.read();
 
      // Check that bytes arrive in sequence as per expected ACK packet
      if (b == ackPacket[ackByteID]) { 
        ackByteID++;
        Serial.print(b, HEX);
      } 
      else {
        ackByteID = 0;  // Reset and look again, invalid order
      }
 
    }
  }
}

I have 2 questions:

  1. Have I set the GPS to altitude mode correctly (->Will this work if i stick it in a HAB balloon?)

  2. When I print the "gpssentence[]" Buffer I always get some corrupted characters. It usually looks something like this:

$PUBX,00,154106.00,4732.65609,N,00733.55878,E,364.181,G3,12,19,���,

So normally this wouldn't irritate me in the least as no actual data is ever corrupted. However I want to use this sentence in a CSV file, meaning that every gps sentence should have the same number of commas in it. However, often they do not. So what could I do to solve this problem? I do not want to parse any of the sentence. I want it raw, and also I don't whant to use any libraries (seeing as I've already got memory problems in my project)

That sentence seems to have more than 65 characters. Have you checked the length?

bestanamnetnogonsin:
I don't want to use any libraries (seeing as I've already got memory problems in my project)

Challenge accepted! :wink:

It seems counter-intuitive, but NeoGPS can almost certainly make your program smaller, faster and more accurate. With the proper configuration, a NeoGPS sketch has always been hundreds or thousands of bytes smaller than the original program. Since you aren't parsing anything yet, and it doesn't quite work, you won't see the same program size reduction, but it can save a lot of RAM, though.

Is that your entire program? I don't know if it's important to you, but it's going to miss some updates, and it may not even save the whole sentence. The baud rate command probably doesn't work, either. But...

Would you use 1300 bytes of program space to save 400 bytes of RAM and get reliable logging?

Do you use any of the GPS information? Maybe an altitude test? Or is it just for logging?

You could also save several thousand bytes of program space if you put the GPS on pins 0 & 1. Then, you wouldn't need SoftwareSerial. You could still do debug prints, but you'd have to disconnect the Arduino RX wire (to GPS TX) to upload a new sketch.

Coincidentally, most of the NeoGPS examples output a CSV format of the parsed values. I import them into a spreadsheet all the time.

Cheers,
/dev

stowite:
2) When I print the "gpssentence[]" Buffer I always get some corrupted characters. It usually looks something like this:

$PUBX,00,154106.00,4732.65609,N,00733.55878,E,364.181,G3,12,19,���,

Are you 'printing' more characters than is in the buffer perhaps ?

Are you 'printing' more characters than is in the buffer perhaps ?

In this example I do, yes. However that is intentional, as I need a "reserve" in the array because the length of the gps string is not always the same. The problem is that even If I give the buffer a starting value, say: 66 times '0' I get these corrupt characters when printing the entire buffer.

Also, that definitely is the entire message. I've tried with a 80 bit buffer too.

Seems the OP did not read my previous post. I think the message is more than the 65 characters long (the buffer size 66 -1 for the terminating zero) so is writing outside the buffer reserved for it. Any write to a variable declared following the buffer declaration could be overwriting the end of the message and so showing up as corrupt characters in the message!

stowite:
Seem the OP did not read my previous post.

Or mine. -_-

bestanamnetnogonsin:
that definitely is the entire message.

No, that's not the entire message, for a variety of reasons.

Why save the message if you're just printing it? That's just an echo program:

void loop()
{
  if (GPS.available())
    Serial.write( GPS.read() );
}

I'm sorry if I have misunderstood something, but I have already used the function -dev- posted to print the sentence:

void loop()
{
  if (GPS.available())
    Serial.write( GPS.read() );
}

I only got what I get using my other function. Therefore I assumed that this was the whole message? But maybe I am wrong?

The reason I am saving it is because, apart from printing it, my entire program (which is more than 500 lines long, and I therefore have not posted) also saves the sentence to an SD card and transmits it via Radio. Therefore it is handy to have it saved in a buffer.

One last try ! IF THE MESSAGE IS LONGER THAN THE 65 CHARACTER BUFFER ALLOCATED TO HOLD IT THEN YOU MAY BE WRITING BEYOND THE END OF THE BUFFER!

Look, maybe I'm missing something here, but if I do not use the buffer at all, and instead only print the sentence with this function:

void loop()
{
  if (GPS.available())
    Serial.write( GPS.read() );
}

Then I only get a message of the same length as I posted. How can the message possibly be any longer than 65 chars?

bestanamnetnogonsin:
Look, maybe I'm missing something here, but if I do not use the buffer at all, and instead only print the sentence with this function:

void loop()

{
 if (GPS.available())
   Serial.write( GPS.read() );
}




Then I only get a message of the same length as I posted. How can the message possibly be any longer than 65 chars?

A quick count of the characters in the message you posted earlier indicated more than 65 characters. Have you printed out the length? If not then do so before doing anything else! If I am right then you have solved one of your problems. If I am wrong then you will have one less thing to eliminate.

Have you made sure the terminating NULL char is appended to the message?

When I write a sequence of characters to a character buffer I check that there is room before writing to it. I also add the terminating zero after each character is written; OK that may be overkill but it works.

bestanamnetnogonsin:
if I do not use the buffer at all, and instead only print the sentence with this function... Then I only get a message of the same length as I posted. How can the message possibly be any longer than 65 chars?

Because you must have other things in loop. That's not a function I provided, that's the only thing loop should do. That simple echo sketch will absolutely print the complete message.

I don't know why you think this is a complete message:

  $PUBX,00,154106.00,4732.65609,N,00733.55878,E,364.181,G3,12,19,���,

Here's an example from the ublox NEO-6 spec, section 21.2:

  $PUBX,00,081350.00,4717.113210,N,00833.915187,E,546.589,G3,2.1,2.0,0.007,77.52,0.007,,0.92,1.19,0.77,9,0,0*5F

Obviously, you are not saving the the whole sentence in your buffer. You are missing almost half of the data. Your program prints only what it was able to save. If you really want to "save the sentence to an SD card", just do this:

void loop()
{
  if (GPS.available())
    sdFile.write( GPS.read() );
}

You finally tell us that your sketch "transmits it via Radio. Therefore it is handy to have it saved in a buffer." Now we know a little more about what you're trying to do.

There are many ways to send GPS information over the radio. Raw NMEA data is the worst. The 111-byte PUBX sentence is 10x bigger than a binary radio message. Let's say you are sending lat, lon and altitude. Here is a simple text representation of those 3 numbers:

    48.11730,11.51667,545.5

That's 24 bytes, and the receiver has to parse the fields into numbers for calculations. Here is a binary representation of those 3 numbers:

    1CAE1E086DD4DCBD516

That's only 10 bytes (displayed with 20 hex characters). It could be sent with one transmission:

    radioSend( (uint8_t *) &gpsDataStruc, sizeof(gpsDataStrcut) );

... and the receiver would not have to parse anything. The received bytes can be copied directly onto a matching structure. If your radio (which radio?) can only send 32-byte packets, it would take 4 packets to send the raw data. If your radio takes longer than 250ms to send a packet, it can't keep up with the raw NMEA data stream.

The other problem in your sketch is that it uses delay. A contributing factor is that it uses SoftwareSerial.

FWIW, you can expect testy responses when you don't recognize contributors for offering suggestions. We all want to help -- the least you can do is acknowledge the transmission.

And the more information you tell us, the better the answers will be. If your code is too big to embed in a post, just attach it as a file with the Attachments and other options in the lower right-hand corner of the post editor.

Thank you for all of your answers. But what I have been trying too say is this: When I test the GPS with this sketch (nothing else):

#include <SoftwareSerial.h>
SoftwareSerial GPS(3, 5);
byte gps_set_sucess = 0 ;
 
void setup()
{
  GPS.begin(9600); 
  // START OUR SERIAL DEBUG PORT
  Serial.begin(9600);
  Serial.println("GPS Level Convertor Board Test Script");
  Serial.println("03/06/2012 2E0UPU");
  Serial.println("Initialising....");
  //
  // THE FOLLOWING COMMAND SWITCHES MODULE TO 4800 BAUD
  // THEN SWITCHES THE SOFTWARE SERIAL TO 4,800 BAUD
  //
  GPS.print("$PUBX,41,1,0007,0003,4800,0*13\r\n"); 
  GPS.begin(4800);
  GPS.flush();
 
  //  THIS COMMAND SETS FLIGHT MODE AND CONFIRMS IT 
  Serial.println("Setting uBlox nav mode: ");
  uint8_t setNav[] = {
    0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 
    0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC };
  while(!gps_set_sucess)
  {
    sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t));
    gps_set_sucess=getUBX_ACK(setNav);
  }
  gps_set_sucess=0;
 
//ADDED THIS//////////////////////////////////////////////////////////////////////////////////////  
GPS.println("$PUBX,40,GLL,0,0,0,0*5C");
GPS.println("$PUBX,40,GGA,0,0,0,0*5A");
GPS.println("$PUBX,40,GSA,0,0,0,0*4E");
GPS.println("$PUBX,40,RMC,0,0,0,0*47");
GPS.println("$PUBX,40,GSV,0,0,0,0*59");
GPS.println("$PUBX,40,VTG,0,0,0,0*5E");
////////////////////////////////////////////////////////////////////////////////////////////////////

}
 
void loop()
{
  //ADDED THIS////////////////////////////////////////////////////////////////////////////////////
  GPS.println("$PUBX,00*33");
  
  delay(2000);
 
  while(GPS.available()){
    Serial.write(GPS.read());
  }
  Serial.println();
  ////////////////////////////////////////////////////////////////////////////////////////////////////
}   
 
 
// Send a byte array of UBX protocol to the GPS
void sendUBX(uint8_t *MSG, uint8_t len) {
  for(int i=0; i<len; i++) {
    GPS.write(MSG[i]);
    Serial.print(MSG[i], HEX);
  }
  GPS.println();
}
 
 
// Calculate expected UBX ACK packet and parse UBX response from GPS
boolean getUBX_ACK(uint8_t *MSG) {
  uint8_t b;
  uint8_t ackByteID = 0;
  uint8_t ackPacket[10];
  unsigned long startTime = millis();
  Serial.print(" * Reading ACK response: ");
 
  // Construct the expected ACK packet    
  ackPacket[0] = 0xB5;  // header
  ackPacket[1] = 0x62;  // header
  ackPacket[2] = 0x05;  // class
  ackPacket[3] = 0x01;  // id
  ackPacket[4] = 0x02;  // length
  ackPacket[5] = 0x00;
  ackPacket[6] = MSG[2];  // ACK class
  ackPacket[7] = MSG[3];  // ACK id
  ackPacket[8] = 0;   // CK_A
  ackPacket[9] = 0;   // CK_B
 
  // Calculate the checksums
  for (uint8_t i=2; i<8; i++) {
    ackPacket[8] = ackPacket[8] + ackPacket[i];
    ackPacket[9] = ackPacket[9] + ackPacket[8];
  }
 
  while (1) {
 
    // Test for success
    if (ackByteID > 9) {
      // All packets in order!
      Serial.println(" (SUCCESS!)");
      return true;
    }
 
    // Timeout if no valid response in 3 seconds
    if (millis() - startTime > 3000) { 
      Serial.println(" (FAILED!)");
      return false;
    }
 
    // Make sure data is available to read
    if (GPS.available()) {
      b = GPS.read();
 
      // Check that bytes arrive in sequence as per expected ACK packet
      if (b == ackPacket[ackByteID]) { 
        ackByteID++;
        Serial.print(b, HEX);
      } 
      else {
        ackByteID = 0;  // Reset and look again, invalid order
      }
 
    }
  }
}

Then the only thing I get is something looking like this:

$PUBX,00,154106.00,4732.65609,N,00733.55878,E,364.181,G3,12,19,���,

And nothing else.

Well this new sketch is quite different to the first one you said you were using in post #11 ("Here's the code I use:").

So now, with this new code, you request the sentence from the GPS with;

GPS.println("$PUBX,00*33");

Wait two seconds, by which time the entire sentence has had plenty of time to arrive, and try to read it from the buffer.

What value did you set for the softserial buffer size, you did not say ?