SD.begin() hangup

I'm working on a gps logger using a mega2560 in conjunction with a NEO-6M gps module and SD card to log data and display it on a 20x4 character LCD, but I'm running into trouble initializing the SD card. After I try to initialize the SD card in the setup, the lcd won't print anything. Even more interesting, the "CardInfo" program in the SD folder works perfectly fine, so that rules out the possibility of a hardware related problem. Here's what I have so far:

#include <TinyGPS.h>
#include <SD.h>
#include <stdlib.h>
#include <LiquidCrystal.h>



#define D7    43
#define D6    45
#define D5    38
#define D4    40
#define EN    42
#define RST   46
#define RW    44
#define VCC   36
#define GND   32
//#define BUS   34


#define CS    A14
#define CS2   53






File dataFile;
LiquidCrystal lcd(RST, RW, EN, D4, D5, D6, D7);
TinyGPS gps;
static char dtostrfbuffer[20];


byte month, day, hour, minute, second, hundredths;
int year;
bool newdata = false;



float flat, flon;
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
//static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;


String SD_date_time = "invalid";
String SD_lat = "invalid";
String SD_lon = "invalid";
String SD_alt = "invalid";
String SD_course = "invalid";
String SD_mph = "invalid";
String dataString ="";
char filename[15];


static void gpsdump(TinyGPS &gps);
static bool feedgps();
static void print_float(float val, float invalid, int len, int prec, int SD_val);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
  Serial.begin(9600);
  Serial3.begin(9600);
  initLCD();
  //delay(1000);
  
  int n = 0;
  for(n; !createSDFile() && n < 10; n++){
    Serial.print("Try #");
    Serial.print(n+1);
    Serial.println(" failed!");
  }
  
  if(n < 9)
    Serial.print("SD initialization successful!");
  
  //lcd.clear();
  //if(createSDFile())
    //Serial.println("SD File created");
  //else
    //Serial.println("SD fatal error!");
  
  //delay(2000);  
  
  bootupScr();
  
  
}

void loop()
{
  newdata = false;
  unsigned long start = millis();
  
  
  while (millis() - start < 500)
  {
    if (feedgps())
      newdata = true;
  }
  
  gpsdump(gps);
  
  if(newdata){
    updateLCD();
  
    logData();  
  }
}



//-------------------------Functions------------------------


void updateLCD(){
  
  static bool toggle = !toggle;
  
  Serial.print(gps.f_altitude());
  lcd.clear();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  //boolean PM = true;
  
  hour = (hour + 5);
  
  if(hour > 24)
    hour -= 24;
  
  float elev = gps.f_altitude();
  
  if(newdata){
  
    lcd.setCursor(0, 0);
    lcd.print("Lat: ");
    lcd.setCursor(5, 0);
    lcd.print(flat, 6);
    
    lcd.setCursor(0, 1);
    lcd.print("Lon: ");
    lcd.setCursor(5, 1);
    lcd.print(flon, 6);
    
    lcd.setCursor(0, 2); 
    lcd.print("HDOP: ");
    lcd.setCursor(6, 2); 
    if(toggle && gps.hdop() < 200)
      lcd.print(gps.hdop());
    lcd.setCursor(11, 2);
    lcd.print("MPH: ");
    lcd.setCursor(16, 2);
    lcd.print(gps.f_speed_mph(), 1);
    
    lcd.setCursor(0, 3);  
    lcd.print("Alt: ");
    lcd.setCursor(5, 3);
    lcd.print(elev, 1);
    lcd.setCursor(12, 3);
    
    if(hour < 10){
      lcd.print('0');
      lcd.setCursor(13, 3);
    }
      lcd.print(hour);   
      lcd.setCursor(14, 3);
      lcd.print(':');
      lcd.setCursor(15, 3);
    
    if(minute < 10){
      lcd.print('0');
      lcd.setCursor(16, 3);
    }
      lcd.print(minute);
    
    lcd.setCursor(17, 3);
    lcd.print(':');
    lcd.setCursor(18, 3);
    
    if(second < 10)
      lcd.print('0');
    lcd.print(second);
      
  }
}


void bootupScr(){
  
  lcd.setCursor(0, 0);
  lcd.print("--------------------");
  lcd.setCursor(0, 1);
  lcd.print("GPS Datalogger v0.3 ");
  lcd.setCursor(0, 2);
  lcd.print("waiting for GPS fix ");
  lcd.setCursor(0, 3);
  lcd.print("--------------------");
  
  Serial.println("--------------------");

  Serial.println("GPS Datalogger v0.3 ");

  Serial.println("waiting for GPS fix ");

  Serial.println("--------------------\n");
  
}


void initLCD(){
  
  lcd.begin(20, 4);
  pinMode(VCC, OUTPUT);
  pinMode(GND, OUTPUT);
  digitalWrite(VCC, HIGH); // power pins for the potentiometer
  digitalWrite(GND, LOW);
  delay(100);
}



boolean createSDFile(){
  
  pinMode(CS, OUTPUT); 
  pinMode(CS2, OUTPUT);
  if(!SD.begin(CS))
  { 
    return 0;  
  }
  
  
  strcpy(filename, "GPSLOG00.CSV");
  
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    if (!SD.exists(filename)){
      continue;
    }
  }
  
  dataFile = SD.open(filename, FILE_WRITE);
  
  if(dataFile){
    Serial.println("Date/Time,Latitude,Longitude,Elevation,Speed,Heading");
    dataFile.println("Date/Time,Latitude,Longitude,Elevation,Speed,Heading");  
    dataFile.close();
    return 1;
  }
  
  else {
    Serial.print("Could not open file: ");
    Serial.println(filename);
    return 0;
  }
}


void logData(){
  
  dataString = SD_date_time + "," + SD_lat + "," + SD_lon + "," + SD_alt + "," + SD_mph + "," + SD_course;  
 
  dataFile = SD.open(filename, FILE_WRITE);
  if (dataFile && newdata)
  {
    dataFile.println(dataString);
    dataFile.close();
  }
}


static void gpsdump(TinyGPS &gps){
  
  
  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age); 
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5, 1); 
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5, 2); 
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

  print_date(gps); 
 
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2, 3);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 5);
  print_float(gps.f_speed_mph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2, 4);
}



static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  
  feedgps();
}



static void print_float(float val, float invalid, int len, int prec, int SD_val){
  
  char sz[32];
  if (val != invalid){
    
    
    if(SD_val == 1) SD_lat = dtostrf(val, 11, 6, dtostrfbuffer);
    else if(SD_val == 2) SD_lon = dtostrf(val, 11, 6, dtostrfbuffer);
    else if(SD_val == 3) SD_alt = dtostrf(val, 7, 2, dtostrfbuffer);
    else if(SD_val == 4) SD_mph = dtostrf(val, 4, 2, dtostrfbuffer);
    else if(SD_val == 5) SD_course = dtostrf(val, 11, 6, dtostrfbuffer);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1);
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
  }
  feedgps();
}




static void print_date(TinyGPS &gps){
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
  {
    
    SD_date_time = "invalid";
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d", month, day, year, hour, minute, second);
    SD_date_time = sz;
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  feedgps();
}




static void print_str(const char *str, int len){
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    feedgps();
}




static bool feedgps(){
  while (Serial3.available())
  {
    if (gps.encode(Serial3.read()))
      return true;
  }
  return false;
}

PS: This code is by no means optimized or perfect, but I would appreciate suggestions :slight_smile:

CWashburn:
PS: This code is by no means optimized or perfect, but I would appreciate suggestions :slight_smile:

Don't do that ten times in a row:

boolean createSDFile(){
  pinMode(CS, OUTPUT); 
  pinMode(CS2, OUTPUT);
  if(!SD.begin(CS))
...

The SD card is to be initialized ONLY ONCE in the sketch. And NOT once before creating every file.
Put the SD.begin() function call into the setup() function!

And after SD.begin(CS) has been executed successfully, never call SD.begin() any more in the sketch!