SD Card - how to reduce the power consumption?

So here's my problem, I've built a karting lap timer that uses an IR beam to trigger the lap time each time the kart passes the pits. I have a Micro SD card which I'm writing the lap times to - this works very well however the SD card is pulling around 12mA even after writing the times and after I've closed the file - myFile.close(); I need to get the timer to run for at least 24 hours including running a screen so mA's are crucial. Without the SD card attached the device only uses about 13mA, with it attached its running at 17mA and when begun - sd.begin() - it jumps to 25mA. This is too much for the batteries (4 x AAA, can't use AA's as the space isn't enough). Different cards behave differently as one of my cards jumps to over 40mA when SD.begin()

Also if I remove the card it jumps back to 13mA but on re inserting the card the whole system restarts, not sure why?

Is there a way to switch off the SD card when not required etc either with software (preferred) or with a hardware method?
I've seen that turning off the SCK pin can put SD cards to sleep, is there any way to do this?
I've also seen an N-MOSFET being used on the gnd line to swith the SD card off, anyone got any experience of this?

Or is my code wrong? here's a sample

myfile = SD.open("times.csv", FILE_WRITE);// Open SD Card File
if (myfile) {// if the file opens ok
myfile.print("Lap,");//Start line with Lap
myfile.print(lapcount);//add the lap count to the file
myfile.print(",");//add a comma for use in excel later
myfile.println(laptime);//save laptime and start new line
myfile.close();// close and save the file
}

Thanks

An Sdcard may take up to 200mA peak, based on specification (it depends what the card actually does).
You may use p-channel mosfet (high-side switch) to switch the card off/on..

Thanks Pito,
I'm aware that the SD Cards pull upto 200ma during reading and writing and thats ok. The problem I have is that the datatsheet for the SD Card shows a sleep mode which pulls around 250uA.

I need to find a way to put the SD Card to sleep between write events to make use of this small current draw.

Could you describe the details of your hardware.

Most SD cards automatically go to a low power mode when no SPI clock is applied. I tested two card with a Teensy 3.0.

I used a Teensy 3.0 since I could connect it directly to 3.3V and the Teensy pins. There are no resistors, level converters, or voltage regulators.

An old full size SanDisk card sleeps at 0.18 ma.

A unique feature of cards in the SanDisk SD Card Product Family is automatic entrance and exit from sleep mode. Upon completion of an operation, cards enter sleep mode to conserve power if no further commands are received in less than 5 milliseconds (ms). The host does not have to take any action for this to occur. However, in order to achieve the lowest sleep current, the host needs to shut down its clock to the card. In most systems, cards are in sleep mode except when accessed by the host, thus conserving power.
When the host is ready to access a card in sleep mode, any command issued to it will cause it to exit sleep, and respond.

A new Amazon microSD sleeps at 0.13 ma.

I just used the SdFat QuickStart and SdInfo examples.

So, I'm using a stripbaord arduino running at 3.3v (no need for level shifting) with a 16x2 LCD screen and a Sparkfun Micro Sd Card module (Link Below). There also an IR receiver TSOP31238 to receivethe signal from the pit wall. The SD Module is hooked up to pins 10 through 13 with 10 being used for the CS pin. Reading and writing to the sd card isn't a problem it just its standby current.

http://proto-pic.co.uk/breakout-board-for-microsd-transflash/

I'm testing with 2 different SD cards one is sandisk 1gb and the other is sandisk 128mb (quite old), both give different results, the 1gb increases the running current from 13mA to around 25mA (this is will last 24 hours ok) the other runs at 40mA (this is not ok and I need a system that isn't dependant on which type of card I use).

I've seen the quote before about the sandisk automatically sleeping when the clk signal isn't received for 5ms or more but i'm not sure if the arduino ever stops the clk signal? and if this is relevant in SPI mode?

I've also found out that some current is always leaking through the clk and data pins once the SD.Begin() is activated so this maybe a problem with the SD libraries on the Arduino as you can't 'Stop' an SD Card. Because of this its seem its very difficult to add a MOSFET to switch either Vcc or Gnd off when the cards not required ( the sandisk datasheet also states that power must come on to Vcc before power is received on the clk or data signals as this could corrupt the card and without being able to 'stop' the sd card this would happen)

Most SD cards won't sleep unless they have been initialized.

I am the author of SdFat which is also the core software for the standard Arduino SD.h linrary.

I've seen the quote before about the sandisk automatically sleeping when the clk signal isn't received for 5ms or more but i'm not sure if the arduino ever stops the clk signal? and if this is relevant in SPI mode?

The only time SPI clock is active with these libraries is during an actual data transfer. In your case it will be rare for SPI clock to be active.

I did another test with a 5 V Uno and and this Adafruit module MicroSD card breakout board+ : ID 254 : $7.50 : Adafruit Industries, Unique & fun DIY electronics and kits

I measured the current from 5 V on the Uno to the Adafruit module after the SD was initialized by the SdFat QuickStart example. I used a Transcend 4 GB class 6 MicroSDHC card.

The current was only 0.21 ma even though this module has level shifters and a voltage regulator. The module activity LED on SCK is not lit when the card is not active.

You don't want to power the card off and on. You then need to reinitialize the card and SD.h wrapper for SdFat has a bug that prevents multiple calls to begin().

Could you download SdFat Google Code Archive - Long-term storage for Google Code Project Hosting. and run the QuickStart example. Measure the SD current after QuickStart prints its success message.

You must have the meter connected during the entire test since the card may draw high current until it is initialized and disconnecting the card will cause it require initialization.

You could use an EEPROM for storage instead of an SD card. I2C (or SPI) chips with 1Mbit in an 8-pin DIP would probably be good enough for what you're doing.

Pete

You should be able to use a modern vanilla microSD with your setup and it should almost always sleep at 100 - 200 micro-amps. No need for MOSFET or EEPROM.

I have now tested about 10 cards in various modules and all draw very little current when idle. Are any of your other devices on the SPI bus? If you access them, the SD might draw more current since it will see SCK active.

It is possible to run SdFat in SPI bit-bang mode on other pins if other SPI activity is causing the problem. You simply edit the config file to select software SPI and specify the pins to use.

So I couldn't use the Quickstart example you suggested due to me using a strip board built arduino running at 3.3v. It has no PC serial connection. I've been using my Uno to load the sketches and then transferring the chip to the strip board. I know this isn't the best idea but I won't to run this device on a karts steering wheel and didn't want to waist my Uno.

I've taken some photo's of my setup to give you an idea.

I'm going to try a different sketch to see if its my programming that's at fault.

And no there are no other SPI devices hooked up.

I thought about using an EEPROM for storage but I wanted this for 24 hour kart races and we can get over a thousand laps recorded during this time so recording them as a .CSV file for easy transfer to excel seemed a better choice.

Try to run SdInfo sketch from SdFat examples. Comment out line 150:

while (Serial.read() <= 0) {}

and put the chip into your board, switch on, wait few seconds and observe the current..

I understand the problem. You are using SD.h and it has a bug that doesn't allow the SD to sleep.

SD.h has not added bug fixes from SdFat for about three years and the Adruino developers have added their own bugs. I tried SD.h with my tests and found cards pulled from 15 to 28 ma when idle.

These same cards pull less than 200 micro-amps with the new SdFat and some as low as 120 micro-amps.

My advice is to convert to my current version of SdFat.

Great, I'll do just that.

Could you post a simple how to guide and i'll give it a try later?

Look at the html for documentation of the classes. Also look at the SdFat examples.

I suggest you use sync() as opposed to opening and closing your log file. sync() does all the operations of close() but leaves the file open and positioned for the next write. You can power off the logger and all data will be saved, provided you are not in the middle of a write to the file.

Here is a simple example of a logger that writes a line number and the time in millis() to a file every second.

#include <SdFat.h>

// Replace SS with the chip slect pin for your SD.
const uint8_t sdChipSelect = SS;

// SD file system.
SdFat sd;

// Log file.
SdFile file;

void setup() {
Serial.begin(9600);
// Initialize the SD and create or open the data file for append.
if (!sd.begin(sdChipSelect)
|| !file.open("DATA.CSV", O_CREAT | O_WRITE | O_APPEND)) {
// Replace this with somthing for your app.
Serial.println(F("SD problem"));
while(1);
}
}

uint32_t n = 0;
uint32_t t = 0;

void loop() {
// delay one second between points
t += 1000;
while (millis() < t);

// Write your data here
file.print(n++);
file.print(',');
file.println(t);

// Use sync instead of close.
file.sync();
}

This is the file produced by the above logger:

0,1000
1,2000
2,3000
3,4000
4,5000
5,6000
6,7000
7,8000
8,9000
9,10000
10,11000
11,12000

Thanks for the work you're putting in on this subject. I'll hopefully give it a try this evening an report back on the results.
I've had a quick look at some of the examples in the SDfat Library and I think I should be able to port over from the standard SD.h library ok, I just need to learn some of the new commands etc (I'll pick them up hopefully from the examples).

I may have forgot to mention but during the setup loop I also read a file on the SD card (2 numeric digits) which the program uses to set the expected lap time in seconds (as its used on different tracks etc), this is to avoid getting a false IR reading too early in the lap. I guess this means that I still need to use the close() call for this file before opening the data file to avoid having 2 files open etc. After this I could then use the sync() call?

There is no limit on how many file you can have open. The only limit is RAM, each SdFile instance requires 31 bytes.

You must close an instance of SdFile before using it to open another file.

  SdFile file;

  file.open("config.csv", O_READ);
  // read data from config.csv
  file.close();
  file.open("log.csv", O_WRITE| O_CREAT | O_APPEND);
  // write to log.csv

Bingo!!!

I ported over my sketch last night to the SdFat library and hey presto the sd is now sleeping like a baby between read / write events. The current consumtion on the SD card has fallen into the circa 200uA region regardless of which card i use. That means the overall system is now running at only 13mA which is mainly the LCD screen. this will give me around 70 hours of run time from 4 AAA batteries - easily enough for the 24 hour race with practice and qualifying covered as well. :slight_smile:

It took me a few attemts to convert the code over but its all working fine and the examples in the SdFst library were a big help

Thanks for your help with this problem and keep up the good work - I'll only be using this library from now on for future SD projects

I added a simple change to the SD library to help with this issue. I have not tested it fully yet but it may be of interest to know that the SD library has a begin() but no matching end(). I implemented:

void SDClass::end() {
if (root.isOpen())
{
root.close();
}
}

This allows you to close the SD library. Also I am using an N-Channel FET in the ground of the SD card (BS170 Drain connected to SD card gnd, BS170 Gate connected to 10K to ground and Arduino digital IO pin, BS170 Source connected to ground). When I wish to switch off the SD card I tristate all the SD card connections and then I tristate the FET Gate pin. The 10K resistor forces the Gate to 0v and all the pins on the SD card float to Vcc. Next step is to switch off the SPI module in the processor and take the power consumption down further.
Switching back on is easy but this time to switch on the power to the SD card put the FET Gate pin to HIGH. This forces the FET full on and with its low Drain - Source resistance puts power back on to the SD card. It all seems to work but I have not measured the off current and I still have to put the processor to sleep.

Your SDClass::end() may not always work. You must make sure all files are closed before calling your end().

Your end() doesn't do the equivalent of an unmount for a file system. I never added that to the underlying SdFat. It really isn't possible since SdFat does not maintain a list of open files. SdFat was written with RAM use as a top priority.

SD.h has a feature or bug that doesn't allow begin() to be called without closing root so this version of end() fixes that. The underlying SdFat allows begin() to be called multiple times but once again you must close all open files before calling begin().

I would be interested in how much energy you can save with your power saving circuit. SD.h has the bug that doesn't allow SD cards to sleep but SdFat allows cards to sleep.

Modern SD cards sleep at 100 - 200 micro-amps. Many SD card take 500 ms to initialize and draw a lot of current during initialization. A card may draw 50 - 100 ma during this time.

My guess is that several minutes of power off would be required before there was any advantage.

I will be interested in how you determine this and what the result is.

Also I am using an N-Channel FET in the ground of the SD card

It may work fine, but usually such modules are always switched on/off by a high-side switch - ie a P-channel Fet in the VCC rail. Also mind the max drain current (up to 200mA for an SDcard). Switching complex modules low-side in the GND is quite rare.. (with the BS170 low-side you offset signal's log levels by +0.24V when Isd=200mA, probably not a big issue here but not a good design practice, though.. ;))

I was thinking about switching the SD card with a FET (I even bought a BS170 for the job) but I would need to write data to the card every 40 - 80 seconds (dependant on the race track lap length) so I would loose too much power re initialising the card. After porting my sketch over to the SdFat library the SD card is nicely sleeping between write events at around 200uA. This is easily enough power saving for my project.

However, I am interested in how you get on with this and how much current is being used when off and for the initialising.