GPS not getting any fix. Why?

Hi

I am using a ublox GPS like this one here. The problem is, it isn't getting a fix. I've tested the Code with another Ublox based GPS and it worked within minutes. What could possible reasons be? I've soldered it onto a board with a lot of metal on it, like this one. May that be blocking the signal? Yes, I know the antenna isn't the best, but it still should work right? What is the optimal antenna orientation? Right now its just horizontal (parallel with the board)

Are you testing the GPS indoors or outdoors? That makes all the difference in the world sometimes.

Indoors. But the other GPS worked indoors too.

Sounds like your next test will be conducted outdoors. :slight_smile:

Indeed. But for the sake of argument, let's assume it doesn't work there either

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!