GPS + Nokia LCD + SD Card, unable to store data into SD Card

Hi all, I am trying to make a GPS datalogger to SD card and at the same time display it to a Nokia 5110 LCD. Both SD and Nokia LCD is controlled through SPI communication. I have no problem with getting GPS information and display on LCD. However, I am having trouble to log the data into SD card.

Based on my code, the program only able to log "Card OK" into my file. In the loop() function, it stops logging anything into card. Please give me some guidance on using SD Card. Thanks

#include <SPI.h>
#include <TinyGPS.h>
#include <SoftwareSerial.h>
#include <SdFat.h>

SdFat sd;
SdFile datalog;

TinyGPS gps;
SoftwareSerial ss(2,3);

#define cs 7  //SD card chip select

#define rst 8  //GLCD RST
#define dc 9   //GLCD data command
#define ce 10  //GLCD chip enable

#define lcd_x 84
#define lcd_y 64


static const byte store[][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20  
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j 
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f ?
};

//====================GPS===================
boolean newData=false;
float flat, flon; 
long spd;
char lat_dir,lon_dir;
int year;byte month, day, hour, minute, second;
int num_sat;
unsigned long current, previous;
char contents[50];

void setup()
{
  Serial.begin(9600);
  
  if(!sd.begin(cs, SPI_HALF_SPEED)) sd.initErrorHalt();
  
  if(!datalog.open("gps.txt",O_RDWR | O_CREAT | O_AT_END)) 
    sd.errorHalt("opening test.txt for write failed"); 
  else
  {
    glcd_setCursor(0,5);
    print_string("Card OK");
    datalog.println("Card OK");
  }
  datalog.close();
  
//  Serial.println("Initializing SD Card...");
//  pinMode(10,OUTPUT);
//  
//  if(!SD.begin(cs))
//  Serial.println("Card failed");
//  else
//  Serial.println("Card initialized");
//  
//  datalog= SD.open("GPS",FILE_WRITE);
//  if(!datalog)
//  Serial.println("Error");
//  else
//  Serial.println("Ready to Go!");
  
  SPI.begin();
  ss.begin(9600);
  glcd_init();
  glcd_clear();
  glcd_setCursor(0,0);
  print_string("  GPS Monitor  ");
  glcd_setCursor(0,1);
  print_string("Lat:");
  glcd_setCursor(0,2);
  print_string("Lon:");
  glcd_setCursor(0,3);
  print_string("Spd:");
  
  
}

void loop()
{
  gps_decoder();
}

void gps_decoder()
{
  current=millis();
  if((current-previous)>1000)
  {
    previous=current;
  }
  sprintf(contents, "Millis: %d",millis());
      
  datalog.open("gps.text", O_RDWR | O_CREAT | O_AT_END);
  datalog.println("testing");
  datalog.println(contents);
  datalog.close();
  
  while(ss.available())
  {
    glcd_setCursor(0,5);
    print_int(current/1000);
    char c=ss.read();
    if(gps.encode(c))
    {
      newData=true;
      gps.f_get_position(&flat,&flon);
      
      if(flat>0)lat_dir='N';else lat_dir='S';
      if(flon>0)lon_dir='E';else lon_dir='W';
      
      spd=gps.f_speed_kmph();
      
      gps.crack_datetime(&year,&month,&day,&hour,&minute,&second);
      year%=100;
      hour=hour+8;
      
      char buffer2[20];
      dtostrf(flat,8,6,buffer2);
      
    }
    if(newData)
    {          
      Serial.println(flat);
      Serial.println(flon);
      glcd_setCursor(25,1);
      print_float(flat,4);
      
      glcd_setCursor(73,1);
      print_char(lat_dir);
      
      glcd_setCursor(25,2);
      print_float(flon,4);
      
      glcd_setCursor(73,2);
      print_char(lon_dir);
      
      glcd_setCursor(25,3);
      print_float(spd,2);
      
      glcd_setCursor(55,3);
      print_string("km/h");
      
      char buffer[10];
      sprintf(buffer,"%d/%d/%d",day,month,year);
      glcd_setCursor(0,4);
      print_string(buffer);
      
      char buffer1[11];
      sprintf(buffer1,"   %d:%d:%d  ",hour,minute,second);
      glcd_setCursor(0,0);
      print_string(buffer1);
      
      newData=false;
      delay(100);      
    } 
  }
  
}

void print_float(float num, int precision)
{
  char buffer[15];
  dtostrf(num,8,precision,buffer);
  print_string(buffer);
}

void print_int(int num)
{
  char buffer[15];
  sprintf(buffer,"%d",num);
  print_string(buffer);
}

void print_char(char character)
{
  for(int index=0;index<5;index++)
  {
    data_write(store[character-0x20][index]);
  }
  data_write(0x00);
}

void print_string(char *string)
{
  while(*string)
  {
    print_char(*string++);
  }
}

void glcd_setCursor(int x,int y)
{
  command_write((0x40|y));
  command_write((0x80|x));
}

void glcd_clear()
{
  for(int i=0;i<(lcd_x*lcd_y/8);i++)
  {
    data_write(0);
  }
}

void glcd_init()
{
  pinMode(rst,OUTPUT);
  pinMode(dc,OUTPUT);
  pinMode(ce,OUTPUT);
  digitalWrite(rst,LOW);
  digitalWrite(rst,HIGH);
  command_write(0x21);  //addition mode
  command_write(0xC0);  //voltage VOP
  command_write(0x07);  //temp control
  command_write(0x13);  //voltage bias system
  command_write(0x20);  //command set basic mode
  command_write(0x0C);  //lcd display normal mode 
}

void data_write(byte data)
{
  digitalWrite(dc,HIGH);
  digitalWrite(ce,LOW);
  SPI.transfer(data);
  digitalWrite(ce,HIGH);
}

void command_write(byte data)
{
  digitalWrite(dc,LOW);
  digitalWrite(ce,LOW);
  SPI.transfer(data);
  digitalWrite(ce,HIGH);
}

The vital code related to the card is commented out, and the "card OK" line is meaningless. Having the LCD on pin 10 might not be such a good idea.

Do you mean this part?

//  Serial.println("Initializing SD Card...");
//  pinMode(10,OUTPUT);
//  
//  if(!SD.begin(cs))
//  Serial.println("Card failed");
//  else
//  Serial.println("Card initialized");
//  
//  datalog= SD.open("GPS",FILE_WRITE);
//  if(!datalog)
//  Serial.println("Error");
//  else
//  Serial.println("Ready to Go!");

And you suggest i switch the chip select between LCD and SD card?

Yes, I think it will work rather better with all those // out the window. And the "card OK" line needs to be moved. At the moment, you are claiming to have won the race before the gun goes off.

I understand pin 10 must be output to use the SD. It might not be a problem, but I'm not sure you can guarantee that when it is being used for the LCD. If you can't be sure, move the LCD wire somewhere else.

In setup you have

  if(!datalog.open("gps.txt",O_RDWR | O_CREAT | O_AT_END)) 
    sd.errorHalt("opening test.txt for write failed");

So in gps_decode you need to fix the file name. gps.text --> gps.txt

 datalog.open("gps.text", O_RDWR | O_CREAT | O_AT_END);

Should be

 datalog.open("gps.txt", O_RDWR | O_CREAT | O_AT_END);

Thanks fat16lib, what a careless mistake that I have made. I just tested it out, finally it starts to log something into the SD card.

Going to further proceed on this project soon. :smiley: