HELP, Can't seem to write to SD card in my code.

I am clearly overlooking something here. But I cannot get the following to work and would really appreciate if someone would look this over and point out what I’ve done wrong. The weird part is that I’ve simplified the file save portion and copied code from a working SD example.

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <RTClib.h>
#include <SoftwareSerial.h>

RTC_DS1307 rtc;
const int tempPin=3;//Temp sensor data pin
const int aPin=0;//Amp sensor pin
const int tPin=A1;
const int buttonPin=9;
int buttonState = 0;
float throttle=0.00;
String dataString = “”;
File logfile;
String filename ;
const int chipSelect = 10;//CS line for SD card
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

SoftwareSerial mySerial(3,4); // RX, TX

void setup()
{
Serial.begin(9600);
Wire.begin();
rtc.begin();
mySerial.begin(9600);
backlightOn();
clearLCD();
uint32_t volumesize;
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
selectLineOne();
mySerial.print(“SD Card failed”);
delay(400);
clearLCD();
return;
} else {
mySerial.print(“SD CARD GOOD!”);
selectLineTwo();
if (!volume.init(card)) {
mySerial.print(“Read failed”);
}else{

volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we’ll have a lot of clusters
volumesize *= 512;
volumesize /=1024;
volumesize /=1024;
mySerial.print(volumesize);
mySerial.print(“MB”);
delay(50);
}
}

delay(1000);
clearLCD();
pinMode(buttonPin,INPUT_PULLUP);

}

void loop()
{
DateTime now = rtc.now();
//DateTime last=rtc.now();
buttonState = digitalRead(buttonPin);
selectLineOne();
float temp=getTemp(tempPin);
selectLineOne();
mySerial.print(“Eng:”);
mySerial.print(int(temp));
mySerial.print((char)223);
goTo(11);
mySerial.print(“log:”);
if (buttonState==HIGH){

mySerial.print(“N”);
}else{

mySerial.print(“Y”);
}
goTo(16);
mySerial.print(“A:”);
mySerial.print(getAmps(aPin));
mySerial.print(" S:");
mySerial.print(getThrottle(tPin));

if (!buttonState){
//log the data if enough time has passed
// Serial.print=now.unixtime();
File logfile=SD.open(“Datafile.txt”,FILE_WRITE);

dataString+=now.month();//+","+now.day();
dataString+="/";
dataString+=now.day();
dataString+="/";
dataString+=now.year();
dataString+=",";
dataString+=now.unixtime();
dataString+=",";
dataString+=String(getAmps(aPin));
dataString+=",";
dataString+=String(getThrottle(tPin));
dataString+=",";
dataString+=String(temp);
//Serial.println(dataString);//Temp for testing
if (logfile){
logfile.println(dataString);
dataString="";
logfile.close();
}else{
Serial.println(“error opening file”);
}
}
delay(50);
}
//***************END OF LOOP

void selectLineOne(){ //puts the cursor at line 0 char 0.
mySerial.write(0xFE); //command flag
mySerial.write(128); //position
delay(10);
}
void selectLineTwo(){ //puts the cursor at line 0 char 0.
mySerial.write(0xFE); //command flag
mySerial.write(192); //position
delay(10);
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){ mySerial.write(0xFE); //command flag
mySerial.write((position+128)); //position
}else if (position<32){mySerial.write(0xFE); //command flag
mySerial.write((position+48+128)); //position
} else { goTo(0); }
delay(10);
}

void clearLCD(){
mySerial.write(0xFE); //command flag
mySerial.write(0x01); //clear command.
delay(10);
}
void backlightOn(){ //turns on the backlight
mySerial.write(0x7C); //command flag for backlight stuff
mySerial.write(255); //light level.
delay(10);
}
void backlightOff(){ //turns off the backlight
mySerial.write(0x7C); //command flag for backlight stuff
mySerial.write(128); //light level for off.
delay(10);
}
void serCommand(){ //a general function to call the command flag for issuing all other commands
mySerial.write(0xFE);
}

float getAmps(int aPin){
float v=(analogRead(aPin)-510)*4.8828125;
v /=1024.0;
return v;
}
float getTemp(int pin){
float v=analogRead(pin)*4.8828125;//Convert based on 5v
v /=1024.0;
//Get Temp in C
float t =(v - 0.5)*100;
//convert to F
t=(t * 9.0 / 5.0)+32.0;
return t;
}
int getThrottle(int pin){
//Get voltage rang .816 to 4.2
float t=analogRead(pin);
//map t to 0-5
t=t * (5.0 / 1023.0);
return t;

}

String dataString = "";
String filename ;

Learn to do it right, using NULL terminated arrays of chars. On a system with limited memory, such as the Arduino, using a process that necessarily needs a lot of memory, pissing away resources on the String class is (pick your favorite derogatory term starting with s).

If you are using other than a Mega, pin 10 MUST be set as OUTPUT to indicate that the Arduino is an SPI master (rather than an SPI slave).

It can still be used as a slave select pin. However, the shield you are using (if you are using a shield), may have other ideas what the proper slave select pin is. The Ethernet shield, for example, has pin 4 as the slave select pin for the SD card. Your use of SoftwareSerial on that pin could be a problem.

I've simplified the file save portion and copied code from a working SD example.

Does the example work with all your other hardware connected?

Everything works, and all the SD file examples work, I'm not using shields I hate shields as they force pin selection on you. The current code is just the latest attempt, frankly grabbing at straws at that point, I've based most of my attempts from example code that works. I'll start by moving my softserial and setting 10 for OUTPUT, for the card.

Wouldn't the SD library set the CS pin to OUTPUT on it's own?

Wouldn't the SD library set the CS pin to OUTPUT on it's own?

Well, yes, it should. It doesn't hurt to do it twice, though. Doing so makes it clear that you know that pin 10 needs to be an output.