Giter Club home page Giter Club logo

sd's People

Contributors

aentinger avatar aethaniel avatar agdl avatar bjelojac avatar canchebagur avatar cmaglie avatar damellis avatar dependabot[bot] avatar facchinm avatar fede85 avatar feilipu avatar giszo avatar inv3nt0r1 avatar ivan-perez avatar jasonsheng avatar jcwren avatar jhansson-ard avatar karlsoderby avatar mutoo avatar paulstoffregen avatar per1234 avatar phoenixxl avatar pitel avatar sandeepmistry avatar shfitz avatar squelched avatar tigoe avatar vladkampov avatar zbysekz avatar zeveland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sd's Issues

File access properties

I was looking for a way to access the last access, creation and read time for a file.
It would be useful to do a few things:

  • Expose the SdFile reference in the File object to access the more low-level features available in SdFile
  • Provide a feature to inquire time properties of the dir_t structure in a directory. This would allows a stat() like capability.

Typo in message printed by Serial.print() when SD card fails to initialize

There is a typo in a message printed by Serial.print() when the SD card fails to initialize that can misguide new users.

Thanks @per1234, for giving accurate information.

#79 (comment)

the sketch is restarted whenever the serial monitor is opened

This is only true for the Arduino boards that use an external USB to serial adapter chip that uses the DTR trick you mentioned. It is not true when using a native USB board (e.g., Leonardo, MKR, Nano 33 IoT, Nano 33 BLE). The serial connection with Serial Monitor is also lost when those boards are reset, so you do need to both a reset and a Serial Monitor restart to get the example sketches to start again and show serial output.

At the time those instructions were written, it's likely all Arduino boards had the reset on Serial Monitor open behavior, so they were correct at that time. Most of Arduino's new boards now have native USB, so the existing instructions become even more outdated over time.

Credits: @per1234

Serial.println("Note: press reset or reopen this serial monitor after fixing your issue!");

if (!SD.begin(4)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("1. is a card inserted?");
    Serial.println("2. is your wiring correct?");
    Serial.println("3. did you change the chipSelect pin to match your shield or module?");
    Serial.println("Note: press reset or reopen this serial monitor after fixing your issue!");
    while (1);
  }

It should be Press reset button and reopen serial monitor after fixing your issue.

Also, this message can be added to other examples as well.

Thank you.

SD card example fail

From @maxcpr on August 18, 2015 18:2

a little bit changed example from IDE (SD listfiles), file listing moved to "loop".
Code stops listing microSD card after 17-20 loops (arduino nano).
(there is similar code, also listing files on microsd, that works fine on the same hardware)

/*
  Listfiles

 This example shows how print out the files in a 
 directory on a SD card 

 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 modified 2 Feb 2014
 by Scott Fitzgerald

 This example code is in the public domain.

 */
#include <SPI.h>
#include <SD.h>

File root;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.print("Initializing SD card...");
  digitalWrite(10, 1);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(4, 0);   // turn the LED on (HIGH is the voltage level)
  delay(2000); 
  while (!SD.begin(4)) {
    Serial.println("initialization failed!");
    delay(2000); 
//    return;
  }
  Serial.println("initialization done.");
}

void loop(){
  Serial.println("starting!");
  root = SD.open("/");
  printDirectory(root, 0);
  Serial.println("done!");
  delay(2000);
  pinMode(10, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(10, 1);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(4, 0);   // turn the LED on (HIGH is the voltage level)


}

void printDirectory(File dir, int numTabs) {
   while(true) {

     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

Copied from original issue: arduino/Arduino#3696

Rename files

There seems to be no direct way to rename a file using the File object in SD.h. Copying a file is the only other costly hack to do this. This is not desirable.

sd library conflict with digitalRead

When I add digitalButtons(), Uno works incorrectly.

void readPushButtons(){

  uiStep();

  analogButtons();

  logicAnalogButtons();

  digitalButtons();

  //logicDigitalButtons();

  spindleSpeedSetting();

}
void initialButtons(){

  pinMode(stepPin, INPUT_PULLUP);   ///set the pin with internal pullup resistor

  pinMode(feedPin, INPUT_PULLUP);   ///set the pin with internal pullup resistor

}

void digitalButtons(){

  stepState = digitalRead(stepPin);   ///record pin state

  feedState = digitalRead(feedPin);   ///record pin state

}

3
When I delete digitalButtons(), correctly.

void readPushButtons(){

  uiStep();

  analogButtons();

  logicAnalogButtons();

  //digitalButtons();

  //logicDigitalButtons();

  spindleSpeedSetting();

}

1

SD card initialization fails after SD power down/new init sequence [imported]

From @cmaglie on November 15, 2012 19:5

This is Issue 1103 moved from a Google Code project.
Added by 2012-11-07T18:50:46.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

What steps will reproduce the problem?

  1. Init SD card
  2. Turn SD card off (by cutting power to SD card, but also to all other SD input pins)
  3. Turn SD card on
  4. Initialize SD card again

What is the expected output? What do you see instead?

The expected output would be to have the SD card re-initialize itself. Instead, the second initialization fails.

I have tracked the failure cause to SDFile.openRoot method that return failure if the root had been already opened.

What version of the Arduino software are you using? On what operating
system? Which Arduino board are you using?

Arduino IDE 1.0.1
Mac OS X
Custom board

Please provide any additional information below.

A fix can be implemented, for example by calling a method that resets the state of the SDClass object in the initialization routine, making sure we start from a blank state.

I am willing to implement the fix, but just want to make sure I implement it the way people would like it.

Copied from original issue: arduino/Arduino#1103

SD wrapper: SD.exists() buggy and SD.stop() missing [imported]

From @cmaglie on November 15, 2012 18:34

This is Issue 465 moved from a Google Code project.
Added by 2011-01-21T14:26:04.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

I am using the new SD wrapper library and find it very simple and useful.
But the following issues make it unusable in some case:

Let's assume someone needs to remove the SD card from the socket (or disables the power to it when system can go idle) and put the same or another card back to the socket while the system is running, the following problems occur:

  1. it seems that the SD object holds a copy of the FAT because
    SD.exists(someFile) returns true even if there is no SDCard in the socket or
    another one (where this file does NOT exist) is put in. I guess this copy of the FAT won't be refreshed again after SD.begin().

  2. you can not re-initialize the SD-object again. This would be
    necessary (for some SPI magic I guess) if you remove the SDCard from the socket and put it back later. There is no SD.close() or something and calling SD.begin() a second time will always return FALSE and not initialize the SD again.

Issue 1 and 2 could be solved by adding a destructor or a function to
re-initialize the SD object.

Copied from original issue: arduino/Arduino#465

Taking much global variable

Hello,

Any example in library is taking almost 50% global variable memory.
As I am using many other library, I want to reduce the global variable memory of sd library.
I am using few function like, file open, file write, file read and file close so other functions are useless for me.
How can reduce the global variable memory by removing the other global variables???

File lacks a copy constructor

Context: I am trying to hunt a bug, similar to #11 - working with older Arduino IDE, I know ;) but going deseperately through SD library's code I found cause for many subtle bugs.

Consider code like this:

void doSomething(File f) {
   // does something nice.
   f.close();
}

void func() {
   File myFile = ....; // obtain a file somehow
   doSomething(myFile);
   myFile.close();
}

On "normal" File, close() is idempotent (as expected), so doing close() multiple times is OK and 2nd+ calls do nothing. There seems to be no copy constructor in File, so when passing by-value to doSomething, the compiler generates (!) one that copies the fields - that is the _file pointer becomes shared between myFile and f locals.

First close will deallocate the (shared) _file pointer and zeroes the pts. The 2nd close will deallocate the same pointer value again.

This reduced example may seem bad, as the programmer should not do permature close - but lack of the copy/destroy semantics severely limits structuring the code since passing File values around easily leads to memory corruption. At this time, the only value safe to assign to other variables is File().

I would also recommmend to reconsider the decision for #2; while it is true, that the current implementation is simple, it requires extreme caution when passing around File variables. I'd recommend to have full copy+move constructor semantics.

If unwanted, I'd recommend to disallow generation by the compiler, so the user is warned:
File(const File&) = delete;

architectures in library.properties inaccurate

library.properties states architectures=* which makes my Arduino IDE choose it over the SD lib included in the esp8266 board package.
This would not be a problem, if Sd2PinMap.h did not contain
#error Architecture or board not supported.
which breaks my build. So I guess the architectures declaration should be more specific.

SeekableStream

From @stg on March 25, 2013 14:35

I would like to see a SeekableStream class going between the File class (SD library) and the Stream class (or by adding the seek, position, size functions to the Stream object directly).

This would allow access to arbitrary (SD or other media) seekable streams without the user including the (large) SD library for projects that do not have an SD card reader, while still maintaining full compatibility with the SD card library.

For example, the HypotheticMusicPlayer class could play music from the SD card in a larger project, or from flash-rom in a smaller project via a class that subclasses SeekableStream and accesses PROGMEM data - without needing to include the SD library, which may not even fit on a smaller device.

This would also make it easier to provide standardised file access to other media, where including the SD card library makes no sense.

Copied from original issue: arduino/Arduino#1330

SD card doesn't go sleep between transfers

My SD card (4G by Transcend) consumes ~20 mA in idle state between transfers. Author of SdFat library wrote some years ago about this:
'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.'
(http://forum.arduino.cc/index.php?topic=149504.msg1124464#msg1124464)

After conversion my code from SD to latest SdFat library power consumption in idle state became normal.

Initialization failure on Mega [imported]

From @cmaglie on November 15, 2012 18:50

This is Issue 796 moved from a Google Code project.
Added by 2012-01-17T22:33:27.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

What steps will reproduce the problem?

  1. load demo code for the W5100 that uses the SDcard (Blinkled from simplewebserver)
  2. Power OFF/ remove USB connector from Mega board
  3. Re-apply power

What is the expected output? What do you see instead?
The demo should work from cold start, but the SDcode hangs internally after supplying one file.
However If a warm start (press reset button on mega) is issued then there is no problem.

There is also no problem if you 'upload' a file to the SDcard before downloading a file, then it functions correctly after a cold start.

What version of the Arduino software are you using? On what operating
system? Which Arduino board are you using?
1.0IDE OSX mega V2

Please provide any additional information below.

The SD and ethernet libraries need to be cleaner, leaving the SPI state 'clean' after exiting and not assuming they are the sole owners, the SDcode should also NOT be disabling system interrupts whilst it is performing actions.

Copied from original issue: arduino/Arduino#796

FILE_WRITE does not work properly since v1.2.0

Command: File file = SD.open(target, FILE_WRITE);
How it looked like (version 1.1.1):

Reading file "/logs/log3.txt":
[26.11.17][12:59:03][4893] S: GSM: ready without restart
[26.11.17][12:59:08][9526] I: GSM: IP: "100.90.60.208"
[26.11.17][12:59:17][18051] S: RTC: synced
[26.11.17][12:59:17][18077] Boot successful

Done!

How it looks like (version 1.2.0),
it always write to first line:

Reading file "/logs/log0.txt":
[01.01.04][00:47:39][60621] Boot successful
86.142.157"

Done!
Reading file "/logs/log1.txt":
[01.01.04][00:52:55][32144] I: GSM: IP: "100.90.60.208"

Done!
Reading file "/logs/log2.txt":
[26.11.17][12:40:57][18082] Boot successful
0.60.208"

Done!

Why not update official Arduino SD library with newest Geiman's one?

From @q2dg on June 27, 2015 0:4

Some parts of official Arduino SD library (https://github.com/arduino/Arduino/tree/master/libraries/SD/src) are based in an old version of Greiman's one (https://github.com/greiman/SdFat). The newest versions of the latter has some interesting improvements, as support to long file names, use of multiple cards, etc. I think it could be worthy to valorate if these changes could be merged.
Thanks.

Copied from original issue: arduino/Arduino#3428

[Documentation]read(buffer, len)

https://www.arduino.cc/en/Reference/FileRead states that the read method returns a character or -1. That however only applies to ::read(). read(buffer, len) returns the number of bytes read or -1 on error.

From SDFile.cpp

//------------------------------------------------------------------------------
/**
 * Read data from a file starting at the current position.
 *
 * \param[out] buf Pointer to the location that will receive the data.
 *
 * \param[in] nbyte Maximum number of bytes to read.
 *
 * \return For success read() returns the number of bytes read.
 * A value less than \a nbyte, including zero, will be returned
 * if end of file is reached.
 * If an error occurs, read() returns -1.  Possible errors include
 * read() called before a file has been opened, corrupt file system
 * or an I/O error occurred.
 */
int16_t SdFile::read(void* buf, uint16_t nbyte) {
  uint8_t* dst = reinterpret_cast<uint8_t*>(buf);

SD Library not working with FAT16

From @matthijskooijman on November 14, 2014 10:49

Initializing the volume and running the CardInfo example works fine, but reading files does not work. Instead of the actual file contents, I get some random garble (mostly spaces) of the correct length. I tried this using the DumpFile example.

I suspect that the block lookup for FAT16 might be wrong. Looking at this piece of code, I can't imagine that being correct.

Copied from original issue: arduino/Arduino#2443

Serial is pulled when using SDCard

While developing a sketch, I was really low on memory and started investigating on which element were taking space. I noticed Serial was being pulled in the final elf even without using it at all.
It appear the SDFile.cpp file contains functions which are embedding Serial.println calls.
Is it possible to add a define which will exclude all print* function and hence reduce memory consumption ?
Thanks

allow multiple deices on SPI bus

PROBLEM:
with 2 devices on the SPI bus, the SD card library fails when calling the begin() function
the problem is that the library is not prepared to work with other SPI devices, it assumes you only have the SD card basically

SOLUTION:
in the file named SD.cpp, in function begin() (line 345) add this instruction before the return statement:

if(root.isOpen()) root.close();

that should do it.

Sdio 4 bit mode support

Hello

Any plan to do it for any Arduino board ?
It is very usefull for any data recorder...
Br
Jp

Incorrect use of millis() for timeout function

In Sd2Card.cpp there are a few places where a timeout function is implemented. However, in each of these places the value returend by millis() is truncated to 16 bits. That can't be correct.

GPL or LGPL?

SD library seems to have been changed to GPL when it was pointed out that William Greiman's SdFat library was GPL in Apr 2015. arduino/Arduino#2936

In the meantime, in Oct 2017, William Greiman's library was changed to MIT License. greiman/SdFat@e4190e5 and greiman/SdFat@f2424ef

As far as I know, for "the stated INTENT of the arduino folk to allow proprietary software trumps", this library is supposed to be LGPL, since it is not mandatory to keep it GPL anymore. https://forum.arduino.cc/index.php?topic=199627.0 (Sorry for not having clearer source. Correct me if I'm wrong.)

SdFat library [imported]

From @cmaglie on November 15, 2012 18:54

This is Issue 885 moved from a Google Code project.
Added by 2012-04-13T15:30:18.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

What steps will reproduce the problem?

  1. Arduino sketches that depend on the sdfat library fail to compile on Arduino-1.0.1-rc2
  2. I received the following error:
    core.a(new.cpp.o): In function `__cxa_pure_virtual':
    /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.cpp:17: multiple definition of`__cxa_pure_virtual'
    SdFat/SdFat.cpp.o:/Users/usename/Documents/Arduino/libraries/SdFat/SdFat.cpp:62: first defined here
    /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
    

What version of the product are you using?

sdfatlib20111205 and SdFatBeta20120327

On what operating system?

Mac OS X

Copied from original issue: arduino/Arduino#885

Maixduino board not working with the SD library

I'm stumped regarding why my new Maixduino board won't initialize the SD card with the command "SD.begin(29)". It has this problem for any of the SD(k210) library examples that use this command. I've tried SD cards ranging from 2GB to 32GB and they all fail. I've tried both the SD formatting utility in Windows and the SD Card Formatter program recommended in the forums. I've tried formatting in both FAT 32 and FAT 16. Nothing works.

However, it does initialize fine with the example "Cardinfo" and running this sketch shows all the correct info about the SD card. I see that this sketch does not use SD.begin(), but uses more basic commands from the utility libraries such as "card.init(SPI_HALF_SPEED, chipSelect" where chipSelect = 29 (for the Maixduino board).

Does anyone have any idea or theory why this board fails to initialize the SD card using the SD.begin() command? Thanks!

SD Card Remove File Issue

From @hammadtq on April 9, 2015 10:31

SD.remove works fine in the start but would stop functioning on itself, if I give a new file name, it will work perfectly fine again while leaving the old file as it is, the last file I encountered problem was of the 4086 bytes. The issue is very random, such as it will perfectly fine for a few days and then will give problem with one of the files.

I couldn't reproduce the condition under which it would start doing this, however, I tried to debug and trace the issue, here is what I found in SDVolume.cpp in the method of

uint8_t SdVolume::freeChain(uint32_t cluster)

do {
  uint32_t next;
    if (!fatGet(cluster, &next)) return false;
    // free cluster
    if (!fatPut(cluster, 0)) return false;
    cluster = next;
  } while (!isEOC(cluster));

I noticed that next has a defined value when the first cluster is called such as maybe: 3911516415
However, when it gets through fatGet and fatPut, if we print the next value just before cluster=next, it appears to be 0, making the while to break and false to return on next loop iteration.

What I did to resolve is simple, I just saved the value of next in a new variable 'newnext' before going to fatGet and then assigned that 'newnext' to cluster at the end, this resolved the issue at once and file was deleted.

do {
  uint32_t next;
  uint32_t newnext = next;
    if (!fatGet(cluster, &next)) return false;
    // free cluster
    if (!fatPut(cluster, 0)) return false;
    cluster = newnext;
  } while (!isEOC(cluster));

I hope this will help in finding and fixing the issue correctly.

Copied from original issue: arduino/Arduino#2946

SD Library not useable for MKR1000

Why this library isn't useable for new processors such SAMD21 Cortex-M0+? If I include this library the compiler get an error: The Sd2PinMap.h contains no entrys for this Controller. I did expect, that all new boards, which are add with the board manager, could used with all librarys in the standard IDE, such SD library. Is there any idea how i can use an MKR1000 board with the SD library?

In file included from D:\Arduino\libraries\SD/utility/Sd2Card.h:26:0,

             from D:\Arduino\libraries\SD/utility/SdFat.h:27,

             from D:\Arduino\libraries\SD/SD.h:20,

             from D:\Arduino\Sketches\gpsLogger3\gpsLogger3.ino:6:

D:\Arduino\libraries\SD/utility/Sd2PinMap.h:284:5: error: 'DDRD' was not declared in this scope

openNextFile does not correctly list files in use [imported]

From @cmaglie on November 15, 2012 18:55

This is Issue 904 moved from a Google Code project.
Added by 2012-04-29T23:57:46.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium, Component-Core, Component-SD, Milestone-1.0.2

Original description

What steps will reproduce the problem?
Method A:

  1. Open the root of an SD card
    root = SD.open("/");
  2. List the files with the example code
    printDirectory(root,0);
    2A. All files on card show up.
  3. Open a (different) file variable for writing SD.open("datafile.csv",FILE_WRITE);
  4. List the files with the example code
    printDirectory(root,0);
  5. File opened for writing does not show up from now till reset.

Method B:

  1. Open the root of an SD card
    root = SD.open("/");
  2. Open a (different) file variable for writing SD.open("datafile.csv",FILE_WRITE);
  3. List the files with the example code
    printDirectory(root,0);
  4. File opened for writing does not show up from now till reset.

What version of the Arduino software are you using? On what operating
system? Which Arduino board are you using?
Arduino 1.0
Windows 7 x64 Ultimate
Arduino Uno SMD + Ethernet Shield R3
Kingston 1GB MicroSD Card in Ethernet Shield

Please provide any additional information below.
Sample code and sample output attached.

Copied from original issue: arduino/Arduino#904

SD example CardInfo doesn't handle large SD cards

From @karplus on December 31, 2012 2:39

I tried reading a 32Gbyte card with CardInfo, and got a ludicrous result for the size. The problem is that a 32-bit number can't hold the number of bytes on the card.

Replacing the bytes and kbytes printing with the following code fixed the problem, though only for cards up to a Terabyte:

if (volumesize < (1<<(32-9)))
{ uint32_t num_bytes = volumesize * 512; // SD card blocks are always 512 bytes
Serial.print("Volume size (bytes) : ");
Serial.println(num_bytes);
}
Serial.print("Volume size (Kbytes): ");
volumesize /= 2;
Serial.println(volumesize);

Copied from original issue: arduino/Arduino#1194

SD Card example sketch "CardInfo"

Hi, using the default CardInfo sketch causes the SD card to be corrupted if power to the Arduino stops. I have resolves this issues on my end by adding:

"root.close();"

to the end of the setup(); function to ensure that the sd card is fully closed, and ready to be ejected.

SD card support [imported]

From @cmaglie on November 15, 2012 18:48

This is Issue 740 moved from a Google Code project.
Added by 2011-12-05T23:57:52.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

I had some problems with repeated initialization of SD cards with Arduino 1.0 (so I can remove them from the Arduino to retrieve the information on them). It would just stop writing to the card after a while. (before writing I initialized the SD card, but somehow this wouldn't work every time)

I got it working by using the latest version of SDFATlib, on which the current SD lib is based I think (a much older version).
The current SD lib works by providing a higher level interface for the old version of the SDFATlib.
With newer versions this is not needed anymore because a higher level interface is included in the SDFATlib itself.

Why don't you integrate this newer library, it also comes with good support for multiple SD cards and more features! :)

You can find the latest (Arduino 1.0 compatible) version on http://code.google.com/p/beta-lib/downloads/list

Copied from original issue: arduino/Arduino#740

SD make83Name doesn't allow extended ASCII characters

From @mcaldwelva on November 9, 2015 23:5

This line of code is overly restrictive:

if (i > n || c < 0X21 || c > 0X7E)return false;

Windows will use extended ASCII in short file names if they are present in the long file name. Based on the Wikipedia entry for FAT 8.3 file naming, something like this seems more appropriate:

if (i > n || c < 0x20 || c == 0x7F) return false;

I hope you will consider making a change along these lines in the future. Thanks!

Copied from original issue: arduino/Arduino#4121

SD.exists() has weird side-effects, breaks subsequent SD calls

From @blowback on January 17, 2013 13:20

If I take the listfiles.ino example and change the chip select to 4, I can get a directory listing of the contents of my SD card, as expected.

If I modify the code by adding SD.exists("foo);' immediately before the 'root = SD.open("/");' then printDirectory() no longer works - specifically, the first call to dir.openNextFile() fails.

If I move the SD.exists() line to after the SD.open("/") line, then it works again.

I tried wrapping the SD.exists() with its own SD.open().....root.close(), but that caused the directory listing to fail again.

It doesn't matter if the file tested for actually exists or not, the behaviour is the same in both cases (and SD.exists() returns the right result).

Here's the code:

/*
  SD card basic file example

 This example shows how to create and destroy an SD card file   
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */
#include <SD.h>

void printDirectory(File dir, int numTabs);


File root;

void setup()
{
   delay(5000);
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  pinMode(10, OUTPUT);

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  /* ADDED CODE: this SD.exists() call will cause the dir.openNextFile()
   * call in printDirectory() to fail, regardless of whether the file
   * actually exists or not.
   */
  if(SD.exists("META.DAT"))
  {
      Serial.println("EXISTS");
  }
  else
  {
      Serial.println("DOESN'T EXIST");
  }
  /* END ADDED CODE
   */

  root = SD.open("/");

  /* ADDITIONAL: if we do our SD.exists() check here, after the SD.open("/"),
   * then it all works again.
   * HOWEVER id we wrap our SD.exists() with its own SD.open() and root.close(),
   * it goes back to being broken!
   */

  if(root)
  {
      Serial.println("root opened");
      printDirectory(root, 0);
  }
  else
  {
      Serial.println("failed to open root");
  }

  Serial.println("done!");
}

void loop()
{
  // nothing happens after setup finishes.
}

void printDirectory(File dir, int numTabs) {
   while(true) {

     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       Serial.println("openNextFile failed");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
   }
}

Copied from original issue: arduino/Arduino#1232

(Question) Reading UTF-8 characters on file.

Hello,
I am aware that this is not an issue, but I would like to know if reading a file encoded in UTF-8 would work, and what format I should save the resulting text in.
For example, if I had a text file full of fixed width columns like so:
1/你好 /hello \n
with 24 bytes per line,
how can I read the file so that I can save the Unicode characters, preferably as a char* array?
I apologise if this is seemingly simple, but I could not find any sources for reading UTF-8 from an SD card.
Many thanks

Change SD Card

From @nemeier on August 1, 2015 10:26

In some of my Projects I need to change the SD card. There is a simple allow this. I just require a single line in the SD.c library.

boolean SDClass::begin(uint8_t csPin) {
  /*
    Performs the initialisation required by the sdfatlib library.
    Return true if initialization succeeds, false otherwise.
   */
// ----> Line Added
  if (root.isOpen()) root.close();      // allows repeated calls
// <--- Line Added
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

After changing the SD card all you need is to reinitialize the sd card.

Will properly solve ISSUE #1103

Copied from original issue: arduino/Arduino#3607

Fix example ReadWrite

I think there is i some mistake in exaple ReadWrite. In code below is pointless while loop which burdens CPU. I'll change if for while and "while(1);" remove
if (!SD.begin(4)) { Serial.println("initialization failed!"); while (1); }

SD Card does not enter high voltage mode

Using information from here and here I am having difficulty setting my UHS-1, Type 2 cards into high voltage mode.

Presumably, this step should be accomplished when sending 0x40000000 during ACMD41, but that does not seem to be the case. In fact, according to the SD protocol, the upper 8 bits are ignored when the lower 24 bits are 0. So does this command even have any effect here? What should the value be instead?

Secondly, it asserts that some cards already require CRC. So I updated the CRC portion of cardCommand() to be:

// send CRC
uint8_t crc = 0XFF;
if (cmd == CMD0) crc = 0X95;  // correct crc for CMD0 with arg 0
if (cmd == CMD8) crc = 0X87;  // correct crc for CMD8 with arg 0X1AA
if (cmd == CMD1) crc = 0xF9;
//if (cmd == ACMD41) crc = 0x77; //correct crc for ACMD41 with arg 0x40000000
if (cmd == ACMD41) crc = 0x17; //correct crc for ACMD41 with arg 0x50000000
if (cmd == CMD58) crc = 0xFD;
spiSend(crc);

Lastly, it recommends sending a dummy byte before CMD0 (aside from the 74 clock pulses), therefore I begin the function:

uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
  // end read if in partialBlockRead mode
  readEnd();

  // select card
  chipSelectLow();

  // wait up to 300 ms if busy
  waitNotBusy(300);

  //send dummy byte before idle
  if (cmd == CMD0) spiSend(0xFF);

  // send command
  spiSend(cmd | 0x40);

...

But for some reason, my cards always remain in low voltage (1.8V) mode, despite being purportedly capable of 2.7-3.3V operation (as evidenced in the OCR).

My full ::init() function looks like this:

uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
  errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
  chipSelectPin_ = chipSelectPin;
  // 16-bit init start time allows over a minute
  unsigned int t0 = millis();
  uint32_t arg;

  // set pin modes
  pinMode(chipSelectPin_, OUTPUT);
  digitalWrite(chipSelectPin_, HIGH);

  /* Drive the MISO pin high */
  pinMode(SPI_MISO_PIN, OUTPUT);
  digitalWrite(SPI_MISO_PIN, HIGH);

#ifndef USE_SPI_LIB
  pinMode(SPI_MISO_PIN, INPUT);
  pinMode(SPI_MOSI_PIN, OUTPUT);
  pinMode(SPI_SCK_PIN, OUTPUT);
#endif

#ifndef SOFTWARE_SPI
#ifndef USE_SPI_LIB
  // SS must be in output mode even it is not chip select
  pinMode(SS_PIN, OUTPUT);
  digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
  // Enable SPI, Master, clock rate f_osc/128
  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
  // clear double speed
  SPSR &= ~(1 << SPI2X);
#else // USE_SPI_LIB
  SDCARD_SPI.begin();
  settings = SPISettings(350000, MSBFIRST, SPI_MODE0);
#endif // USE_SPI_LIB
#endif // SOFTWARE_SPI

  // must supply min of 74 clock cycles with CS high.
#ifdef USE_SPI_LIB
  SDCARD_SPI.beginTransaction(settings);
#endif
  for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
#ifdef USE_SPI_LIB
  SDCARD_SPI.endTransaction();
#endif

  chipSelectLow();
  //Send CMD0
  // command to go idle in SPI mode
  while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
    unsigned int d = millis() - t0;
    if (d > SD_INIT_TIMEOUT) {
      error(SD_CARD_ERROR_CMD0);
      goto fail;
    }
  }
  //Send CMD8
  // check SD version
  if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
    type(SD_CARD_TYPE_SD1);
  } else {
    // only need last byte of r7 response
    for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
    if (status_ != 0XAA) {
      if(status_ != 0x01){
        error(SD_CARD_ERROR_CMD8);
        goto fail;
      }
    }
    type(SD_CARD_TYPE_SD2);
  }
  //SDHC supported, SDXC maximum performance
  arg = type() == SD_CARD_TYPE_SD2 ? 0X50000000 : 0;

  while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
    // check for timeout
    unsigned int d = millis() - t0;
    if (d > SD_INIT_TIMEOUT) {
      break;
    }
  }

  /*Try CMD1 before trying ACMD41 again */
  if(status_){
    while ((status_ = cardCommand(CMD1, 0)) != R1_READY_STATE) {
      unsigned int d = millis() - t0;
      if (d > SD_INIT_TIMEOUT) {
        error(SD_CARD_ERROR_CMD0);
        goto fail;
      }
    }
    while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
      // check for timeout
      unsigned int d = millis() - t0;
      if (d > SD_INIT_TIMEOUT) {
        error(SD_CARD_ERROR_ACMD41);
        goto fail;
      }
    }
  }

  // command to initialize in SPI mode

  // initialize card and send host supports SDHC if SD2
  // if SD2 read OCR register to check for SDHC card
  if (type() == SD_CARD_TYPE_SD2) {
    if ((status_ = cardCommand(CMD58, 0))) {
      error(SD_CARD_ERROR_CMD58);
      goto fail;
    }
    if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
    // discard rest of ocr - contains allowed voltage range
    for (uint8_t i = 0; i < 3; i++) spiRec();
  }
  chipSelectHigh();

#ifndef SOFTWARE_SPI
  return setSckRate(sckRateID);
#else  // SOFTWARE_SPI
  return true;
#endif  // SOFTWARE_SPI

 fail:
  chipSelectHigh();
  return false;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.