Go Down

Topic: SdFat closing weird, (Read 2909 times) previous topic - next topic

Tduck999

Hey

So I have a problem that I really dont understand why I even have it, none the less I would like to understand it.

The code of the SdFat Write Read example is what I'm using right now to get my idea going.

The idea is simple log data onto an SD card and sleep between logs I'm powering it down with a MOSFET to save power completely.

But for some reason I run the code and this works but only if I open and read the file straight after closing the file that I have just written to like this ,,,,

Code: [Select]
const int chipSelect = 4;
/*
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4   
*/
#include <SdFat.h>
SdFat sd;
SdFile myFile;

char fileName[] = "2468.txt";
int sdPower = 3;
void setup()

  pinMode(sdPower,OUTPUT);
}

void loop()

  digitalWrite(sdPower,HIGH);
  sd.begin(chipSelect, SPI_HALF_SPEED);
  myFile.open(fileName, O_RDWR | O_CREAT | O_AT_END);

  myFile.println("Hello World");


  myFile.close();
    // open and close again ,,, not sure why but it works this way.
  myFile.open(fileName, O_READ);
  myFile.read();
  myFile.close();     // close the file:

  digitalWrite(sdPower,LOW);
delay(1000); 
}


This works but when I remove the last open / read and close bit the file is created but not written too ?

like this

Code: [Select]
const int chipSelect = 4;
/*
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4   
*/
#include <SdFat.h>
SdFat sd;
SdFile myFile;

char fileName[] = "2468.txt";
int sdPower = 3;
void setup()

  pinMode(sdPower,OUTPUT);
}

void loop()

  digitalWrite(sdPower,HIGH);
  sd.begin(chipSelect, SPI_HALF_SPEED);
  myFile.open(fileName, O_RDWR | O_CREAT | O_AT_END);

  myFile.println("Hello World");

  myFile.close();

  digitalWrite(sdPower,LOW);
delay(1000); 
}


This does not write to the file that is created.

I have no idea why this is happening.

I have stripped down the SdFat code to the min that works to make this as basic as possible.

Any ideas on how to fix this and reasons for this happening would be great help for my understanding.

fat16lib

#1
Oct 03, 2014, 09:15 pm Last Edit: Oct 03, 2014, 09:34 pm by fat16lib Reason: 1
You can't just power down an SD.  The SD has RAM buffers and may not have programmed the flash when you power down.  Flash pages in modern SD cards are a multiple of 16 KB so the card tries to optimize programming flash.

Closing, reopening and reading the file causes the SD card to write the RAM buffer to flash.  The SD will also write the buffer after no activity for some time and then sleep.  The amount of RAM buffer and the sleep delay depends on the card.

Why are you using the MOSFET?  A good SD card sleeps at about 70-100 micro-amps http://forum.arduino.cc/index.php?topic=269004.msg1901095#msg1901095.

Powering up the card and initializing it typically takes 50-100 ms and may draw 30-50 ma.  This is equivalent to about a minute of sleep.  

Opening the file will also take time and high current as will closing the file and forcing the write to the card and updating the directory.

The MOSFET may be worth implementing if you are logging for months and the time between data points is more than a few minutes.

Edit: The SD card may go busy for 100-200 ms while powering up.  You need to check the time from turning on the MOSFET until sd.begin() returns, it could be longer than the typical init time for a card that is already powered.

Tduck999

I am logging data for about a month with a gaps of about 5-15 minutes ( user settable ) - I see how this would come into play though its good to know.

So to make sure that the SD card is powering up correctly I should put maybe a 500ms delay after I set the sdPower pin high to account for start up time?
Yet the device works now without that delay, so I'm not seeing how that would come into play ? unless its for different SD cards that I will be using in the Logger take different times to start up ,, is that it ?
-I'll give it a go now.

I have also tried the sync() function before closing the file and it does not seem to help in writing the Ram in the buffers as you say ,,,, also good to know thanks.

Its there another function to force this to happen ?  Or should I stick with the current method ?

fat16lib

#3
Oct 04, 2014, 03:54 pm Last Edit: Oct 04, 2014, 03:58 pm by fat16lib Reason: 1
The problem is not with the program in the Arduino.  The controller in the SD card has RAM buffers and a proprietary algorithm for when to write these buffers to the flash chips in the SD card.  Most likely closing the file after the write and delaying a second will save your data correctly.

You can try enabling a check for completion of flash programming.  Edit Sd2Card.cpp at about line 556 and set this symbol nonzero.
Code: [Select]
#define CHECK_PROGRAMMING 0
I disable this by default since modern cards never fail.  Modern SD cards just remap bad flash areas automatically.  The card should finish programming if you enable this feature.

Your MOSFET is a waste of time and introduces risk in a logger that runs for only a month.  You will save under 72 (30*24*0.1 ) mAh of power.  An AA battery is about 2000 mAh http://rightbattery.com/123-1-5v-aa-duracell-copper-top-vs-duracell-procell-alkaline-batteries/.

fat16lib

#4
Oct 04, 2014, 08:08 pm Last Edit: Oct 04, 2014, 08:11 pm by fat16lib Reason: 1
Here is a low power test system I put together.  It draws 92 micro-amps from the batteries when idle http://forum.arduino.cc/index.php?topic=269004.msg1907901#msg1907901.

The 92 micro-amps is current into the regulator and is powering the SD and the pro mini in sleep mode.  There is no need to init the SD when the pro mini wakes to log data.

Tduck999

Maybe its just my setup or the reader or Card I'm using but when I cut the power and sleep my micro ( 1284P ) the current draw is 0.7mA and when the SD card is powered from the 5V rail instead the current is 4.7mA its just something I will have to look into. I am getting a different SD card reader shortly so I will be able to test it again.

Also my Multi Meter is not the best right now so getting a better one shortly to test the current consumption again with other devices in my circuit ( RTC and Such )

Thanks for the help

Go Up