Yet another Arduino Data Logger

Hello all,

I’m new to the forum, been learning and building with Arduino for a while and have made some good progress, however, I have recently hit a stumbling block with my data logger project.

I am attempting to log at high frequency (4x per sec) the waggle of a joystick (RS 548-7648; just off the top right of the pic), I have interfaced a DS1307 RTC and a MicroSD transflash break out from Sparkfun (via voltage divider). Several LEDs are currently connected to act as error/notifications. It is a ATMega328.

Hardware seems to work fine, logging well. The issue comes when I leave the device logging for several hours. My green LED still blinks and the free space on the SD Card decreases proportionally, but no file is visible in Windows when I remove it from the logger. I am using the FAT16 Library to log to MicroSD. It works well for minutes to about an hour and then “keeps” running but doesn’t write a visible file. It could be related to the voltage divider/Fat16 issue, but with the logger working well initially, could explain the longer term problem?

I have also tried Filelogger and that didn’t work for longer periods, giving me a corrupt file when I attempt to read the card in Windows.

I am just wondering if it is something that I am obiously over-looking?

Here is my draft code:

// Wave exposure meter version 0.2

//Lets try Fat16
#include <Fat16.h>
#include <Fat16util.h>

// Include files for clock DS1307 library 
#include <WProgram.h> 
#include <Wire.h> 
#include <DS1307.h> 

// FAT16Lib Analogger Code: A simple data logger for the Arduino analog pins
#define LOG_INTERVAL 250    // mills between entries
#define SENSOR_COUNT     2 // number of analog pins to log
#define ECHO_TO_SERIAL   0 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()
#define SYNC_INTERVAL 1000  // mills between calls to sync()
uint32_t syncTime = 0;     // time of last sync()
#define error(s) error_P(PSTR(s))

//Init for SD Cards FAT16
SdCard card;
Fat16 file;

// The pins to power LEDs for notifications and error checking
int ledPinY = 5; //yellow
int ledPinG = 6; //green
int ledPinR = 7; //red

// Initialise record count variable
long reccount = 0;

//Setup, code runs once per run
void setup(void)
{
  Serial.begin(9600);
  Serial.println();

//led initialse pins as outputs
  pinMode(ledPinG, OUTPUT);
  pinMode(ledPinR, OUTPUT);    
  pinMode(ledPinY, OUTPUT);    
  
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

// initialize the SD card, using true as I'm using a resistor voltage control for SD Card
  if (!card.init(true)) 
  {
    digitalWrite(ledPinY, HIGH); //red and yellow on for error
    digitalWrite(ledPinR, HIGH);
    error("card.init");
  }

  if (!Fat16::init(card))
  {
    digitalWrite(ledPinY, HIGH); //all lights on for error
    digitalWrite(ledPinR, HIGH);
    digitalWrite(ledPinG, HIGH);
    error("Fat16::init");
  }
  
// Now let's create a new logging file
  char name[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) 
  {
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
  if (file.open(name, O_CREAT | O_EXCL | O_WRITE))break;
  }
  if (!file.isOpen()) error ("file.create");
  Serial.print("Logging to: ");
  Serial.println(name);

// Write the header at the top of the log file
  file.writeError = 0;
  file.print("time");
  file.print(",");
  file.print("date");
  file.print(",");
  file.print("records");
#if ECHO_TO_SERIAL 
  Serial.print("time");
  Serial.print(",");
  Serial.print("date");
  Serial.print(",");
  Serial.print("records");  
#endif //ECHO_TO_SERIAL

//Test the number of sensors to log
#if SENSOR_COUNT > 6
#error SENSOR_COUNT too large
#endif //SENSOR_COUNT

//Cycle number of sensors and write header for each

  for (uint8_t i = 0; i < SENSOR_COUNT; i++) 
  {
    file.print(",sens");file.print(i, DEC);    
    #if ECHO_TO_SERIAL
    Serial.print(",sens");Serial.print(i, DEC);
    #endif //ECHO_TO_SERIAL
  }
  
  file.println();  
  #if ECHO_TO_SERIAL
  Serial.println();
  #endif  //ECHO_TO_SERIAL

  if (file.writeError || !file.sync()) 
  {
    error("write header");
    digitalWrite(ledPinG, HIGH); //red and green on for error
    digitalWrite(ledPinR, HIGH);    
  }

}

//Void Loop, all the main processing is done in here.
void loop(void)
{
  reccount = reccount + 1;
  // clear print error
  file.writeError = 0;
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  
  //hold time/date values  
  char time[8]; 
  char date[9]; 
 
  // lets log it!
  file.print(getClock(time));
  file.print(',');
  file.print(getDate(date));
  file.print(',');
  file.print(reccount);   
  #if ECHO_TO_SERIAL
  Serial.print(getClock(time));
  Serial.print(',');
  Serial.print(getDate(date));
  Serial.print(',');
  Serial.print(reccount);   
  #endif //ECHO_TO_SERIAL
      
  // log the sensor data 
  for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) 
  {
    uint16_t data = analogRead(ia);
    file.print(',');    
    file.print(data);
    #if ECHO_TO_SERIAL
    Serial.print(',');   
    Serial.print(data);
    #endif //ECHO_TO_SERIAL
  }
  
  file.println();  
  #if ECHO_TO_SERIAL
  Serial.println();
  #endif //ECHO_TO_SERIAL
  
  //blink LED to show logging status
  digitalWrite(ledPinG, (millis() / 500) & 1); 
  
  //Notify upon error
  if (file.writeError) 
  {
    digitalWrite(ledPinR, HIGH); 
    error("write data");
  }
  
  // FAT16Lib OK regulate the amount of sync - requires 2048 bytes of I/O to SD card
  if ((millis() - syncTime) <  SYNC_INTERVAL) return;
  syncTime = millis();
  
  if (!file.sync())
  {
     digitalWrite(ledPinY, HIGH); 
     error("sync");
  } 

}

///////////////// 
// Subroutines // 
///////////////// 

// FAT16Lib store error strings in flash to save RAM
void error_P(const char *str)
{
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode) 
  {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode, HEX);
    Serial.print(',');
    digitalWrite(ledPinR, HIGH);
    digitalWrite(ledPinG, LOW); 
  }
  while(1);
}

// Get the time from the external clock 
char* getClock(char *timeStr) 
{ 
  char buffer[5]=" "; 
  itoa(RTC.get(DS1307_HR,true),buffer,10); //Hours
  strcpy(timeStr,buffer); 
  strcat(timeStr,":"); 
  itoa(RTC.get(DS1307_MIN,false),buffer,10); //Minutes
  if (strlen(buffer)==1)// Add 0 if a single digit minute has been returned 
  { 
    strcat(timeStr,"0");  
  }
  strcat(timeStr,buffer); 
  strcat(timeStr,":");
  itoa(RTC.get(DS1307_SEC,false),buffer,10); //Seconds
  if (strlen(buffer)==1)// Add 0 if a single digit second has been returned 
  { 
    strcat(timeStr,"0");  
  }  
  strcat(timeStr,buffer); 
  return timeStr; 
} 

// Get the date from the external clock 
char* getDate(char *dateStr) 
  { 
    char buffer[5]=" "; 
    itoa(RTC.get(DS1307_DATE,true),buffer,10); 
    strcpy(dateStr,buffer); 
    strcat(dateStr,"/");  
    itoa(RTC.get(DS1307_MTH,false),buffer,10); 
    strcat(dateStr,buffer); 
    strcat(dateStr,"/"); 
    itoa(RTC.get(DS1307_YR,false),buffer,10);  
    strcat(dateStr,buffer); 
    return dateStr; 
  }

Image: