Black Lives Matter - Action and Equality. ... Adafruit is open and shipping.
0

GPS Shield altitude missing
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

GPS Shield altitude missing

by jcraig on Sun Aug 10, 2008 11:10 am

Hi,

Thanks for the incredible product! It went together without a hitch, but I'm looking to use the GGA data, and I can't seem to get it. it gives me the "!" error. I think this is the only way to get altitude data, so it's pretty important for me (I'm sending up a weather balloon). Please let me know if you have figured out what is going on. I read another similar post, but I'm not sure if we are talking about the same problem.
jcraig
 
Posts: 7
Joined: Sun Aug 10, 2008 11:05 am

by adafruit on Mon Aug 11, 2008 12:11 am

thats very odd
i have this working just fine

dont forget to reduce the amount of RAM as in the instructions!

Code: Select all | TOGGLE FULL SIZE
// this is a generic logger that does checksum testing so the data written should be always good
// Assumes a sirf III chipset logger attached to pin 0 and 1

#include "AF_SDLog.h"
#include "util.h"
#include <avr/pgmspace.h>

AF_SDLog card;
File f;

#define led1Pin 4                // LED1 connected to digital pin 4
#define led2Pin 3                // LED2 connected to digital pin 3
#define powerpin 2               // GPS power control

// set the  RX_BUFFER_SIZE to 32!
#define BUFFSIZE 83         // we buffer one NMEA sentense at a time, 83 bytes is longer than the max length
char buffer[BUFFSIZE];      // this is the double buffer
uint8_t bufferidx = 0;

#define LOG_RMC  1      // essential location data
#define RMC_ON   "$PSRF103,4,0,1,1*21\r\n"  // the command we send to turn RMC on (1 hz rate)
#define RMC_OFF  "$PSRF103,4,0,0,1*20\r\n"  // the command we send to turn RMC off

#define LOG_GGA  1      // contains fix, hdop & vdop data
#define GGA_ON   "$PSRF103,0,0,1,1*25\r\n"   // the command we send to turn GGA on (1 hz rate)
#define GGA_OFF  "$PSRF103,0,0,0,1*24\r\n"   // the command we send to turn GGA off

#define LOG_GSA 0      // satelite data
#define GSA_ON   "$PSRF103,2,0,1,1*27\r\n"   // the command we send to turn GSA on (1 hz rate)
#define GSA_OFF  "$PSRF103,2,0,0,1*26\r\n"   // the command we send to turn GSA off

#define LOG_GSV  0      // detailed satellite data
#define GSV_ON   "$PSRF103,3,0,1,1*26\r\n"  // the command we send to turn GSV on (1 hz rate)
#define GSV_OFF  "$PSRF103,3,0,0,1*27\r\n"  // the command we send to turn GSV off

#define LOG_GLL 0      // Loran-compatibility data
// this isnt output by default

#define USE_WAAS   1     // useful in US, but slower fix
#define WAAS_ON    "$PSRF151,1*3F\r\n"       // the command for turning on WAAS
#define WAAS_OFF   "$PSRF151,0*3E\r\n"       // the command for turning off WAAS

#define LOG_RMC_FIXONLY 1  // log only when we get RMC's with fix?
uint8_t fix = 0; // current fix data

// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
    if (c < '0')
      return 0;
    if (c <= '9')
      return c - '0';
    if (c < 'A')
       return 0;
    if (c <= 'F')
       return (c - 'A')+10;
}

uint8_t i;

// blink out an error code
void error(uint8_t errno) {
   while(1) {
     for (i=0; i<errno; i++) {   
       digitalWrite(led1Pin, HIGH);
       digitalWrite(led2Pin, HIGH);
       delay(100);
       digitalWrite(led1Pin, LOW);   
       digitalWrite(led2Pin, LOW);   
       delay(100);
     }
     for (; i<10; i++) {
       delay(200);
     }     
   }
}

void setup()                    // run once, when the sketch starts
{
  Serial.begin(4800);
  putstring_nl("GPSlogger");
  pinMode(led1Pin, OUTPUT);      // sets the digital pin as output
  pinMode(led2Pin, OUTPUT);      // sets the digital pin as output
  pinMode(powerpin, OUTPUT);
  digitalWrite(powerpin, LOW);
 
  if (!card.init_card()) {
    putstring_nl("Card init. failed!");
    error(1);
  }
  if (!card.open_partition()) {
    putstring_nl("No partition!");
    error(2);
  }
  if (!card.open_filesys()) {
    putstring_nl("Can't open filesys");
    error(3);
  }
  if (!card.open_dir("/")) {
    putstring_nl("Can't open /");
    error(4);
  }
 
  strcpy(buffer, "GPSLOG00.TXT");
  for (buffer[6] = '0'; buffer[6] <= '9'; buffer[6]++) {
      for (buffer[7] = '0'; buffer[7] <= '9'; buffer[7]++) {
         //putstring("\n\rtrying to open ");Serial.println(buffer);
         f = card.open_file(buffer);
         if (!f)
      break;        // found a file!     
         card.close_file(f);
      }
      if (!f)
         break;
  }

  if(!card.create_file(buffer)) {
    putstring("couldnt create "); Serial.println(buffer);
    error(5);
  }
  f = card.open_file(buffer);
  if (!f) {
    putstring("error opening "); Serial.println(buffer);
    card.close_file(f);
    error(6);
  }
  putstring("writing to "); Serial.println(buffer);
  putstring_nl("ready!");

delay(1000);

 putstring("\r\n");
#if USE_WAAS == 1
   putstring(WAAS_ON); // turn on WAAS
#else
  putstring(WAAS_OFF; // turn on WAAS
#endif

#if LOG_RMC == 1
  putstring(RMC_ON); // turn on RMC
#else
  putstring(RMC_OFF); // turn off RMC
#endif

#if LOG_GSV == 1
  putstring(GSV_ON); // turn on GSV
#else
  putstring(GSV_OFF); // turn off GSV
#endif

#if LOG_GSA == 1
  putstring(GSA_ON); // turn on GSA
#else
  putstring(GSA_OFF); // turn off GSA
#endif

#if LOG_GGA == 1
 putstring(GGA_ON); // turn on GGA
#else
 putstring(GGA_OFF); // turn off GGA
#endif
}

void loop()                     // run over and over again
{
  //Serial.println(Serial.available(), DEC);
  char c;
  uint8_t sum;
 
  // read one 'line'
  if (Serial.available()) {
    c = Serial.read();
    //Serial.print(c, BYTE);
    if (bufferidx == 0) {
      while (c != '$')
        c = Serial.read(); // wait till we get a $
    }
    buffer[bufferidx] = c;

    //Serial.print(c, BYTE);
    if (c == '\n') {
      //putstring_nl("EOL");
      //Serial.print(buffer);
      buffer[bufferidx+1] = 0; // terminate it
     
      if (buffer[bufferidx-4] != '*') {
        // no checksum?
        Serial.print('*', BYTE);
        bufferidx = 0;
        return;
      }
      // get checksum
      sum = parseHex(buffer[bufferidx-3]) * 16;
      sum += parseHex(buffer[bufferidx-2]);
     
      // check checksum
      for (i=1; i < (bufferidx-4); i++) {
        sum ^= buffer[i];
      }
      if (sum != 0) {
        //putstring_nl("Cxsum mismatch");
        Serial.print('~', BYTE);
        bufferidx = 0;
        return;
      }
      // got good data!

      if (strstr(buffer, "GPRMC")) {
        // find out if we got a fix
        char *p = buffer;
        p = strchr(p, ',')+1;
        p = strchr(p, ',')+1;       // skip to 3rd item
       
        if (p[0] == 'V') {
          digitalWrite(led1Pin, LOW);
          fix = 0;
        } else {
          digitalWrite(led1Pin, HIGH);
          fix = 1;
        }
      }
#if LOG_RMC_FIXONLY
      if (!fix) {
          Serial.print('_', BYTE);
          bufferidx = 0;
          return;
      }
#endif
      // rad. lets log it!
      //Serial.print(buffer);
      Serial.print('#', BYTE);
      digitalWrite(led2Pin, HIGH);      // sets the digital pin as output

      if(card.write_file(f, (uint8_t *) buffer, bufferidx) != bufferidx) {
         putstring_nl("can't write!");
    return;
      }
      digitalWrite(led2Pin, LOW);

      bufferidx = 0;
      return;
    }
    bufferidx++;
    if (bufferidx == BUFFSIZE-1) {
       Serial.print('!', BYTE);
       bufferidx = 0;
    }
  }
}

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by jcraig on Mon Aug 11, 2008 9:53 am

Thanks a million! I went and changed the RAM amount from 32 to 16, to see if that would help, and loaded the code you posted. I'm not sure which one did the trick, so I'm going to try and change the RAM back to 32 again to see if it stops working (the code at first glance looks the same). I'll send pictures from the balloon if I'm successful.
jcraig
 
Posts: 7
Joined: Sun Aug 10, 2008 11:05 am

by adafruit on Mon Aug 11, 2008 2:25 pm

sounds awesome. be sure to do lots of testing first, OK? it would suck if something was wrong and you didnt find out until -afterwards-

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by jcraig on Tue Aug 12, 2008 9:17 pm

It should be pretty cool. I'm a pro photographer, so at least the cameras will be nice! As for testing, we are sending the com payload up in a private plane to test the tracking system, and I have to replace the gps at some point with one that can read +100000 ft. In the above code how do you set the sleep interval? It seems stuck at 1hz rate. I tried changing the command string, but to no avail (a bit over my head). We are going to use a 2m ham radio for telemetry so we can watch in real time. Arduino in space...
jcraig
 
Posts: 7
Joined: Sun Aug 10, 2008 11:05 am

by adafruit on Wed Aug 13, 2008 1:22 am

each GPS has different methods to set the rate
you can use the $PSRF (or whatever) sentences. be sure to set the checksum properly. look at the resources for more info

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by jcraig on Wed Aug 13, 2008 3:04 pm

I'm using the em-406a, and trying to use the $psrf to set the rate, but I have no clue how to correctly calculate the checksum. I looked at the resource info and found the correct part of the string to modify, but the checksum really confused me. I also looked elsewhere on the net, and couldn't seem to find a simple way to calculate the checksum. Maybe you could steer me in the right direction? I'm trying to set the rate to every 10 seconds on the RMC and the GGA.
jcraig
 
Posts: 7
Joined: Sun Aug 10, 2008 11:05 am

by adafruit on Wed Aug 13, 2008 6:57 pm


adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by jcraig on Wed Aug 13, 2008 11:29 pm

I thought it was for a different module (MTK) and didn't immediately see the $PSRF... I feel sheepish. It's now working perfectly. Thanks.
jcraig
 
Posts: 7
Joined: Sun Aug 10, 2008 11:05 am

by zlite on Sat Aug 30, 2008 2:07 am

Limor,

I had the same problem when trying to read GGA (the "#!#!#!#!" report of buffer overrun) despite decreasing the RAM to 32 as instructed. Then I pasted in your code above and it worked! What, aside from switching the 0 to a 1 in the GGA definition line, did you change in that code?

Chris
zlite
 
Posts: 9
Joined: Sun Jul 06, 2008 12:47 pm

by adafruit on Sat Aug 30, 2008 7:00 pm

no idea :) do a diff?

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by zlite on Sat Aug 30, 2008 8:09 pm

Thanks for the prod :wink: .There are actually loads of differences, but the one that seems to make the key difference is that you increased the BUFFSIZE to 83 from 75.
zlite
 
Posts: 9
Joined: Sun Jul 06, 2008 12:47 pm

by zlite on Sat Aug 30, 2008 9:50 pm

Limor,

You might think about posting your code above on the main GPS shield download page, or modifying the logging code there as you did this one. The instructions on the "Use it" page for that code (which says to enable other NMEA sentences by changing the 0 to a 1 in definitions line) won't work for GGA unless you increase the buffer size.
zlite
 
Posts: 9
Joined: Sun Jul 06, 2008 12:47 pm

Please be positive and constructive with your questions and comments.