FileLogger

I've created a new library for Arduino to append data to files in microSD memory cards. It is based on previous work by David Cuartiello, and it has been used in GPSLogger by Raúl Hevia.

This project focus in just one simple functionality: logging data to a file in SD cards from Arduino boards.

We are trying to get it 1) fast and 2) small, so this library can be used in other projects based on arduino with little impact on memory resources and performance.

By now, it takes about 175 mSecs to append 512 bytes to the file, so transfer rate is about 2925 bytes per second.

The library memory footprint is:

  • 3764 bytes in program memory (Flash)
  • 542 bytes in data memory (SRAM)

The library has been contributed as OpenSource unde GPL license, you can find source code here:
http://code.google.com/p/arduino-filelogger

Does the SD card need to be prepared in any fashion, does it need to be formatted a certain way, before using it with this library?

Does the card need to have a file created, with a particular label, before using it with the library?

Can data be added to more than one file on the SD card?

Using FileLogger, where would data be entered on the arduino board (which pin, or pins)?

My Hardware/Libraries already has an MMC folder, I'm assuming that it will be different from MMC folder that the FileLogger requires, which would result in a conflict. (I'm assuming)

Hi prakat,

yes, the SD card need to be formated with FAT16.
You need to create a file in the root folder, the name is not important as you will give the name of the file when you call the function append(). In fact you can log to more than one file specifying differente file names. The only restriction for the files is that the size must not be zero (at least one character must be written before using the liberay).
This library has been tested with the microSD shield by Libelium: Howly | Get Professional Advice & Answers to Your Questions From an Expert
Anyway I guess this should work with any SPI aware shield.
There should be no conflict with mmc library, as I didn't modify it.

Hope this help

Thanks edugarcia!
I am looking forward to trying this out.

So far, I can't get the example to compile. I get:
In function 'void loop()':
error: 'File_logger' was not declared in this scope

The 3 .o files were created when I started the IDE. Am I missing something?

John

John,

try to update from subversion, I changed the example some days ago and forgot to change the example code. The point is that from now on you should use FileLogger::append() instead of File_logger.append().

sorry about it,

Eduardo.

How is data read from the SD card?
Can data be entered directly to a PC from the card via USB ?

Thank you for your previous information. :slight_smile:

Pakrat,

yes, data can be read directly from PC. You can open the file with any text editor (i.e. notepad).

Eduardo,
What's your experience regarding when you can pull the card? Must power be off?

John,

in my experience you can pull the card anytime, I haven't had any special care about it and never lost data.
Anyway, I have found from time to time (maybe 1 in 20 times) that the system doesn't recognise the card after inserting it, so write fails (the function append() returns != 0). A friend has proposed a workaround: to write some header in the file before writing the real data. If this write fails, the led blinks five times to inform, so you should remove and re-insert the card. It isn't a perfect solution, but it works.

Hi,

I've uploaded a new release of the library, V05.
I have removed from MMC the SPI related code, and I have coupled MMC to the Arduino SPI Library instead, as some of you have reported having problems with SPI and this library.
By the way, if you are using SPI in your projects, you can remove Spi.cpp from FileLogger library, it will work.
Together with some small changes in code, we have won 163 bytes in Flash memory in this release, so total size is 3601 bytes now.

Enjoy it,

Eduardo García.

Will this library tolerate the following scenario?

1 - I write several lines to the SD Card
2 - I remove the SD card and re-insert it
3 - I write more lines to the SD Card

I am trying it with your example code, and I get file errors when I try to write after re-inserting the card. The only way to fix it seems to be resetting the Arduino.

Thanks.

RB123,

I guess there is some conflict with the monitor serial libraries that I'm using to read keystrokes and write messages, so from time to time I have found such errors, but I think if you use fileLogger in a standalone application, with no monitor, it will work fine.
Anyway, there is a workaround: anytime you find errors writing after re-inserting the card, close and reopen the serial line (click on the icon at the upper right). This will not reset Arduino, only the serial line.

@RB123, I had the same problem (I am using the SD card socket from Sparkfun, not MicroSD, with a Panasonic card). Also, mine is running on solar and if the voltage dropped and then came back up, the card would stop working.

I made a change in nanofat.cpp (this is a TOTAL hack, but I may go through it again when I have time). Basically it was erroring out in locateFileStart when it called mmc::readSector. I added code to line 183, after the second-to-last closing bracket in the function:

} [glow]else {
   mmc::initialize();
  }[/glow]

  return false;

So it will still return false to show it had an error, but it will reinitialize the card and usually works on the next write, although sometimes it take 2 writes to kick it back on.

I anybody with better coding skillz wants to improve on my hack, feel free. :smiley:

Hi,

I'm using FileLogger lib.
I would like to create a function for logging info bat i have a problem with variables:

my code:

 void write_log(char msg[]){
 unsigned int length = (strlen(msg)+1);
  byte buffer[length];
  buffer = msg;
  FileLogger::append(FILE_LOG, buffer, length);
  }

on my loop:

write_log("test 123 prova 123");

but error generated

 In function 'void write_log(char*)':
error: incompatible types in assignment of 'char*' to 'byte [(((unsigned int)(((int)length) + -0x000000001)) + 1)]

please help me?

thanks!!

Marcoberri,

first, "buffer" is a pointer to a new assigned array of bytes. If you do this assignment:

buffer=msg;

you are trying to point "buffer" to the incoming "msg" array, so you would lose any reference to your array. Instead, you should copy any single char in the "msg" array to the "buffer" array:

for(int i=0; i<length;i++) {
buffer = msg*;*
}
[/quote]
By the way, you better declare your "buffer" array as a char array, instead of byte array:
> char buffer[length];
Hope this help,
Eduardo

it's ok! Thank You Very Much!!!

the final code:

 void write_log(char msg[]){
 unsigned int length = (strlen(msg)+1);
  byte buffer[length];
  Serial.print(length);
  for(int i=0; i<length;i++) 
    buffer[i] = msg[i];
  FileLogger::append(FILE_LOG, buffer, length);
  }

Hi,

I'm hoping to use FileLogger to store data from a weather station I'm building but I'm having some problems with it. I did have it working but now it's stopped and I can't figure out why. I could do with some help/suggestions please!

I'm using the FileLoggerDemo code:

// Title        : FileLogger library for Arduino, example code
// Author       : Eduardo García (egarcia@stream18.com)
// Date         : April 2009
// Id                  : $Id: FileLoggerDemo.pde 24 2009-04-23 22:45:13Z stream18 $
//
// DISCLAIMER:
// The author is in no way responsible for any problems or damage caused by
// using this code. Use at your own risk.
//
// LICENSE:
// This code is distributed under the GNU Public License
// which can be found at ...
//


#include "FileLogger.h"

// define the pin that powers up the SD card
#define MEM_PW 8

// variable used when reading from serial
byte inSerByte = 0;

#define MESSAGE "Hello, this is my message. Just testing the FileLogger library.\r\n"
unsigned long length = sizeof(MESSAGE)-1;
byte buffer[] = MESSAGE;

void setup(void) {
  pinMode(MEM_PW, OUTPUT);
  digitalWrite(MEM_PW, HIGH);
  Serial.begin(9600);
}

void loop(void) {
  char command = '0';
  unsigned long t1, t2;

  // Arduino expects one of a series of one-byte commands
  if (Serial.available() > 0) {
    int result;
    inSerByte = Serial.read();
    switch (inSerByte) {
      case 'W':
        result = FileLogger::append("data.log", buffer, length);
        Serial.print(" Result: ");
        if( result == 0) {
          Serial.println("OK");
        } else if( result == 1) {
          Serial.println("Fail initializing");
        } else if( result == 2) {
          Serial.println("Fail appending");
        }
      break;
    case 'T':
        for(int i=0; i<10; i++) {
            result = FileLogger::append("data.log", buffer, length);
              Serial.print(" Result: ");
              if( result == 0) {
                Serial.println("OK");
              } else if( result == 1) {
                Serial.println("Fail initializing");
              } else if( result == 2) {
                Serial.println("Fail appending");
              }
        }
          Serial.print("Done");
      break;
    }
  }
}

When I try to write to a file on an SD card by typing 'W' into the serial monitor I get ' Result: Fail initializing'. There is one file on the card, called data.log, and it has one character in it to initialise it.

The fact that I had it working before and haven't changed anything makes me think it might be a hardware problem. Is there any way of testing this?

I'm using an Arduino Duemilanove, a microSD board from Libelium and the latest version of the IDE.

Apologies if I've done something stupid but I'm completely new to all this!

Hi Linstead,

just one suggestion: try to format your SD card again, then create the one-byte-file "data.log". Maybe there is nothing wrong with the hardware, but maybe there is a problem with the card.

Hi edugarcia,

Thanks for the suggestion. I've tried refomatting and making sure that the file is 1 byte, and I've tried other cards, but I still get the same problem.