Trying to use adafruit GPS logger with Arduino mega?

Hello, I'm working on a project for which, until recently, I was using an Arduino Uno and Anna adafruit ultimate GPS logging shield (found here: https://learn.adafruit.com/adafruit-shield-compatibility/ultimate-gps-shield). However, I am running out of memory because I am also using an LCD screen and this means that I have a bunch of libraries to include. I have an Arduino mega lying around, and I read on the above link that it may be possible to get it to work with the GPS shield. I have followed their instructions, and jumpered pin 8 to RX1, pin 7 to TX1 (along with ground to ground, and 5V to 5V, which they didn't mention but I assume you have to do). I changed the serial line like they suggested, and now am trying to follow their recommendations for the SD card. ( I am using the shield_sdlog example included with the adafruit GPS library )

This is what they say:

"For the SD card, the following may be tried, in decreasing order of recommendation: Use the Adafruit SD library, specifying pin 10 for chip select, 11 for MOSI, 12 for MISO and 13 for SCK. Edit the file utility/Sd2Card.h in the default Arduino SD library, changing line 42 to read "#define MEGA_SOFT_SPI 1" (default is 0)."

I tried to follow the first suggestion, but i'm not sure i'm doing it right. I commented out the previous definition of ledPin, because it was already 13. Then I commented out all uses of the LED pin, which I don't think should affect the functionality of the logging. Than I defined the pins they suggested, as follows:

// Set the pins used
#define chipSelect 10
#define MOSI 11
#define MISO 12
#define SCK 13
//#define ledPin 13

However, when I run the program, it says that the card initiation failed, which is the same problem I have run into before when I accidentally misjumpered's Arduino Uno. I haven't tried their second suggestion, because I'm not sure if I'm supposed to do that in addition to the other pin definitions or what.

Anyway, I was just wondering if anyone had any suggestions on how to get this working. Help would be much appreciated.

Thanks

This is what they say:

"For the SD card, the following may be tried, in decreasing order of recommendation: Use the Adafruit SD library, specifying pin 10 for chip select, 11 for MOSI, 12 for MISO and 13 for SCK. Edit the file utility/Sd2Card.h in the default Arduino SD library, changing line 42 to read "#define MEGA_SOFT_SPI 1" (default is 0)."

Why would you want to do that? Hardware SPI is much faster and more reliable.

(along with ground to ground, and 5V to 5V, which they didn't mention but I assume you have to do)

No. Those are already connected.

I am using the shield_sdlog example included with the adafruit GPS library )

If you want help, you'll post your code.

#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <avr/sleep.h>

#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);

// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  true
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY false  

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

// Set the pins used
#define chipSelect 10
#define MOSI 11
#define MISO 12
#define SCK 13
//#define ledPin 13

File logfile;

// 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;
}

// blink out an error code
void error(uint8_t errno) {
  /*
  if (SD.errorCode()) {
   putstring("SD error: ");
   Serial.print(card.errorCode(), HEX);
   Serial.print(',');
   Serial.println(card.errorData(), HEX);
   }
   */
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}

void setup() {
  // for Leonardos, if you want to debug SD issues, uncomment this line
  // to see serial output
  //while (!Serial);

  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  Serial.begin(115200);
  Serial.println("\r\nUltimate GPSlogger Shield");
  //pinMode(ledPin, OUTPUT);

  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  //if (!SD.begin(chipSelect, 11, 12, 13)) {
  if (!SD.begin(chipSelect)) {      // if you're using an UNO, you can use this line instead
    Serial.println("Card init. failed!");
    error(2);
  }
  char filename[15];
  strcpy(filename, "GPSLOG00.TXT");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }
  }

  logfile = SD.open(filename, FILE_WRITE);
  if( ! logfile ) {
    Serial.print("Couldnt create "); 
    Serial.println(filename);
    error(3);
  }
  Serial.print("Writing to "); 
  Serial.println(filename);

  // connect to the GPS at the desired rate
  GPS.begin(9600);

  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For logging data, we don't suggest using anything but either RMC only or RMC+GGA
  // to keep the log files at a reasonable size
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 100 millihertz (once every 10 seconds), 1Hz or 5Hz update rate

  // Turn off updates on antenna status, if the firmware permits it
  GPS.sendCommand(PGCMD_NOANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);

  Serial.println("Ready!");
}


// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
  #ifdef UDR0
      if (GPSECHO)
        if (c) UDR0 = c;  
      // writing direct to UDR0 is much much faster than Serial.print 
      // but only one character can be written at a time. 
  #endif
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } 
  else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

void loop() {
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences! 
    // so be very wary if using OUTPUT_ALLDATA and trying to print out data
    
    // Don't call lastNMEA more than once between parse calls!  Calling lastNMEA 
    // will clear the received flag and can cause very subtle race conditions if
    // new data comes in before parse is called again.
    char *stringptr = GPS.lastNMEA();
    
    if (!GPS.parse(stringptr))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another

    // Sentence parsed! 
    Serial.println("OK");
    if (LOG_FIXONLY && !GPS.fix) {
      Serial.print("No Fix");
      return;
    }

    // Rad. lets log it!
    Serial.println("Log");

    uint8_t stringsize = strlen(stringptr);
    if (stringsize != logfile.write((uint8_t *)stringptr, stringsize))    //write the string to the SD file
        error(4);
    if (strstr(stringptr, "RMC") || strstr(stringptr, "GGA"))   logfile.flush();
    Serial.println();
  }
}


/* End code */

Actually I just made a modification that solved the card initiation error. Based on the pin out diagram of the Uno and the mega, I jumpered the following connections:

GPS shield-> Mega 10-> 53 11-> 51 12-> 50 13-> 52,

And modified the corresponding section of my code to read:

#define chipSelect 53
#define MOSI 51
#define MISO 50
#define SCK 52
//#define ledPin 13

I believe this is SPI communication as you mentioned. However, the mega is now having trouble communicating with the GPS. It doesn't give any output from the GPS sendCommands not turn on the GPS sentences, and then later in the loop, it doesn't receive any sentences. So maybe I should somehow be communicating with the GPS using SPI? I'm not sure how to modify the code to do this

Oops, never mind. I was testing direct connection with the mega yesterday and accidentally had switched the original wiring and turned the switch to direct instead of soft serial. Problem solved!