Hi,
I am doing my first Arduino project: a 3 channel temperature logger 
I've used this: http://arduinolearning.com/projects/temperature-logger.php as the base for the hardware and code.
I read the temperature sensors and write to the SD card every 3 min.
I left it to run for a day, when I cheacked the SD there was enterys only for the first ~12hrs.
I've added the anti-reset capacitor to the reset line, Cleaned the SD, and reset the Arduino.
In this run it stopped logging after ~17hr. Connected the Arduino to my pc and saw that the code was still running, just it was not writing to the SD.
What am I'm doing wrong?
Is the serial monitor showing the file not opening?
Maybe you should post your modified code.
I also found out that if I take the SD out while the code runing the text "error opening temp.tx" will not show up, but from this point on after inserting the card it will not write to it.
maybe this is part of my problem.
This is my code:
#include <SD.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define DS18B20 7
const long DelayS=180;
const int chipSelect = 4;
OneWire ourWire(DS18B20);
DallasTemperature sensors(&ourWire);
String TempS, TimeS, Tout;
long day = 86400000; // 86400000 milliseconds in a day
long hour = 3600000; // 3600000 milliseconds in an hour
long minute = 60000; // 60000 milliseconds in a minute
long second =Â 1000; // 1000 milliseconds in a second
void setup() {
 Serial.begin(9600);
 while (!Serial) {
   Serial.print("."); // wait for serial port to connect.
 }
 Serial.print("Initializing SD card…");
 pinMode(10, OUTPUT);
Â
 //init SD card
 if (!SD.begin(chipSelect)) {
  Serial.println("Card failed, or not present");
  return; }
 Serial.println("card initialized.");
 sensors.begin();
}
void loop() {
 sensors.requestTemperatures();
 TempS="";
 TempS=GetTemp();  //Read the temperaturs to string
 long timeNow = millis();Â
 int days = timeNow / day ;                //number of days
 int hours = (timeNow % day) / hour;           //the remainder from days division (in milliseconds) divided by hours, this gives the full hours
 int minutes = ((timeNow % day) % hour) / minute ;    //and so on...
 int seconds = (((timeNow % day) % hour) % minute) / second;
 TimeS=String(days) +" "+ String(hours) +":"+ String(minutes) +":"+ String(seconds);
 Tout=TimeS + " " + TempS;
Â
 // open the file.
 File dataFile = SD.open("temp.txt", FILE_WRITE);
Â
 // if the file is available, write to it:
 if (dataFile)
 { Â
  dataFile.println(Tout);
  dataFile.close();
 }
 // if the file isn’t open
 else
 {
  Serial.print("error opening temp.txt  ");
 }
 Serial.println(Tout);
 delay (DelayS* 1000);
}
// write 3 temp sensors to string file
String GetTemp () {
 String out;
 out=String (sensors.getTempCByIndex(0)) +" "+ String (sensors.getTempCByIndex(1));
 out+=" " + String(sensors.getTempCByIndex(2));
 return out;
}
The String data type has never failed to cause me problems. I recommend using character arrays instead.
The GetTemp function has a problem. The String variable "out" may be invalid when the GetTemp function returns.
Is the SD device a card slot only? No other SPI devices connected?
I will look into the String vars and the GetTemp function.
The card is:
http://www.aliexpress.com/snapshot/7282289706.html
I've connected it according to the diagram in http://arduinolearning.com/projects/temperature-logger.php
The legs of my sd Shield are in different order than in that drawing. I read the text in the picture and connected accordingly.
I also found out that if I take the SD out while the code runing the text "error opening temp.tx" will not show up, but from this point on after inserting the card it will not write to it.
maybe this is part of my problem.
Removal of the card, reinserting it, and having the sketch write to it requires a new call to SD.begin(), but this is not supported in SD.h. You will have to restart the sketch with "reset".
There are ways to call SD.begin() a second time without using reset. See this thread which discusses those issues. Writing to SD Card after removing and replacing it - Storage - Arduino Forum
The remove/reinsert issues are separate from the program stopping after 12+ hours.
Connected the Arduino to my pc and saw that the code was still running, just it was not writing to the SD.
How do you do this without creating a reset when opening the Serial monitor? Or, was the serial monitor open through the 17 hours and the serial print out of Tout was still running?
I agree with Surfer Tim and would recommend a re-write without "Strings" (String TempS, TimeS, Tout;) which can lead to memory problems.
No other SPI devices connected?
Important point from Surfer Tim. The Catalex SD modules are good ones, but they need to be alone on the SPI bus.
cattledog:
Important point from Surfer Tim. The Catalex SD modules are good ones, but they need to be alone on the SPI bus.
Not true. You must include code to prevent collisions on the SPI bus. I use a SD card with the w5100, and both are SPI bus.
Surfer Tim--
There was a problem with some versions of the Catalex module and multiple devices on the spi bus in that the Catalex module did not release MISO when chip select is high. Catalex MicroSD Card Adapter do I need to level shift - #4 by fat16lib - Storage - Arduino Forum
That applies to almost all SD cards. fat16lib says that is corrected in the SdFat library.
http://forum.arduino.cc/index.php?topic=276274.0
edit: If you read that thread, you will find the patch for the SD library. I just checked. The SdFat library has the patch, and the SD library does not.
To apply the patch to the IDE v1.6.9 SD library, open /libraries/SD/src/utility/Sd2Card.cpp and add this single line in the function at line 162..
void Sd2Card::chipSelectHigh(void) {
 digitalWrite(chipSelectPin_, HIGH);
 SPI.transfer(0x00); // add this line
#ifdef USE_SPI_LIB
 if (chip_select_asserted) {
  chip_select_asserted = 0;
  SPI.endTransaction();
 }
#endif
}
BTW, some Catalex SD card readers now have been modified to free up the MISO line. The line buffer output control for the MISO line was connected to GND, which would never release the MISO line. It is now connected to the CS pin, which will release the MISO line when CS is taken HIGH. So it depends on the model Catalex SD reader you are using.
Thanks Tim for that information. I was not aware of the full extent of the issue.
I mostly use SdFat, but in most of the problem sketches presented in this section of the forum the OP is using SD.h. I don't like to add to their confusion by recommending a library change unless absolutely necessary.
I added the schematic for the new Catalex unit above to show the new connection for the output enable for the MISO line on the 74vhc125.
I don't usually recommend changing the library unless the user really understands what they are doing. That is why I included the patch for the SD library.
cattledog:
How do you do this without creating a reset when opening the Serial monitor? Or, was the serial monitor open through the 17 hours and the serial print out of Tout was still running?
I found somewhere that putting a 10uF capacitor between the reset and gnd will stop the auto reset when connecting the USB cable.
(This also breaks the upload process as the PC cannot make the reset at the end of the upload)
cattledog:
Removal of the card, reinserting it, and having the sketch write to it requires a new call to SD.begin(), but this is not supported in SD.h. You will have to restart the sketch with "reset".
There are ways to call SD.begin() a second time without using reset. See this thread which discusses those issues. Writing to SD Card after removing and replacing it - Storage - Arduino Forum
I changed the code to SdFat but still there is no error when I take the SD out.
The " if (dataFile) { " line will never go to the else part even when the card is out.
Is this normal?
How can I know when to rerun the SD.begin()?
The new test code:
#include <SPI.h>
#include <SdFat.h>
SdFat SD;
File dataFile;
const long DelayS=1;
const int chipSelect = 4;
void setup() {
Serial.begin(9600);
while (!Serial) {;} // wait for serial port to connect.
//init SD card
Serial.print("Initializing SD card…");
pinMode(10, OUTPUT);
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
return; }
Serial.println("card initialized.");
}
void loop() {
long timeNow = millis();
// open the file.
dataFile = SD.open("temp.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(timeNow);
dataFile.close();
} else {
// if the file isn’t open
Serial.print("error opening temp.txt ");
}
Serial.println(timeNow);
delay (DelayS* 1000);
}
I used your code modified slightly, and it displays "error opening temp.txt" the next file open attempt after I remove the SD card. This code will restart the SD. I increased the delay to 10 seconds so I could watch it easier.
#include <SPI.h>
#include <SdFat.h>
SdFat SD;
File dataFile;
const long DelayS=10;
const int chipSelect = 4;
void setup() {
 Serial.begin(115200);Â
 while (!Serial) {;} // wait for serial port to connect.Â
 //init SD card
 digitalWrite(10,HIGH);
Â
 Serial.print("Initializing SD card…");
 if (!SD.begin(chipSelect)) {
  Serial.println("Card failed, or not present");
  return; }
 Serial.println("card initialized.");
}
void loop() {
 long timeNow = millis();Â
 // open the file.
 dataFile = SD.open("temp.txt", FILE_WRITE);
Â
 // if the file is available, write to it:
 if (dataFile) { Â
  dataFile.println(timeNow);
  dataFile.close();
 } else {
  // if the file isn't open
  Serial.println("error opening temp.txt");
  while(!SD.begin(4)) {
   delay(1000);   Â
   Serial.println("Starting SD");
Â
  }
 Â
 }
 Serial.println(timeNow);
 delay (DelayS* 1000);
}
I changed the code to SdFat but still there is no error when I take the SD out.
I do not confirm this. I run your code as posted and it shows the error print out when the card is removed while running. Indeed, even when I use the sketch as written but change back to SD.h I see the error message. The millis() are still being printed out and perhaps that has confused you.
Surfer Tim's code works well. You want to make sure that the file has closed before pulling the card.
EDIT--Your bigger problem is the random failure of the code with long run times. Are you still seeing that?
SurferTim:
I used your code modified slightly, and it displays "error opening temp.txt" the next file open attempt after I remove the SD card. This code will restart the SD. I increased the delay to 10 seconds so I could watch it easier.
I have the feeling that I have some hardware problem with the SD card shield.
I've re checked and all the lines to it are connected correctly both in order and electronically.
I still don't see the "error opening temp.txt" when the SD is out.
I also only see the RX led flashes and not the TX. Is this ok?
The shield is connected to the +5V. I saw some talk about the need to use 3.3V?!
I've added a SD.begin(chipSelect); before the SD.open so now it does re connect to the SD correctly.
I started a new run, so I hope now it will not lose data.
I think I will order another SD shield.