SD card read/write with Arduino

if anyone want the PCB file, send me a PM, its make on eagle software

:wink:

Hello All!
I'm am new to the Sd card phase. My question is which of the libraries and setups do you recommend for logging gps data strings to an sd card. Yes I know about Ladyadas shield and code but I am overwhelmed. I bought the sparkfun arduino sd shield without realizing it was a failed product. Through the forums I found how to wire it up and got the sparkfun code working but I'm still having small issues. So i'm coming here to find out where i should start.

Jon

I am looking for a library that solves my needs or information on how to do it. I have a project that will use asynclab's wishield and a microsd card. All I need to do is read files from an SD card. There can be any number of files on the SD card so I think uFAT is out. I can do what I want with sdlaftlib after I make my own read function. I need to be able to read a byte at a specific position in a file. The files will be created on a PC.

When I include both the wishield and sdfatlib they don't leave much memory left for the program. In fact, right now my program is 1.3k over the limit of a 368 arduino. I went through the sdfatlib and took out everything that deals with writing to files as I don't need that. I also went through my code and made sure I didn't allocate memory when I didn't need to. I got it down to 1k over the limit.

Since I just need to read from a microsd I was wondering if there is a library that takes up a smaller footprint that will do that.

I was not sucessfull in write/read SD Card using this schematics and library. Could someone give a help? I'm using an Kingston 1GB SD Card, and an Freeduino v1.0. I had connected the SD Card like this picture, but I was not sucessful.

someone might use it? (the circuit and the lib)

tnks

Just to say thanks. I got a seeeduino a couple of days ago, tried using a card holder hacked from a broken camera and couldn't get the DevicePrintDemo to work (mmc::initialize() returned 3). All the connections tested ok with a multimeter on beep but I noticed a (2k) short on one of the connections. So I took the advice elsewhere in this or parallel thread and soldered wires directly to a micro-adapter, set the + to 3v3 and it just worked - no resistors needed!!

The adapter seemed to have pin 3 connected to pin 6 internally so that saved one of the connections.

Hi,
as soon as I try and run this example I receive the following error:
My Documents\arduino-0018\libraries\SDcard\arduino sd card example.cpp:161: error: 'DEC' was not declared in this scope

This makes no sense to me as "DEC" seems to be used in the correct way throughout the example. Can anyone help?

Many thanks!

NOTE: I'm using Arduino_0018 and the "libraries" folder is not within the "hardware" folder, does this matter?

Hi to all,

This is N.Nandhakumar again. After a lot of struggle I have purchased the EM-406a GPS module, Adafruit GPS shield V1.1, Freeduino ATMega328 for my project.
I soldered the GPS shield , interfaced it with the Arduino and the GPS logged data successfully into the SD card.
Now, I have a problem. I want to read back the logged data from the log file stored in SD card for doing some processing, comparison with the data. I made use of SdFat library's SdFatRead example code and I was able to read back the file contents .

/*
 * This sketch reads and prints the file
 * PRINT00.TXT created by SdFatPrint.pde or
 * WRITE00.TXT created by SdFatWrite.pde
 */
#include <SdFat.h>
#include <SdFatUtil.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}
void setup(void)
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("type any character to start");
  while (!Serial.available());
  Serial.println();
  
  // initialize the SD card
  if (!card.init()) error("card.init");
  
  // initialize a FAT volume
  if (!volume.init(card)) error("volume.init");
  
  // open the root directory
  if (!root.openRoot(volume)) error("openRoot");
  
  // open a file
  if (file.open(root, "PRINT00.TXT", O_READ)) {
    Serial.println("Opened PRINT00.TXT");
  }
  else if (file.open(root, "WRITE00.TXT", O_READ)) {
    Serial.println("Opened WRITE00.TXT");    
  }
  else{
    error("file.open");
  }
  Serial.println();
  
  // copy file to serial port
  int16_t n;
  uint8_t buf[7];// nothing special about 7, just a lucky number.
  while ((n = file.read(buf, sizeof(buf))) > 0) {
    for (uint8_t i = 0; i < n; i++) Serial.print(buf[i]);
  }
  /* easier way
  int16_t c;
  while ((c = file.read()) > 0) Serial.print((char)c);
  */
  Serial.println("\nDone");
}

void loop(void) {}

The problem is that the file contents are read in raw format using uint8_t [ I googled about this datatype . But I am not clear with this datatype and how it works :frowning: ] . It will be more useful If I could read the data from the file in char or string format .

I searched for a better way to convert the uint8_t data to char datatype. But I get only junk characters.

I need the forum's help to solve this issue. Please give your suggestions on this.
Please help me out. Waiting for your valuable suggestions.

My works on the project at : http://walkingwithtux.wordpress.com/2010/05/02/tran-duino-under-progress/

Regards

N.Nandhakumar :slight_smile:

Hi,

Do you think you could post here what is the content of the file you are reading and what you are seeing in the serial window? I'm not sure if I can help you out, but I think that information would be helpful.

Good luck!

Hi cemath,

Thanks for the reply. THe code which I edited in the SdFatRead Example is

  int16_t n;
  char msg;
  uint8_t buf[7];// nothing special about 7, just a lucky number.
  while ((n = file.read(buf, sizeof(buf))) > 0)
  {
    for(uint8_t i=0;i < n;i++)
       msg = (char)buf[i];
       Serial.print(msg);
  }
  Serial.println("\nDone");

I am trying to read the file contents , convert them to char type from uint8_t type.

The file which I am trying to read from SD card is the GPSLOG00.TXT . the file contains GPS sentences logged into a text file from GPS.
The contents are

$GPRMC,112209.290,A,1307.3214,N,08013.3322,E,,,030510,,*0D
$GPRMC,112210.290,A,1307.3089,N,08013.3367,E,,,030510,,*02
$GPRMC,112211.290,A,1307.3299,N,08013.3306,E,,,030510,,*07
$GPRMC,112212.290,A,1307.3512,N,08013.3207,E,,,030510,,*00
$GPRMC,112213.290,A,1307.3630,N,08013.3141,E,,,030510,,*03
$GPRMC,112214.290,A,1307.3468,N,08013.3262,E,,,030510,,*09
$GPRMC,112215.290,A,1307.3531,N,08013.3234,E,,,030510,,*06
$GPRMC,112216.290,A,1307.3595,N,08013.3207,E,,,030510,,*0B
$GPRMC,112217.290,A,1307.3534,N,08013.3249,E,,,030510,,*0B
$GPRMC,112218.290,A,1307.3502,N,08013.3273,E,,,030510,,*08
$GPRMC,112219.290,A,1307.3489,N,08013.3282,E,,,030510,,*05
$GPRMC,112220.290,A,1307.3705,N,08013.3196,E,,,030510,,*0E
$GPRMC,112221.290,A,1307.3383,N,08013.3295,E,,,030510,,*05
$GPRMC,112222.290,A,1307.3405,N,08013.3251,E,,,030510,,*07
$GPRMC,112223.290,A,1307.3420,N,08013.3292,E,,,030510,,*0E
$GPRMC,112224.290,A,1307.3526,N,08013.3229,E,,,030510,,*0E
$GPRMC,112225.290,A,1307.3553,N,08013.3228,E,,,030510,,*0C
$GPRMC,112226.290,A,1307.3535,N,08013.3259,E,,,030510,,*09
$GPRMC,112227.290,A,1307.3417,N,08013.3269,E,1.42,312.24,030510,,*0B
$GPRMC,112228.000,A,1307.3425,N,08013.3270,E,0.33,308.80,030510,,*04
$GPRMC,112229.000,A,1307.3422,N,08013.3278,E,0.04,240.51,030510,,*0F
$GPRMC,112230.000,A,1307.3417,N,08013.3283,E,0.23,173.43,030510,,*00
$GPRMC,112231.000,A,1307.3416,N,08013.3285,E,0.34,164.87,030510,,*0E
$GPRMC,112232.000,A,1307.3413,N,08013.3285,E,0.53,166.36,030510,,*01
$GPRMC,112233.000,A,1307.3410,N,08013.3286,E,0.63,159.12,030510,,*09
$GPRMC,112234.000,A,1307.3406,N,08013.3288,E,0.72,157.94,030510,,*07
$GPRMC,112235.000,A,1307.3404,N,08013.3290,E,0.78,157.79,030510,,*04
$GPRMC,112236.000,A,1307.3400,N,08013.3295,E,1.01,158.20,030510,,*0A
$GPRMC,112237.000,A,1307.3394,N,08013.3298,E,0.58,151.13,030510,,*08
$GPRMC,112238.000,A,1307.3391,N,08013.3302,E,0.23,124.27,030510,,*09
$GPRMC,112239.000,A,1307.3392,N,08013.3305,E,0.23,144.30,030510,,*0C
$GPRMC,112240.000,A,1307.3393,N,08013.3306,E,0.19,0.60,030510,,*0D
$GPRMC,112241.000,A,1307.3391,N,08013.3308,E,0.55,344.99,030510,,*0D
$GPRMC,112242.000,A,1307.3393,N,08013.3309,E,0.65,346.12,030510,,*0F
$GPRMC,112243.000,A,1307.3391,N,08013.3311,E,0.58,327.75,030510,,*0D
$GPRMC,112244.000,A,1307.3392,N,08013.3312,E,0.31,315.15,030510,,*02
$GPRMC,112245.000,A,1307.3390,N,08013.3311,E,0.43,334.94,030510,,*0D
$GPRMC,112246.000,A,1307.3393,N,08013.3305,E,0.45,322.00,030510,,*04
$GPRMC,112247.000,A,1307.3396,N,08013.3301,E,0.76,330.60,030510,,*01
$GPRMC,112248.000,A,1307.3397,N,08013.3297,E,0.27,314.78,030510,,*0A
$GPRMC,112249.000,A,1307.3400,N,08013.3295,E,0.36,20.55,030510,,*3B
$GPRMC,112250.000,A,1307.3400,N,08013.3290,E,0.29,263.99,030510,,*0D
$GPRMC,112251.000,A,1307.3397,N,08013.3288,E,0.48,229.59,030510,,*09
$GPRMC,112252.000,A,1307.3398,N,08013.3284,E,0.41,316.03,030510,,*02
$GPRMC,112253.000,A,1307.3398,N,08013.3280,E,0.80,313.98,030510,,*0D
$GPRMC,112254.000,A,1307.3401,N,08013.3277,E,1.11,318.17,030510,,*00
$GPRMC,112255.000,A,1307.3403,N,08013.3274,E,1.02,322.50,030510,,*08
$GPRMC,112256.000,A,1307.3406,N,08013.3268,E,0.51,310.56,030510,,*03
$GPRMC,112257.000,A,1307.3405,N,08013.3265,E,0.20,172.19,030510,,*07
$GPRMC,112258.000,A,1307.3405,N,08013.3265,E,0.25,131.33,030510,,*02
$GPRMC,112259.000,A,1307.3405,N,08013.3263,E,0.50,286.05,030510,,*0D
$GPRMC,112300.000,A,1307.3405,N,08013.3263,E,0.43,318.18,030510,,*08
$GPRMC,112301.000,A,1307.3406,N,08013.3262,E,0.14,166.60,030510,,*0D
$GPRMC,112302.000,A,1307.3403,N,08013.3263,E,0.23,93.57,030510,,*31
$GPRMC,112303.000,A,1307.3400,N,08013.3267,E,0.58,150.75,030510,,*05
$GPRMC,112304.000,A,1307.3396,N,08013.3268,E,0.73,157.31,030510,,*0B
$GPRMC,112305.000,A,1307.3395,N,08013.3270,E,0.23,144.14,030510,,*00
$GPRMC,112306.000,A,1307.3395,N,08013.3272,E,0.21,139.18,030510,,*05
$GPRMC,112307.000,A,1307.3393,N,08013.3272,E,0.28,356.23,030510,,*08
$GPRMC,112308.000,A,1307.3391,N,08013.3272,E,0.12,3.89,030510,,*0F
$GPRMC,112309.000,A,1307.3390,N,08013.3273,E,0.15,342.02,030510,,*0C
$GPRMC,112310.000,A,1307.3388,N,08013.3272,E,0.03,14.17,030510,,*3F
$GPRMC,112311.000,A,1307.3388,N,08013.3272,E,0.51,352.24,030510,,*08
$GPRMC,112312.000,A,1307.3389,N,08013.3272,E,0.43,339.14,030510,,*07
$GPRMC,112313.000,A,1307.3389,N,08013.3272,E,0.11,290.20,030510,,*04
$GPRMC,112314.000,A,1307.3388,N,08013.3270,E,0.21,235.81,030510,,*07
$GPRMC,112315.000,A,1307.3388,N,08013.3270,E,0.17,241.13,030510,,*0B
$GPRMC,112316.000,A,1307.3386,N,08013.3272,E,0.18,122.90,030510,,*06
$GPRMC,112317.000,A,1307.3385,N,08013.3275,E,0.25,29.10,030510,,*3F
$GPRMC,112318.000,A,1307.3385,N,08013.3277,E,0.07,201.14,030510,,*0E
$GPRMC,112319.000,A,1307.3385,N,08013.3278,E,0.48,0.37,030510,,*09
$GPRMC,112320.000,A,1307.3385,N,08013.3281,E,0.40,346.95,030510,,*04
$GPRMC,112321.000,A,1307.3387,N,08013.3281,E,0.78,340.65,030510,,*05
$GPRMC,112322.000,A,1307.3388,N,08013.3282,E,0.23,328.18,030510,,*00
$GPRMC,112323.000,A,1307.3388,N,08013.3283,E,0.79,341.04,030510,,*0D
$GPRMC,112324.000,A,1307.3389,N,08013.3282,E,0.48,321.94,030510,,*07
$GPRMC,112325.000,A,1307.3390,N,08013.3280,E,0.11,297.44,030510,,*01
$GPRMC,112326.000,A,1307.3390,N,08013.3275,E,0.27,211.88,030510,,*03
$GPRMC,112327.000,A,1307.3389,N,08013.3270,E,0.43,291.88,030510,,*05
$GPRMC,112328.000,A,1307.3388,N,08013.3266,E,0.57,203.58,030510,,*0F
$GPRMC,112329.000,A,1307.3386,N,08013.3265,E,0.12,265.01,030510,,*0E
$GPRMC,112330.000,A,1307.3389,N,08013.3261,E,0.10,192.25,030510,,*02
$GPRMC,112331.000,A,1307.3391,N,08013.3259,E,0.37,338.75,030510,,*03
$GPRMC,112332.000,A,1307.3392,N,08013.3257,E,0.36,345.45,030510,,*05
$GPRMC,112333.000,A,1307.3392,N,08013.3256,E,0.19,286.73,030510,,*03
$GPRMC,112334.000,A,1307.3395,N,08013.3254,E,0.52,327.34,030510,,*07
$GPRMC,112335.000,A,1307.3395,N,08013.3253,E,0.21,248.92,030510,,*01
$GPRMC,112336.000,A,1307.3395,N,08013.3252,E,0.21,301.84,030510,,*08
$GPRMC,112337.000,A,1307.3395,N,08013.3252,E,0.09,264.22,030510,,*0D
$GPRMC,112338.000,A,1307.3396,N,08013.3252,E,0.16,346.95,030510,,*02
$GPRMC,112339.000,A,1307.3397,N,08013.3252,E,0.11,277.62,030510,,*0E
$GPRMC,112340.000,A,1307.3396,N,08013.3252,E,0.31,346.83,030510,,*0F
$GPRMC,112341.000,A,1307.3394,N,08013.3253,E,0.23,330.10,030510,,*05
$GPRMC,112342.000,A,1307.3394,N,08013.3254,E,0.20,327.85,030510,,*08
$GPRMC,112343.000,A,1307.3392,N,08013.3255,E,0.12,193.25,030510,,*08
$GPRMC,112344.000,A,1307.3391,N,08013.3256,E,0.29,347.05,030510,,*0E
$GPRMC,112345.000,A,1307.3389,N,08013.3257,E,0.40,340.46,030510,,*08
$GPRMC,112346.000,A,1307.3388,N,08013.3258,E,0.20,327.57,030510,,*02
$GPRMC,112347.000,A,1307.3388,N,08013.3258,E,0.35,339.64,030510,,*08
$GPRMC,112348.000,A,1307.3389,N,08013.3259,E,0.13,322.44,030510,,*0B
$GPRMC,112349.000,A,1307.3389,N,08013.3260,E,0.08,272.78,030510,,*01
$GPRMC,112350.000,A,1307.3388,N,08013.3260,E,0.12,204.95,030510,,*01
$GPRMC,112351.000,A,1307.3387,N,08013.3261,E,0.05,209.98,030510,,*08

When I uploaded the code , The serial monitor contents are,

Opened GPSLOG00.TXT



,.11023*R2,.,3,0$12391,00M1A302,,G190,3E53C4,4860,P207N.,1
,.19073*R2,.,3,0$12321,00M1A302,,G190,3E5EC1,3890,P207N.,1
,.12023*R2,.,3,0$12331,00M2A302,,G190,3E30,P207N.,03*R2,.,30000M3A302..50C1,488381
,.1105360$10301,,,,G100,3E10,P207N.,53*R2,.,31800M3A302..58C8,380221
,.1905300$10331,,3*R2,.,30400M4A303..5FC3,381571
,.1902150$10301,,,,G100,3E30,P207N.,33*R2,.,30400M4A302.51
,.1000990$10371,,,,G100,3E30,P207N.,13*R2,.,31800M5A302..58C6,486551
,.1005090$10351,,,,G100,3E20,P207N.,13*R3,.,30600M0A302.51
,.1007850$10361,,,,G100,3E10,P207N.,33*R3,.,30600M0A302.90$10301,,,,G100,3E13*R3,.,30200M1A302..57C3,387121
,.1800110$10381,,,,G100,3E10,P207N.,903M1A302..5EC9,3874,,G100,3E30,P207N.,43*R3,.,30800M2A302..5DC4,388491
,.1900140$10301,,,,G100,3E20,P207N.,03*R3,.,30500M3A302..52C1,385371
,.1907650$10321,,,,G100,3E30,P207N.,43*R3,.,30100M3A302..5DC8,385191
,.1902120$10361,,,,G100,3E30,P207N.,23*R3,.,30300M4A302..5EC5,385441
,.1808070$10381,,,,G100,3E30,P207N.,73*R3,.,30400M5A302..58C2,386241
,.1807940$10311,,0,P207N.,.5FC6,387180$10381,,3*R3,.,30.5FC9,388160$10371,,,,G100,3E10,P207N.,63*R4,.,30700M0A302..5BC5,389131
,.1603360$10311,,,,G100,3E10,P207N.,903M1A303..58C1,380401
,.1604860$10301,,0,P207N.,53*R4,.,30.52C6,380430$10331,,0,P207N.,73*R4,.,30.5FC0,380121
,.1601750$10311,,,,G100,3E10,P207N.,33*R4,.,30800M2A303.71
,.15093,,G100,3E10,

Done

The contents in the serial monitor are of different format [ I think its of HEX type]
and the full contents are also not fully converted and displayed in the serial monitor. Please help me out and tell me where I made wrong in the code. I also need to convert the full contents into char, since the log file is very huge.

Thanks in advance
N.Nandhakumar

Hi Nnk,

I found a pattern while comparing the data in your file and the data that is displayed in the monitor window. If you break the file data in blocks of 7 characters (the last caracter of a line, break line, counts as a caracter), and you keep only the last caracter of each block, then you can reconstruct what you are seeing in the monitor window. The problem must be in the example code you use to display the caracters, but I do not see it. I suspect that by reading a single byte at a time (using uint8_t buf[1] instead of uint8_t buf[7]) it should correct the problem, but that doesnt not explain it.

I suggest that you debug the code step by step by displaying the value of 'n' and other variables to verify that the program is doing what it should.

Also, I think that going throught the 'char' intermediate step is not necessary, because the formats 'uint8_t' and 'char' are very similar. I think uint8_t is equivalent to the format 'byte', which is 8 bits unsigned, and char is 8 bits signed. But since the caracters in ASCII are encoded on a range from 0 to 127, signed or unsigned bytes make no difference.

I hope that you find the solution to your problem quickly!

Good luck,

cemath

Hi guys

i am in a serious situation, i can't graduate if i don't get done with the datalogging...
so please, help , i very appreciate it
here is the case:
i am having a project that display a speed and record it
the former part is done, however, the later part is very difficult to me
i am trying to save the speed into the SDcard, don't need to read or copy, just write.
here is the code for the former part:

#define FREQ_PIN 3
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
  pinMode(FREQ_PIN, INPUT);
 lcd.begin(16, 2);
}

void loop()
{

unsigned long t1 = pulseIn(FREQ_PIN, HIGH);// Time how long it takes to go HIGH again
unsigned long t2 = pulseIn(FREQ_PIN, LOW); // and how long it takes to go low again.
 double t = t1 + t2;
         double f = 1000000.0/t;
           double w = 2 * 3.14 * f;
           double v = w * 0.05;
       lcd.setCursor(0,0);
         lcd.println(v);
         delay(2000);
}

Help please, I very very appreciate it.

i have the exactly the same circuit with this post, but i don't know how to write, thanks a lot

The code above is created by members, they are Pauls, Groove, AWOL and mem, i couldn't do this without their help, thanks a lot :slight_smile:

Hi

Thanks for the reply Cemath. Really sorry the late post. I tried out as you said. But still I am not getting the expected output. I found that increasing or decreasing the buffer size [ default 7 ] as no effect on the output. The only change is that suppose if I set buffer[10], then while reading the data, I get a junk character or symbol after each tenth character. So, I googled again and seeked help from other forums too. Finally I found the sdfatlib library doing the GPS logging and SDcard read/write functionality. Google Code Archive - Long-term storage for Google Code Project Hosting..
I tried the examples provided by that library and it worked fine. I was able to read data in char datatype. But since, the GPS sentences logged by GPS are of varied length due to absence of some fields, I had problems in parsing the sentence from the file and extracting the latitude and longitude alone for further processing.
So, I tried the otherway around and modified the GPS logging code[ SdFatGPSLogger example from the sdfatlib library] to log only the latitude and longitude into the sdcard textfile. I worked fine. The log file has contents like below,

13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1225,80.2222
13.1225,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2221
13.1227,80.2221
13.1227,80.2221
13.1227,80.2220
13.1227,80.2220
13.1227,80.2219
13.1227,80.2219
13.1227,80.2218
13.1227,80.2218
13.1227,80.2217
13.1227,80.2217
13.1227,80.2216
13.1227,80.2216
13.1227,80.2215
13.1227,80.2215
13.1227,80.2214
13.1227,80.2214
13.1227,80.2214
13.1227,80.2213
13.1227,80.2213
13.1227,80.2213
13.1227,80.2213
13.1228,80.2213

Now, I stored this file in sdcard and tried to read it using the SdFatRead example. the example read the contents. Since, the file contents in each line are of same size, I used a fixed buffer size and used the comma delimiter to parse the data. I stored the latitude and longitude temporarily within the loop using two char arrays. I tried printing it as I read from the card. It worked.
Now, my problem is that , As I read the above data line by line from the card I need to compare it with another char array, so that If the arrays matches, I will send some data to print on the LCD display.
I used string functions. no use. Since the comparsion is between two char arrays, Inclusion of loops doesnot have data in it to compare. I really dont where is the mistake happening. I am stuck in this issue. I have posted the modified code here [ with no comparsion part] . Please help me out.

/*
 * This sketch reads and prints the file
 * PRINT00.TXT created by SdFatPrint.pde or
 * WRITE00.TXT created by SdFatWrite.pde
 */
 #include <stdio.h>
#include <SdFat.h>
#include <SdFatUtil.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}
void setup(void)
{
  Serial.begin(4800);
  Serial.println();
  Serial.println("type any character to start");
  while (!Serial.available());
  Serial.println();
  
  // initialize the SD card
  if (!card.init()) error("card.init");
  
  // initialize a FAT volume
  if (!volume.init(card)) error("volume.init");
  
  // open the root directory
  if (!root.openRoot(volume)) error("openRoot");
  
  // open a file
  if (file.open(root, "GPSLOG00.TXT", O_READ)) {
    Serial.println("Opened GPSLOG00.TXT");
  }
  else if (file.open(root, "WRITE00.TXT", O_READ)) {
    Serial.println("Opened WRITE00.TXT");    
  }
  else{
    error("file.open");
  }
  Serial.println();
  
  // copy file to serial port
  int16_t n;
//  uint8_t buf[19];// nothing special about 7, just a lucky number.
  char buf[15];
  char lat[8],lon[8];
  char temp;
int linecount=494,count=0; // char *latitude="13.1224",*longitude="80.2222";
  char array1[linecount][8],array2[linecount][8];
 while ((n = file.read((uint8_t *)buf, sizeof(buf))) > 0) 
  {
    for(int i=0;i<n;i++)
    {
     if(buf[i]!=',')
      {
        lat[i]=buf[i];
        Serial.print(lat[i]); // This place is where comparsion will occur
      }
      else
      {
        i=i+1;
        lon[i]=buf[i]; // This place is where comparsion will occur 
        Serial.print(lon[i]);
      }
    }
  }
  /* easier way
  int16_t c;
  while ((c = file.read()) > 0) Serial.print((char)c);
  */
 Serial.println("\nDone");
}

void loop(void) {}

My doubt may be silly. But please help me out since I need to complete the project as part of my academics.
Thanks in advance
Regards
N.Nandhakumar

Dear All
I don't meant to hijack this thread, but I also got same problem with sdfatlib, and when I put sdfatlib as search keyword it refer to this thread.

So here we go.
I have a data file like this :

1474,254
1616,253
2998,254
3153,253
3925,254
4094,253
4642,254
4827,253
5255,254
5459,253
5810,254
6039,253
6336,254
6597,253
6851,254
7160,253
7379,254
7768,253
7957,254
8547,253
8705,254
10133,255
10293,254
10831,255
11031,254
11365,255
11617,254
11866,255
12210,254
12405,255
13096,254
13240,255
13600,256
13744,255
14413,256
14614,255
14931,256
15209,255
15431,256
15918,255
16077,256
16803,257
16963,256
17434,257
17664,256
17922,257
18298,256
18474,257
19442,258
19619,257
19981,258
20254,257
20468,258
21838,259
22057,258
22318,259
22746,258
22905,259
23336,260
23494,259
23917,260
24187,259
24395,260
25432,261
25643,260
25905,261
26455,260
26592,261
26613,262
26757,261
27244,262
27523,261
27721,262
28491,263
28690,262
28963,263
30133,264
30414,263
30605,264
31214,265
31406,264
31682,265
32712,266
32995,265
33180,266
33666,267
33852,266
34131,267
35051,268
35337,267
35517,268
35902,269
36082,268
36364,269
37199,270
37488,269
37662,270
37963,271
38138,270
38424,271
39185,272
39479,271
39648,272
39873,273
40042,272
40335,273
41035,274
41333,273
41497,274
41662,275
41826,274
42122,275
42768,276
43072,275
43231,276
43333,277
43491,276
43797,277
44401,278
44717,277
44870,278
44891,279
45039,278
45369,279
45949,280
46294,279
46436,280
46457,281
46621,280
46899,281
47374,282
47659,281
47817,282
47869,283
48025,282
48314,283
48764,284
49059,283
49211,284
49232,285
49389,284
49670,285
50078,286
50366,285
50518,286
50539,287
50699,286
50967,287
51327,288
51599,287
51754,288
51775,289
51932,288
52199,289
52528,290
52797,289
52951,290
52972,291
53133,290
53385,291
53673,292
53928,291
54086,292
54107,293
54268,292
54517,293
54773,294
55019,293
55179,294
55200,295
55361,294
55603,295
55835,296
56079,295
56238,296
56259,297
56427,296
56655,297
56844,298
57069,297
57236,298
57257,299
57418,298
57651,299
57837,300
58073,299
58231,300
58252,301
58427,300
58636,301
58760,302
58962,301
59140,302
59184,303
59356,302
59565,303
59682,304
59889,303
60061,304
60082,305
60251,304
60461,305
60567,306
60773,305
60943,306
60964,307
61139,306
61338,307
61406,308
61594,307
61777,308
61798,309
61965,308
62170,309
62247,310
62447,309
62617,310
62638,311
62827,310
63006,311
63027,312
63205,311
63392,312
63429,313
63616,312
63793,313
63814,314
64001,313
64177,314
64198,315
64391,314
64561,315
64582,316
64788,315
64947,316
64968,317
65219,316
65354,317
65375,318

and here is what I got from SdFatTail.pde

Question :
How to put each "field" of the output into to different variable (ie: var1, var2) rather than printing it out.

here is the code (small edited from original sample)

/*
 * This sketch reads and prints the tail of all files
 * created by SdFatAppend.pde, SdFatPrint.pde, and
 * SdFatWrite.pde.
 */
#include <SdFat.h>
#include <SdFatUtil.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("type any character to start");
  while (!Serial.available());
  Serial.println();
  
  // initialize the SD card
  if (!card.init()) error("card.init");
  
  // initialize a FAT volume
  if (!volume.init(card)) error("volume.init");
  
  // open the root directory
  if (!root.openRoot(volume)) error("openRoot");
}

/*
 * Print tail of all SdFat example files
 */
void loop(void)
{
  dir_t dir;
  char name[13];
  
  // read next directory entry
  if (root.readDir(dir) != sizeof(dir)) {
    Serial.println("End of Directory");
    while(1);
  }
  
  // check for file name "APPEND.TXT", "PRINT*.TXT"
  // or "WRITE*.TXT"
  // first 8 bytes are blank filled name
  // last three bytes are blank filled extension
  if ((strncmp((char *)dir.name, "MYSTEP", 6)) ||
      strncmp((char *)&dir.name[8], "TXT", 3)) {
        return;
  }
  // format file name
  SdFile::dirName(dir, name);
  
  // remember position in root dir
  uint32_t pos = root.curPosition();
  
  // open file
  if (!file.open(root, name, O_READ)) error("file.open");
  
  // restore root position
  if (!root.seekSet(pos)) error("root.seekSet");
  
  // print file name message
  Serial.print("Tail of: ");
  Serial.println(name);
  
  // position to tail of file
  //if (file.fileSize() > 100) {
  //  if (!file.seekSet(file.fileSize() - 100)) error("file.seekSet");
  //}
  int16_t c;
  // find end of line  
  //while ((c = file.read()) > 0 && c != '\n');
  
  // print rest of file
  while ((c = file.read()) > 0) 
  {
    Serial.print((char)c);
  }
  file.close();
  Serial.println();
}

Sincerely
-bino-

Does it work with a micro-SD ? I been trying use it but it didnt work out :frowning:

I'm having the same problem as alecjcook. when i put the #includes in an otherwise skeleton sketch i get:

C:\Program Files\arduino-0018\libraries\SDcard\arduino sd card example.cpp:161: error: 'DEC' was not declared in this scope

along with 'HEX' not declared, 'Serial' not declared, 'delay' not declared ...

does the cpp file need some tweaking maybe?

Hi, delete #include <FatStructs.h> and the problems disappear.

I have other problem how i can change the pins 10-13 to 5-8?I modified Sd2PinMap but not working.

Thanks

Hi everyone,
I'm sorry to re-ressurect this, but this library seems to be the best (of the thousand SD Libraries) to fit my needs...

I've got the same problem as post number 136 in page 10 (I would post the link, but I'm not allowed).

Seems like it is not compiling in Arduino 19. I tried out the soluton proposed in the next post, but it didn't help :frowning:

EDIT: Ok, it's because it doesn't work on ATmega328...

Guys, how do I get this working with the Arduino Mega (Atmega1280) Thanks.

H there,

First of all, thanls so much for this great tutorial. Some weeks ago i developed my own SD Card shield and it runs perfectly.

However, now i have a problem: sometimes it does not write data into the SD.

Let me explain. I made a datalogger based on a RTC ds1337 and a SD card wired such as showed in this topic. No apparenty it is not the problem.
I have the arduino sleeping most of the time, and ones per hour the rtc get up the arduino and measure by different senors, and save the data into a SD.

From time to time i remove the SD card from its slot and check the new data. I observed that when i do it (remove and put the SD card into the slot again, it does not save the data). BUT if i remove the slot, but if i remove the power to arduino just immediately after to put the SD card into the slot, OR push the reset button (at the end it is the same)... the next data are saved. :-/

So, i am a little bit lost in this situation. It is not a big problem, because to remove the power and connecting it again is enough, or pushing the reset button but it is not ideal for my project..., right?

I use the filelogger library.

The code is prettly long, so i put here just only the essential lines..

#include <FileLogger.h>                      // Librería para almacenamiento de dtos en microSD
#include <DallasTemperature.h>               // Librería para el sensor de temperatura DS18B20
#include <OneWire.h>
#include <Wire.h>
#include <DS1337.h>                          // Librería para el RTC DS1307
#include <Sensirion.h>                       // Librería para el sensor de temperatura y humedad SH15
#include <avr/power.h>
#include <avr/sleep.h>                       // Librería para modo dormir del microcontrolado

// Definición de los pin analógicos
#define luz 0                                // Luminosidad LDR
#define suelo 1                              // Humedad del suelo
#define lluvia 2                             // Intensidad de la lluvia
#define bateria 3                            // Voltaje de entrada

// Definición de los pin digitales
#define alarma 2                             // Alarmas del RTC DS1337
#define viento 3                             // Anemómetro QRD1114
#define tempsuelo 4                          // Temperatura del suelo DS18B20
#define temphumdat 5                         // Temperatura/humedad/Punto de rocío SH15
#define temphumcl 6                          // Temperatura-humedad SH15
#define vida 7                               // Led de vida
#define power 8                              // Alimentación de los sensores
#define temp 9                               // Temperatura al sol DS18B20

// Activación de librerías
DS1337 RTC = DS1337();                       // Configuración librería RTC DS1337
OneWire oneWire(temp);                       // Configuración librería termómetro DS18B20
DallasTemperature sensors(&oneWire);
OneWire oneWire2(tempsuelo);                 // Configuración librería termómetro DS18B20
DallasTemperature sensors2(&oneWire2);
DeviceAddress tempDeviceAddress;             // Define la dirección de cada sensor de temperatura
Sensirion SH15 = Sensirion(temphumdat, temphumcl);          

// Definición de constantes
const float pi = 3.14159265;                 // Numero PI
const float volt = 0.0108480556;             // Resolución voltaje de entrada
const int periodo2 = 10000;                  // Periodo de medida del anemómetro (ms)
const int radio = 65;                        // Radio de anemómetro (mm)
const int temp_precision = 12;               // Resolución de los sensores de temperarura (bits)
const int sensibilidad = 30;                 // Sensibilidad del disdrometro
const float area=0.001654;                   // Area de medida del sensor disdrómetro (m^2)

// Definición de variables
long contador = 1;                           // Contador de datos almacenados
unsigned int year = 0000;                    // Año
int month = 00;                              // Mes
int day = 00;                                // Día
int hora = 00;                               // Hora
int minuto = 00;                             // Minuto
int segundo = 00;                            // Segundos
float batt = 0;                              // Voltage de entrada
float innerVcc;                              // Voltaje interno
float innertemp;                             // Temperarura interna
float ambtemp = 0;                           // Temperatura ambiental SH15 (ºC)
float humedad = 0;                           // Humedad ambiental SH15 (%)
float TRocio = 0;                            // Punto de rocio (ºC)
unsigned long BWCounter = 0;                 // Pulsos Blanco/Negro del anemómetro
float velviento = 0;                         // Velocidad del viento (m/s)
long lux = 0;                                // Luminosidad (LUX)
float tempext = 0;                           // Temperatura (ºC)
float suelohum = 0;                          // Humedad del suelo (%)
float TSAr = 0;                              // Temperatura del suelo arriba (ºC)
float TSAb = 0;                              // Temperatura del suelo abajo (ºC)
unsigned long intensidad = 0;                // Intensidad de lluvia (gotas/horas/m2)


void setup(){
  // Inicializacion RTC
  RTC.start();
  // Configuración de la alarma
  RTC.enable_interrupt();
  RTC.setSeconds(55);
  RTC.setMinutes(59);
  RTC.setAlarmRepeat(EVERY_HOUR);
  RTC.writeAlarm();
  pinMode(alarma, INPUT);                   // Receptor de alarmas
  digitalWrite(alarma, HIGH);
  // Configuración de pins
  pinMode(power, OUTPUT);                    // Alimentacion de sensores
  pinMode(vida, OUTPUT);                     // Led de vida
  // Inicializacion del puerto serie
  Serial.begin(9600);                        // Inicia comunicaciones
  // Inicialización de sensores
  sensors.begin();                           // Inicia el sensor de temperatura DS18B20
  sensors2.begin();
  // Mostrar cabecera por puerto serie (*)
  SplashScreen();
}

void loop(){
  digitalWrite(power, HIGH);
  delay(5000);
  digitalWrite(vida, HIGH);                // Enciende el led mientras realiza las lecturas
  tiempo();                                // Toma la hora
  delay(20);
  readVcc();                               // Lee el voltaje interior
  delay(20);
  midebateria();                           // Mide el voltaje de entrada
  delay(20);
  readTemp();                              // Mide la temperatura interna
  delay(20);
  midegotas();                             // Mide la intensidad de lluvia (disdrómetro)
  delay(20);
  temperatura();                           // Mide la temperatura exterior (DS18B20)
  delay(20);
  sueloH();                                // Mide la humedad del suelo
  delay(20);
  suelotemp();                             // Mide la temperatura del suelo
  delay (20);
  temphumroc();                            // Lee temperatura y humedad (SH15) y calcula el punto de rocío
  delay (20);
  luminosidad();                           // Mide la luminosidad (LDR)
  delay  (20);
  velocidadviento();                       // Mide la velocidad del viento (QRD1114)
  mostrar();                             // Muestra los datos a través del puerto serial
  grabar();                              // Graba los datos en formato ascii en un soporte microSD
  delay(5000); 
  contador = contador + 1;                 // Actualiza el contador de medidas
  digitalWrite(vida, LOW);                 // Apaga el led al acabar el proceso
  digitalWrite(power, LOW);
  //attachInterrupt(0, Despertar, FALLING);
  delay(500);
  Dormir();
}


void Despertar(){
}

void Dormir(){
  attachInterrupt(0, Despertar, FALLING);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  RTC.enable_interrupt();
  sleep_mode();
  // -->FASE DE BAJO CONSUMO DEL DISPOSITIVO<--
  sleep_disable();
  RTC.disable_interrupt();
  detachInterrupt(0);
}

// Lee el Reloj de Tiempo Real (DS1337)
void tiempo(){
  // Lee el RTC
  RTC.readTime();
  // Memoriza la fecha actual
  day = RTC.getDays();
  month = RTC.getMonths();
  year = RTC.getYears();
  //Memoriza la hora actual
  hora = RTC.getHours();
  minuto = RTC.getMinutes();
  segundo = RTC.getSeconds();
  return;
} 

// Lee el voltaje de entrada
float midebateria(){
  batt = (analogRead(bateria))*volt;
  return batt;
}

Code follows with other functions to measure the different sensors. I think that they are not essential here...

[Sorry, comments are in Spanish]

So,any idea about what could be the idea and how could i solve it by software or hardware?

Thanks!!