chipKIT® Development Platform

Inspired by Arduino™

SD card library

Created Thu, 23 Jun 2011 19:08:01 +0000 by onebigdoor


onebigdoor

Thu, 23 Jun 2011 19:08:01 +0000

I had great success with the Arduino UNO and the SDuFAT library using Libelium's uSD shield.
Here is the library. (you can find the library by googling sdufat, the forum won't allow a link) I'm trying to use the same shield with the ChipKit Uno32, but there doesn't seem to be a library that supports SD cards yet.
After reading this post "Trouble with SPDR SPCR" (again, can't link, sorry) it seems that the trouble is that all the SD libraries I know about use AVR code for some of the low level stuff. The SDI library was rewritten for the ChipKit, should it be as simple as swapping the SDI calls that use AVR code for SDI calls in the updated SDI library?
I'm in a bit over my head, so I'm having trouble making a succinct question. Basically I'd like to know if there's a solution out there now for reading an SD card from the ChipKit UNO, if an intermediate level Arduino user such as myself should attempt to tweak the library, or if I have to wait for someone to rewrite a library from the ground up.


Jacob Christ

Thu, 23 Jun 2011 21:14:11 +0000

I was able to get the Circuits @ Home USB Host Shield lib working with the Uno32 but I basically had to re-write the SPI lib, not because it was needed, but because I couldn't include it in a contributed library. I kept getting Spi.h not found issues.

I'm sure getting the SD libs to work is a similar issue. I'm capable of getting the spi working, but I'm not sure how to make the mpide recognize the spi lib in a contributed lib.

Jacob


jerkey

Wed, 29 Jun 2011 00:08:47 +0000

It would be really great if someone got the SD library to work. The ChipKIT is already 3.3 volts so it's super easy to hook up a secure digital card.


Nickolai

Fri, 22 Jul 2011 21:15:32 +0000

Have you tried the following:

Go to Sktech > Add File...

Browse for the .h file and double-click it.

It should show up as a separate tab and the mpide should no longer give you the ".h file not found issues".

Let us know if it works as I am also trying to get the chipkit to write to an SD card.


GeneApperson

Fri, 22 Jul 2011 23:50:46 +0000

Digilent has someone working on porting the SD library. Unfortunately, the guy working on it is going to be out next week. It should be done some time the following week.

Gene Apperson Digilent


behbeh

Sun, 24 Jul 2011 10:41:11 +0000

Hello Gene that is a good message ! I am waiting for the libary to write my new project for a new datalogger to be used in a high performance geophysical instrument. Bernd


ricklon

Sun, 07 Aug 2011 22:26:39 +0000

SD libraries are update in the master branch https://github.com/chipKIT32/chipKIT32-MAX/tree/master/hardware/pic32/libraries/SD

They will be included in the new build.


rasmadrak

Sun, 11 Sep 2011 21:32:37 +0000

Hi there,

Did any of you get it to work? I would very much appreciate some help on reading files from a external SD card reader (ET-MINI SD/MMC [url]http://mac6.ma.psu.edu/space2008/RockSat/microController/MINISD.pdf[/url])...


Nickolai

Sun, 11 Sep 2011 22:58:51 +0000

I've gotten it to work with the most recent build, but there are still issues. It will write for a while, and then all of a sudden, you try to write again and it enters an infinite loop.

From my experiences, if you're trying to write less than 50KB of data, you might be OK for now - if you can accept that the thing might freeze up entirely at some point.


rasmadrak

Mon, 12 Sep 2011 06:57:30 +0000

How about reading? For the time being, I only need reading from the card.

Do you have any examples you could share? I'm really stuck....


Nickolai

Mon, 12 Sep 2011 14:40:32 +0000

I don't know about reading. There should be a read/write example with the SD library that you can reference.


rasmadrak

Wed, 14 Sep 2011 18:38:18 +0000

Finally got it to read, but at the "blistering" speed of 3.5 milliseconds per read byte... :(

I've read about people getting several KB's/sec throughput - is the native library really that slow? What could I be doing wrong?

Code:

myFile = SD.open("test.txt", O_RDONLY);  
while (myFile.available())
{
   myFile.read();
}
myFile.close();

Nickolai

Wed, 14 Sep 2011 21:47:16 +0000

It could simply be the library performing poorly since the chipkit architecture is very different from that of arduino, for which the SD.h library was initially written (if I'm not mistaken...)


rasmadrak

Fri, 16 Sep 2011 07:47:38 +0000

What kind of performance do you get with your SD-card applications? Is it possible that I've connected it wrong somehow? But then it shouldn't work at all, right? Also - I'm quite certain it's not the SD card or SD card-reader that is the problem, even the cheapest of the cheapest should be able to read 0.3KB/sec...

I've skimmed through the SD code and it would seem that "SOFTWARE_SPI" is enabled, SPI speed is set to HALF_SPEED etc. But even after I've modified what I believe to be the culprit the speed is the same.


rasmadrak

Tue, 20 Sep 2011 21:21:27 +0000

It turns out I was reading to little data. With 4096 bytes read, the total time was 48 ms. So I figure there's still a couple of digitalWrite's in the library that slows the reading down. But performance wise I could work with this. :)

Sorry guys...


pito

Thu, 22 Sep 2011 19:03:02 +0000

With pic32, spi @20MHz we've got >600kBytes/sec write speed and >1700kBytes/sec read speed with our fastest sdcards. See retrobsd.org forum. We've used enhanced buffering with spi (no DMA) and bsd fs. The r/w speeds depends on the sdcard used, though. Pito.


Mattia743

Mon, 03 Oct 2011 16:43:07 +0000

Hy,

I recently try SD card library mi chipkit UNO and found no problem on Reading, and create and delete files.... only one problem.... when I create a new blank file , with myFile = SD.open("newfile.txt", FILE_WRITE); then the program freeze when I try to write in it with for example : myFile.println("some text and etc"); .... Instead, if I create a file (with the function SD.open or with a PC) and write with a text editor some characters into the file, then the function works perfectly.... So why I'm only able to write in a NON-empty file? Why should the library be able to create new empty files if we can't write in them?

Thanks,

Mattia


rasmadrak

Tue, 04 Oct 2011 12:34:03 +0000

I'm having the same problem. The files are created on the SD card, but the initial writing hangs the program.


Nickolai

Tue, 04 Oct 2011 17:07:36 +0000

That's just the way the library works - the file needs to exist and have something in it. I normally just write "Start of file" at the top and that's enough. Unless I'm mistaken, I believe the library works the same way on Arduino.

Now what you'll really have trouble with (and this is what I was having trouble with a couple months ago, so given the rapid pace of chipkit development this might have been solved) is if you try to write too much to the file, eventually it will just hang on the write. To be specific, I'm talking about calling the write command lots of times, not necessarily writing a lot of data at once (although that might hang it as well, I never felt the need to find out).


rasmadrak

Tue, 04 Oct 2011 17:28:41 +0000

So the library cannot be used to create new files? That doesn't sound right to me, so I'm pretty sure I've misunderstood something.


Mattia743

Tue, 04 Oct 2011 17:31:13 +0000

So the library CAN be used to create new file (IT DOES!!) but can't write on it until we open them with a computer???

I don't think that's the right way.... :(


Nickolai

Tue, 04 Oct 2011 17:37:29 +0000

As far as I understand it, you are correct. The library cannot create new files. If you need multiple files, just create them all ahead of time. Or do you have some application that absolutely needs to be able to dynamically create files?


Mattia743

Tue, 04 Oct 2011 17:50:20 +0000

Yes,

I need to dynamically create AND write on files.... :( But it's a solvable problem??? Or you think there is some "hardware" reasons that makes the problem unsolvable?

Thanks, Matt


Mattia743

Tue, 04 Oct 2011 17:52:54 +0000

And the libray [color=#FF0000]CAN create new files[/color]..... with the library I can create how many files you want, but the remain empty, until you open it with a pc and write something into and save. After that you can write on it with the library

Matt


Nickolai

Tue, 04 Oct 2011 18:02:00 +0000

This is beyond the scope of my experience with SD.h. You might be able to use another library to create the files, although I don't know what works with ChipKit. Take a look at Fat16 or something like that.

Out of curiosity, what sort of tasks are you trying to accomplish that you can't just pre-make all your files on the SD card?


Mattia743

Tue, 04 Oct 2011 18:19:50 +0000

I am creating a sensor network with xbees series 2, controlled by one coordinator, in which I can add a sensor simply by powering it.... when the coordinator (controlled by the chipkit) "sense" the new sensor, it creates a file and start stores the data... so for each sensor that i will have in the network I want a file...


Mattia743

Tue, 04 Oct 2011 18:22:08 +0000

My question would transmit my potential intenction on collaborate to correct the library to avoi this, i think important, lack...... but i need a hand from someone tha knows how the library works and why it wotks in that strange mode.....


Nickolai

Tue, 04 Oct 2011 19:00:50 +0000

I'm not familiar enough with the library to help you out, but I would imagine you could still create files beforehand and simply have the controller write to them whenever a sensor is added - just take the next number (i.e. SENSOR1, SENSOR2, etc.). You can quickly tell which files have been written to and which ones haven't by looking at their size when you pull up the SD card.


rasmadrak

Wed, 05 Oct 2011 07:25:20 +0000

Ok, so I didn't misunderstood.

But it sound like a serious lack of functionality, and/or bug, which needs to be corrected. Why on earth should we be able to create files at all if the library cannot write to them? Requiring the user to create the files beforehand is not an acceptable solution to me. Imagine a datalogger that the customer tries to swap the SD card after it's become full, only to find the hardware failing to write to a new SD card...

From the Arduino code:

// open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }

The example does not speak of "create the files beforehand" etc. I think that would be crucial piece of information to share when creating a tutorial... :)

There must be something wrong here.


patrickk

Wed, 05 Oct 2011 18:02:31 +0000

The library is definitely able to create and write to files on Arduino boards. I have a code that creates a new file every time the code runs with an incremented number. It is working fine on the Arduino Uno, but this is the first problem I've run into while trying to port the code to the Uno32. I wish I knew more about how the library works, but I think I'm stuck at this point until someone else figures it out.


Mattia743

Wed, 05 Oct 2011 21:17:18 +0000

Have you ever tried to find in what precise point of the library code hangs when we try to write on file? this will be very helpful to try solutions....

Anyone can do / explain how to do?

Matt


patrickk

Mon, 10 Oct 2011 13:32:04 +0000

I don't suppose anyone has made any progress on this topic? I wasn't able to narrow it down any further. It just hangs when it tries to write to the newly created file. It seems like it could be a problem with the way the file is opened rather than the actual write. Maybe I'll try creating the file on the chipkit and writing to the same file with the arduino.

-Patrick


rasmadrak

Mon, 10 Oct 2011 18:35:37 +0000

I don't have the possibility to test it right now, but what if the following was done?

  1. open (and create) file
  2. close file
  3. reopen file
  4. write data

patrickk

Mon, 10 Oct 2011 23:33:59 +0000

I just tried that, and it makes it all the way to 4. The problem is still when you try to write to a blank file.

I also tried creating the blank file with the chipkit and writing to it with the arduino and that worked like a charm, so it would appear that the file gets created properly on the chipkit, but the problem is still with writing to the blank file.

Also, this may or may not be related, but when I do

myfile = SD.open(...

and there is no SD card inserted, the code hangs. I know I should check to see if the card initialized properly, but arduino runs right though it with no problems. Could it be some form of error handling that isn't functioning properly?


Mattia743

Tue, 11 Oct 2011 20:01:09 +0000

I try the 4 point but still it hangs when write to the blank file.... I hope digilent support will work on this because it should be already done in this release .... :(


rasmadrak

Sat, 15 Oct 2011 14:17:09 +0000

Again, with no possibility to test myself -

If a file is created beforehand, and then truncated and written to? Would that work? I'm thinking of a configuration file that should be read, possibly changed, and rewritten completely.


KeithV

Sat, 15 Oct 2011 16:31:43 +0000

Not sure if this is helpful, but in the latest release of the chipKIT Network Shield libraries we provide an example of a USB Memory Stick example with a fully funcitonal FAT file system. I realize this is USB and not SD, but it might give you an alternate path to do what you need. Here is a link to the Network Shield; at the bottom of the page will be a link to the libraries.

http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,892,942&Prod=CHIPKIT-NETWORK-SHIELD

Sorry I can't help specifically with SD, good luck!


patrickk

Wed, 02 Nov 2011 18:01:06 +0000

So if this is an actual bug, which it appears to be, is there any chance that it might be fixed? Do we need to submit a bug report on github?


claudiub

Thu, 03 Nov 2011 19:27:26 +0000

This is a bug. I tried Arduino sd library and sdfatlib, on Arduino boards. Both of them allow to create a new file, then to write into the newly created file. This is the normal behaviour for a library like this. As I tried the Max32 with the library, it allows to create a new file, but it doesn't allow to write anything in it. Even more, if I create an empty file on the SD card, using my PC, it doesn't write anything in it. On the other hand, if I create a file with a specific size, let's say 1 MByte, for instance with "fsutil file create new..." command in WinXP, the library is able to write in this file until the position pointer reaches the end of previously created file. Then it freezes.


claudiub

Fri, 04 Nov 2011 21:48:32 +0000

I think I've found a possible workaround, at least it works for me. The problem is in SdFile.cpp, method addCluster(). That method calls vol_->allocContiguous(1, &curCluster_). I don't know very well Pic32 C, but it seems that the curCluster_'s address is passed wrong. So I declared a local variable uint32_t*, I allocated it and I passed it to the allocContiguous. I was able to write in a newly created file. This is the code that worked for me:

uint8_t SdFile::addCluster() { 
          uint32_t *curClusterP_ = new uint32_t();
          *curClusterP_ = curCluster_;
          if (!vol_->allocContiguous(1, curClusterP_)) return false;
          curCluster_ = *curClusterP_;
          delete curClusterP_;
          curClusterP_ = NULL;
    // if first cluster of file link to directory entry
        if (firstCluster_ == 0) {
                 firstCluster_ = curCluster_;
                 flags_ |= F_FILE_DIR_DIRTY;
         }
         return true;
}

SdFile.cpp that needs to be modified is located in mpide-0022 install folder\hardware\pic32\libraries\SD\utility. There is another bug I've found: the library doesn't work with FAT32 cards. Please tell me if anybody found this. Thanks.


claudiub

Thu, 10 Nov 2011 15:07:25 +0000

Found a part of the FAT32 bug. It's in the same SDFile.cpp, openRoot method, where in calling vol->chainSize(firstCluster_, &fileSize_), fileSize_'s address is not correct. Tried this and works to open a FAT32 card , it says it creates a new file, but I didn't check the card. So I don't know if there is another bug remained or not.

Initial code in the openRoot method is:

if (!vol->chainSize(firstCluster_, &fileSize_)) return false;

Modified code in the openRoot method is:

uint32_t *pfileSize_ = new uint32_t();
    *pfileSize_ = fileSize_;
    if (!vol->chainSize(firstCluster_, pfileSize_))
    { 
	Serial.println("Error opening FAT32 filesystem"); return false;
    }
    Serial.println("Success opening filesystem"); 
    fileSize_ = *pfileSize_;
    delete pfileSize_;
    pfileSize_ = NULL;

The Serial.println's are just for debugging.

I'll not continue anymore. Using SD card library with ChipKit is just a waste of time. I'm going to switch back to Arduino or to NetduinoPlus. In the ChipKit wiki they say that SD library is working. Working for what? How did they test it? It's sad that a well done board like ChipKit Max32 has such a poor software support. End of story.


patrickk

Fri, 18 Nov 2011 22:34:54 +0000

Well I appreciate all the work you've done. I switched back to Arduino a while back because of this, but if these fixes can allow me to use the chipkit, I will. It's hard to pass up the speed and I/O increase.

As for the wiki, that should definitely be updated. Can anyone create an account? If so I'll change it myself.


Jacob Christ

Sat, 19 Nov 2011 03:58:22 +0000

Can anyone create an account? If so I'll change it myself.

I created an account and I'm no one, so surely anyone can...

Jacob


claudiub

Sat, 19 Nov 2011 13:15:53 +0000

Thanks, Patrickk. You're right, Chipkit boards are good pieces of hardware. Please tell me if my modifications work for you, too. BTW, I think that SD card library implementation that is used in MPIDE uses only the software SPI. Or am I wrong?


mattschinkel

Sat, 19 Nov 2011 20:25:16 +0000

Hello everyone. Can you please tell me how I may fix the following error? I am trying to run the sd card examples that come with the IDE in the most recent package. I get these errors when compiling CardInfo.

D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp: In function '__uint8_t spiRec()': D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:45:15: error: 'prtSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:45:23: error: 'bnSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:48:14: error: 'prtSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:48:22: error: 'bnSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:56:22: error: 'prtSDI' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:56:29: error: 'bnSDI' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp: In function 'void spiSend(__uint8_t)': D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:71:15: error: 'prtSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:71:23: error: 'bnSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:75:17: error: 'prtSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:75:25: error: 'bnSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:78:16: error: 'prtSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:78:24: error: 'bnSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:95:17: error: 'prtSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:95:25: error: 'bnSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp: In member function '__uint8_t Sd2Card::init(__uint8_t, __uint8_t)': D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:237:25: error: 'prtSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:237:33: error: 'bnSCK' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:238:25: error: 'prtSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:238:33: error: 'bnSDO' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:239:24: error: 'prtSDI' was not declared in this scope D:\uno32.\hardware\pic32\libraries\SD\utility\Sd2Card.cpp:239:32: error: 'bnSDI' was not declared in this scope

Thanks, Matt.


jkreutz

Tue, 22 Nov 2011 17:06:18 +0000

I can't even get the microSD card reader (I am using the one from sparkfun but have changed it so that it hooks up to 50-53 on the Max32) to speak with the Max32.

Any hints? I have a feeling that its the SPI connection that is failing but I haven't really had time to go through the SD library.


patrickk

Sun, 27 Nov 2011 16:16:54 +0000

claudiub, I tried out both of your modifications and it fixed both of the problems I was having. Fat32 now works and I can write to newly created files. For my purposes, everything now seems to be working as advertised.

As for the software spi, I have no idea. If so, I'm assuming it is for pin compatibility with the arduino, but I haven't dug quite that deep yet.

Now all I need to do is figure out how to use the pic32 timers.

Thanks for all the help claudiub. I hope you'll continue using the platform.


jkreutz

Sun, 27 Nov 2011 23:33:00 +0000

patrickk, are you using the Uno32 or the Max32? I am trying to get the Max32 to even communicate with the sd card reader with no luck.


patrickk

Mon, 28 Nov 2011 22:53:07 +0000

I'm using the Uno32.

I would check the chip select. I'm using the default (10) for the Uno/Uno32. I seem to recall there being some differences there, but I don't remember exactly what.


mattschinkel

Tue, 29 Nov 2011 08:01:50 +0000

Can someone post a working project?

Thanks!


rasmadrak

Wed, 30 Nov 2011 13:26:04 +0000

If I remember correctly, I had to update the SD card library (basically redefining the missing pins) to get it to work.

The problem still exists with the creation of files thou.

Chipkit team - When do you plan to fix this?


jkreutz

Wed, 30 Nov 2011 16:06:18 +0000

Thanks rasmadrak. I think I may have found what I have to change, when I find time I will attempt to fix what I think I need to and then test it.

Has anyone from Chipkit been looking into this, it lists on the wiki that SD card libraries work, but clearly it doesn't. Maybe that should be updated?


GeneApperson

Tue, 13 Dec 2011 17:04:55 +0000

I looked at the SD library yesterday. Part of the problem is that the code just doesn't work when compiled for 32 bit. One of the things that is going on is that pointers to member variables of one class are being passed to functions in another class. In the AVR build, it works fine. In the PIC32 build of exactly the same source code, it faults. This is happening, for example, when it tries to add a second cluster to a file when writing.

We've found a work around that will get past some of these problems, but I think that some parts of the library are going to have to be rewritten to really fix it.

I was hoping that I could have it done before the next release, but it's looking doubtful. This is on my high priority list of things to be fixed now.

Gene Apperson Digilent


CedGn

Wed, 04 Jan 2012 09:54:19 +0000

Hello,

I can't help you because I really don't how the filesystem works. When do you think this bug will be resolved ?

(I need to use this library at work in a R&D project.)

Thank you.


GeneApperson

Thu, 05 Jan 2012 22:32:14 +0000

I've been working on this for the last few days (among a bunch of other projects).

What I have determined so far is that someone, somewhere put #pragma pack(1) in one of the header files that gets included by everything in the library. This causes all structures to be packed on byte boundaries. This is needed to ensure that the C structs that describe the disk data structures match.

However this also caused all of the library object classes to be packed on byte boundaries as well, which caused DWORDs to be misaligned. The end result was that the functions that add clusters to a file were faulting because they were being passed misaligned pointers.

I have fixed this problem, and I can read and write files on the SD card. However, Windows disk check complains that there is an error on the disk after writing a file. The file contents are correct, but there is something wrong with the FAT table. I don't know if this is a pre-existing bug or a new one in chipKIT.

Anyone want to look into it further? I'll keep working on it, but I'm really busy with other things and don't know how soon I'll be able to finish it.

Gene Apperson Digilent


amiarts

Thu, 05 Jan 2012 23:38:08 +0000

Hello Gene,

these Library is really very important for us. A lot of projects hang on it at the moment.

Thanks and greeting René


rasmadrak

Fri, 06 Jan 2012 21:38:29 +0000

Nice to see some progress on this matter! :)

Will this version also contain a hardware SPI version of the library? Right now it seems to be software SPI only if one examines the code... I'm getting 1024 KB @ 18 milliseconds, which seems very slow.

The actual code I would need to have "hardware-ized", Arduino copyrighted, is this:

/** Soft SPI receive */
uint8_t spiRec(void) {
  uint8_t data = 0;
  
  // output pin high - like sending 0XFF
  PORTSetBits(prtSDO, bnSDO);

  for (uint8_t i = 0; i < 8; i++) {
	PORTSetBits(prtSCK, bnSCK);

    data <<= 1;

	// adjust so SCK is nice
    asm("nop");
    asm("nop");

    if (PORTReadBits(prtSDI,bnSDI)) data |= 1;


    PORTClearBits(prtSCK, bnSCK);
  }

  return data;
}

slayer1991

Wed, 11 Jan 2012 00:35:19 +0000

Quick question:

Can I use an SD card and a TLC5940? If I use slave select low when I update the TLC and the rest of the time slave select low on the sd card?

If anyone has both, can you test that please? I ordered an SD slot from sparkfun, it should arrive sometime so I can test myself.


amiarts

Thu, 19 Jan 2012 15:27:13 +0000

Are there new insights?

Thanks and regards René


slayer1991

Thu, 19 Jan 2012 18:52:51 +0000

When I'm trying to use the example to read the info about the SD card, it doesn't initialize and tells me to check the wiring over serial monitor.

So I check it, pins 10,11,12,13 on UNO 32, set as master. the jumper on pin 10 set to SS2. But it still isn't working. any ideas?

LE: Could anyone share their partly working modded sd library?


Jacob Christ

Fri, 20 Jan 2012 01:05:12 +0000

LE: Could anyone share their partly working modded sd library?

What version of MPIDE are you using? If your using 0822 you need mod the code as described in this thread to get something working. I think the latest version may have the mods, we haven't tied it yet.

I don't have the code on this computer, if I remember tomorrow I'll post it.

Jacob


slayer1991

Fri, 20 Jan 2012 01:12:01 +0000

Thanks, I'll check if the 1221 version has modifications to the sd codes.

Also, do I need pull up resistors?

LE: I added the 2 parts of code to the SdFile. I really hope the dev's are working on this. All I can do is just to recheck pin assignments until then. LE2: Why do I feel like the library is circling the registers instead of writing directly PORTxSET=0x20..? Shouldn't that be faster? Gene, you around :D ?


jRobert

Fri, 20 Jan 2012 05:28:35 +0000

PORTxSET should be LATxSET if you want to write to a port in the chipKIT.

jRobert


slayer1991

Fri, 20 Jan 2012 14:51:14 +0000

Actually I think writing to PORTxSET or LATxSET is the same for pic32. Reading is different.

I tried to modify the library but I must be missing something. I would appreciate it if someone would upload the modified SD and SoftSPI (if that's modded too) libraries. Or if some good news comes from the developers :)

Also, the 1221 version of the software has exactly the same SD library as the 0822


slayer1991

Wed, 25 Jan 2012 17:59:16 +0000

I managed to make it to work using another pin for SS and not the hardware one.

But when I write, I can't add another cluster to a file. I have the library modds posted here.

Is there anything to do?


nvrdunn

Wed, 25 Jan 2012 21:32:49 +0000

I managed to make it to work using another pin for SS and not the hardware one. But when I write, I can't add another cluster to a file. I have the library modds posted here. Is there anything to do?

Sounds like we are stuck at the same spot... I can list the card contents and when requesting to open a file, it creates the file but hangs when attempting to write. Frustrating...


nvrdunn

Thu, 26 Jan 2012 00:00:58 +0000

Sounds like we are stuck at the same spot... I can list the card contents and when requesting to open a file, it creates the file but hangs when attempting to write. Frustrating...

Another site someone had a somewhat similar issue, the fix, make sure the file you are writing to is not 0k. So I just put the SD card in my laptop, added 1 line to the text file, moved it back to the MAX32, and now it works!!


nvrdunn

Thu, 26 Jan 2012 00:06:56 +0000

Spoke to soon, yes it writes until the file hits 2k, then dies. If I delete everything from the file except the 1st line then I can write to it again until hitting 2k.

So close...


slayer1991

Thu, 26 Jan 2012 00:31:24 +0000

The way it adds new clusters has to be modified by someone who knows what he's doing. Until then..


nvrdunn

Thu, 26 Jan 2012 02:44:46 +0000

Did more testing and found if you open the file in the "setup" function then just 'write' then 'flush' data to the card in the loop and not close the file, I can get above the 2k issue. The issue seems to be opening a file that is above 2k. if it's below 2k and can open it has no issue writing to the file above 2k.


amiarts

Thu, 26 Jan 2012 08:38:55 +0000

Nevertheless, I have already written this. With Fat16 these are a 32K and with Fat32 2K.

Unfortunately, it is not gone on working on this mistake, although these Library are very importantly for many projects.

Greeting René


slayer1991

Fri, 27 Jan 2012 01:37:36 +0000

I was wondering.. is there a way to drop some Serial.prints in the libraries to see where it stops? And I get Serial not defined.

So, can I find out where does it stop, like after adding a new cluster? Or I can do that only with picKit3..


Jacob Christ

Fri, 27 Jan 2012 05:08:11 +0000

I was wondering.. is there a way to drop some Serial.prints in the libraries to see where it stops? And I get Serial not defined. So, can I find out where does it stop, like after adding a new cluster? Or I can do that only with picKit3..

Try including HardwareSerial.h in what ever file you would like to print from.

Jacob


slayer1991

Fri, 27 Jan 2012 18:36:30 +0000

Including HardwareSerial.h in sd .h files raises tons of other errors..

I guess I just have to wait on the dev's to fix it..


Gophert

Sun, 29 Jan 2012 15:06:31 +0000

I am not an expert but looking at the thread shows two problem. 1) a newly created file cannot be written to, and 2) only 2k of data can be written to an existing file if some amount of data was previously in the file.

Therefore, I am wondering if there is code that is supposed to check for open (available) sections on the SD card and that code is not working correctly.

Just a thought,

GopherT


rasmadrak

Sun, 29 Jan 2012 21:39:35 +0000

Please read this before commenting further.

I've been working on this for the last few days (among a bunch of other projects). What I have determined so far is that someone, somewhere put #pragma pack(1) in one of the header files that gets included by everything in the library. This causes all structures to be packed on byte boundaries. This is needed to ensure that the C structs that describe the disk data structures match. However this also caused all of the library object classes to be packed on byte boundaries as well, which caused DWORDs to be misaligned. The end result was that the functions that add clusters to a file were faulting because they were being passed misaligned pointers. I have fixed this problem, and I can read and write files on the SD card. However, Windows disk check complains that there is an error on the disk after writing a file. The file contents are correct, but there is something wrong with the FAT table. I don't know if this is a pre-existing bug or a new one in chipKIT. Anyone want to look into it further? I'll keep working on it, but I'm really busy with other things and don't know how soon I'll be able to finish it. Gene Apperson Digilent

The bug IS corrected (at least - so it seems) but is not yet in any of the released code-branches. Please wait for this to be released and try to work around the issue for now.

Design your code on how it is supposed to work, not on how it is currently (not) working.


Mark597

Mon, 06 Feb 2012 19:25:40 +0000

I have been trying just to read file from an SD card. I can list directory contents, verify the file exsists and get it's size. When trying to read a single char only a -1 is returned.

datafile.read()

It appears that several people have had success reading file from SD cards. I have an UNO32 with a ethernet shield that doesn't have the SD slot on board. The hardware works fine with a Arduino Uno but is too slow. The ethernet shield works fine with the UNO32 but not the SD shield.

Could someone suggest were to look?


Jacob Christ

Mon, 06 Feb 2012 22:25:23 +0000

Could someone suggest were to look?

If you read this entire thread there are three changes that need to be made to the SD library code to get it to work. This may not be perfect but it somewhat functional. These changes have not been rolled into the MPIDE since there is yet another issue that has been identified by Gene from Digilent that when competed should resolve all the issues and the other changes will be unnecessary.

Jacob


Mark597

Tue, 07 Feb 2012 01:05:58 +0000

Jacob

Thank you for your reply. I did not look through the entire thread but I will now.

Mark


Mark597

Wed, 08 Feb 2012 02:00:16 +0000

Jacob,

I read through the hole post and did find anything that helped me get the SD working. I noticed Gene mentioned having a setup that could read and write files but with minor FAT errors. I also gathered that I wasn't the only one with SD library issues. I guess what I learned is that I need to wait or find a fix myself if I can. ChipKIT boards hold a lot of promise if the Libraries get fixed.

Mark


Jacob Christ

Wed, 08 Feb 2012 02:19:23 +0000

Jacob, I read through the hole post and did find anything that helped me get the SD working.

Read these posts:

http://chipkit.cc/forum/viewtopic.php?p=2669&sid=16fbcb525816b01449d499b1a0a60fe6#p2669

http://chipkit.cc/forum/viewtopic.php?p=2702&sid=16fbcb525816b01449d499b1a0a60fe6#p2702

Some how I think there is a third issue as well.

Jacob


Mark597

Wed, 08 Feb 2012 15:54:18 +0000

Jacob,

I did notice those posts but the one had to do with writing to files and the second referred to reading FAT32. My card is formatted FAT 16 and I just want to read files. I have traced it back to this line of code in the SDfile.cpp that is returning the -1 by changing the return values to id the failure point.

In member function

int16_t SdFile::read(void* buf, uint16_t nbyte) . . . // amount to be read from current block if (n > (512 - offset)) n = 512 - offset;

// no buffering needed if n == 512 or user requests no buffering
if ((unbufferedRead() || n == 512) &&
  block != SdVolume::cacheBlockNumber_) {
  if (!vol_->readData(block, offset, n, dst)) return -1;   <---This is were the -1
  dst += n;                                                                     is being returned I
} else {                                                                          believe.

Is there a way to determine what is happen from here? I have traced it back further but don't see anything obvious. The code doesn't seem to use existing libraries for SPI communication with the SD card which I found strange.

Mark


Mark597

Sat, 11 Feb 2012 22:09:08 +0000

Does anyone have an UNO32 that will read SD cards that are formatted FAT16?

If someone does what SD shield are you using?

I have had no luck reading text files. I can list all the files in a directory and there size.

Any examples that read or write files do not work.

I'm using MIDE 0023 20111221. Many users appear to be able to read files but I can't. I get a failure when SD card CMD17 is issued to the SD card.

Mark


slayer1991

Sun, 12 Feb 2012 02:45:45 +0000

hello,

You can try the one attached with the examples.

I use no shield, but I'm using a different CS pin than 10.

Have a nice day!


Mark597

Sun, 12 Feb 2012 13:13:08 +0000

hello, You can try the one attached with the examples. I use no shield, but I'm using a different CS pin than 10. Have a nice day!

Fantastic! I replaced my SD libraries with the ones you provided and it works! The examples work now. Now I can get my Web Server going.

Did you have to modify the library some how?


slayer1991

Sun, 12 Feb 2012 14:34:52 +0000

This is the one Digilent is working on right now. It's not updated on their GitHub repository.


Mark597

Sun, 12 Feb 2012 15:11:15 +0000

This is the one Digilent is working on right now. It's not updated on their GitHub repository.

Thanks for posting the fix. I wasn't getting anywhere with it.


Mark597

Sun, 12 Feb 2012 16:56:57 +0000

Well I can read text file from my SD card now. Well until I start the ethernet. The ethernet libs use hardware SPI and the SD libs have there own soft SPI routines with in the library files. "SD2card"

Has anyone noticed this? Can they work together the way they are?


amiarts

Sun, 12 Feb 2012 22:19:58 +0000

Thanks Slayer,

It finally works!

Greetings Renè


amiarts

Sun, 12 Feb 2012 23:47:41 +0000

I'm using Fat16 with a read speed of about 93 kb / s. Rather slowly for a smooth animation on a display ...


Mark597

Tue, 14 Feb 2012 11:42:35 +0000

Fantastic! I replaced my SD libraries with the ones you provided and it works! The examples work now. Now I can get my Web Server going. Did you have to modify the library some how?

Thanks again slayer1991 for posting the SD library code!

I have notice one thing strange though. It won't read the last byte in a sector from a file. OR Saying it another way. It misses every character at 512 byte increments. I'm going to try and track it down. I think you are more familiar with code and might find it quicker.


Mark597

Tue, 14 Feb 2012 18:45:39 +0000

I found the issue I mentioned in my previous post. The problem seem to be in the SD2Card.cpp. See below.

uint8_t Sd2Card::readData(uint32_t block, uint16_t offset, uint16_t count, uint8_t* dst) { uint16_t n;

if (count == 0) return true; if ((count + offset) > 512) { goto fail; } if (!inBlock_ || block != block_ || offset < offset_) if (!waitStartBlock()) { goto fail; } offset_ = 0; inBlock_ = 1; }

// skip data before offset for (;offset_ < offset; offset_++) { spiRec(); } //********************************************** n = count - 1; //if the count = 1 a <= is needed in the for loop directly //below to get the very last byte. // transfer data ********************************************** for (uint16_t i = 0; i <= n; i++) { dst[i] = spiRec(); }

offset_ += count; if (!partialBlockRead_ || offset_ >= 512) { // read rest of data, checksum and set chip select high readEnd(); }

return true;

fail: chipSelectHigh(); return false; }


amiarts

Tue, 14 Feb 2012 20:18:25 +0000

I have tested it with the following original Arduino code and it works without errors:

uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) { return readData(block, 0, 512, dst); } //------------------------------------------------------------------------------ /**

  • Read part of a 512 byte block from an SD card.
  • \param[in] block Logical block to be read.
  • \param[in] offset Number of bytes to skip at start of block
  • \param[out] dst Pointer to the location that will receive the data.
  • \param[in] count Number of bytes to read
  • \return The value one, true, is returned for success and
  • the value zero, false, is returned for failure. / uint8_t Sd2Card::readData(uint32_t block, uint16_t offset, uint16_t count, uint8_t dst) { uint16_t n;

if (count == 0) return true; if ((count + offset) > 512) { goto fail; } if (!inBlock_ || block != block_ || offset < offset_) if (!waitStartBlock()) { goto fail; } offset_ = 0; inBlock_ = 1; }

// skip data before offset for (;offset_ < offset; offset_++) { spiRec(); } //******************************************************* //n = count - 1;

// transfer data for (uint16_t i = 0; i < count; i++) { dst[i] = spiRec(); } //******************************************************* offset_ += count; if (!partialBlockRead_ || offset_ >= 512) { // read rest of data, checksum and set chip select high readEnd(); }

return true;

fail: chipSelectHigh(); return false; }


Mark597

Wed, 15 Feb 2012 01:50:36 +0000

Yes that does look like the original code. I found all the Arduino examples worked fine. I have read large files and not noticed any problems. It may depend on how the files run across one block to the next on the SD cards disk structure. I also found that if you try to do a file seek to the missing byte it causes unpredictable behavior.

If it works for you then that's great. I could see that it might. All I know is that it works far better than the original and I found this to be a minor issue.


amiarts

Wed, 15 Feb 2012 12:10:23 +0000

If now one the hardware SPI would get up and running, so all this is still a little faster, then I would be happy.

Thanks and regards, René


MarkHoskins

Tue, 28 Feb 2012 00:15:15 +0000

I've got SD working pretty good so far.. using both Hardware SPI and software SPI. I'm using a Chipkit Max32 board. I'm opening a file and writing to it in an infinite loop, one byte at a time. I have the O_SYNC flag set, so after every write it will call sync. Inefficient, I know ( Preeetty sure it transfers 512 bytes SPI every sync, in accordance with SD standards. ), but in my actual use case the data sizes will be variable in size and I can't afford to lose too much information if the power were to die.

So pretty soon after I start writing to the SD card in this infinite loop, the write starts returning -1, in batches. As in, every so many loops several writes will sequentially fail. Eventually it gets into some mode where every single write fails.

It happens if I use software OR hardware SPI for my SD communication, but at different intervals in different ways.

I can post my code and such, but I'm mainly wondering if anyone else has been checking the return value on every write to make sure it succeeded.

I have some debug log information. It fails in several ways, but this is ALWAYS the first failure:

Write failed
7 &lt;- Failed in sync command
4 &lt;- SD_CARD_ERROR_CMD24
63 &lt;- status_, from what I can tell from the SD specs, this means pretty much every error that can occur with a command, did occur with this command. As in, IDLE, ERASE RESET, ILLEGAL COMMAND, COMMUNICATION CRC ERROR, ERASE SEQUENCE ERROR, ADDRESS ERROR.
/*
  SD card test 
   
 This example shows how use the utility libraries on which the'
 SD library is based in order to get info about your SD card.
 Very useful for testing a card when you're not sure whether its working or not.
 	
 The circuit:
  * SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
 ** CS - depends on your SD card shield or module

 
 created  28 Mar 2011
 by Limor Fried 
 */
 // include the SD library:
#include &lt;SD.h&gt;
#include &lt;DSPI.h&gt;

// set up variables using the SD utility library functions:
SdFile   root;
SdFile   test;
SdVolume volume;
Sd2Card  card;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int CSPin   = 49;

void setup()
{
  Serial.begin(9600);
  
  Serial.print("\nInitializing 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( 53, OUTPUT );     // change this to 53 on a mega
  //pinMode( 19, OUTPUT );
  //pinMode( 53, OUTPUT );
  //pinMode( 74, OUTPUT );

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init( CSPin )) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    Serial.println( (uint32_t)card.errorCode() );
    Serial.println( (uint32_t)card.errorData() );
    return;
  } else {
   Serial.println("Wiring is correct and a card is present."); 
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }

  // print the type and size of the first FAT-type volume
  unsigned long volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters, 512 bytes each.
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 2;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot( &amp;volume );
  
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
  
  test.open( &amp;root, "test2.txt", FILE_WRITE | O_SYNC );
  Serial.println( (uint32_t)test.isOpen() );
  test.seekSet( test.fileSize() );
}

uint8_t Data[ 16384 ];
void loop(void) {
  if ( test.isOpen() &amp;&amp; test.write( (void*)Data, 1 ) == -1 )
  {
    Serial.println( "Write failed" );
    Serial.println( test.writeError );
    Serial.println( (uint32_t)card.errorCode() );
    Serial.println( (uint32_t)card.errorData() );
  }
}

Mark597

Tue, 28 Feb 2012 01:37:26 +0000

Hi MarkHoskins,

I found using an SD Hex editor helped when trying to figure out problems like this. I used HxD editor and looked at the actual SD card FAT formatting. It takes a little bit to find the files on the card but can give you a different view point of what is happening. I found the last byte in a block was being missed when reading a file and it was important to my project. The libraries do have faults when it comes how files are algined on the SD card file structure.

Good Luck


MarkHoskins

Tue, 28 Feb 2012 18:48:00 +0000

There doesn't seem to be any particular pattern to the failures.

These numbers represent the number of successful writes before a failure occurs:

83
0
0
0
58
0
0
0
196
0
0
0
72
0
0
0
227
0
0
0
44
0
0
0
39
0
0
0
230
0
0
0
53
0
0
0
29
0
0
0
234
0
0
0
121
0
0
0
48
0
0
0
41
0
0
0
16
0
0
0
52
0
0
0
26
0
0
0
35
0
0
0
21
0
0
0
50
0
0
0
26
0
0
0
72
0
0
0
238
0
0
0
72
0
0
0
15
0
0
0
135
0
0
0
15
0
0
0
63
0
0
0

MarkHoskins

Wed, 29 Feb 2012 20:44:13 +0000

[ REMOVED to avoid confusion ]

Seems like the "n = count - 1" problem was happening here. I didn't think that the block read would be affecting the block write, but apparently it does. That is to say, the fix for block READING that Mark597 posted fixes my bug for block WRITING. Oi.


freto

Sun, 04 Mar 2012 12:05:27 +0000

I received my Max 32 Friday and here is where I am on Sunday evening with the help of previous posts. Hope this summary helps someone. In order to have the SD card working: 1- I downloaded the new library posted by Slayer1991 2 - Added an equal sign to become i <= n on line 383 of Sd2Card.cpp by Mark597 3- changed 514 to 515 on line 403 of SdCard.cpp

Hint: an LED between SCK and GND is very helpful to check if something is writing to the card.

Still I have a problem, my very fast SanDisk Ultra SD card does not work, it fails initialization! However it works with Arduino ProMini 3.3v. Any idea?

With the simple example code, I can write 3.2Mb in a minute. There is a function someone requested to increment filenames automatically.

#include &lt;SD.h&gt;

File myFile;
char fileName[13];
long i = 0;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  pinMode(53, OUTPUT); // 53 on the Max32
  
  if (!SD.begin(53)) { 
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  createSDFile(myFile);
  delay(100);
  myFile = SD.open(fileName, FILE_WRITE);
  
  while (millis() &lt; 60000)
  {
    i++;
    String str = i;
    str += " ";
    str += millis(); 
    myFile.println(str);
    //delayMicroseconds(100); // Used to Crash without the delay, add bigger delay if needed
  } 
  myFile.close();
  Serial.println("Done 1 minute");
}

void loop()
{

}

// create a new log file, increment number if file already exists
void createSDFile (File dataFile)
{
    String str;
    
    for (int i = 0; i &lt; 999; i++) {
        str = "LOG";
        if (i &lt; 10) str += "00";
        else if (i&gt;=10 &amp;&amp; i &lt;100) str+="0";
        str += i;
        str += ".txt";
        //Serial.println(str);
        str.toCharArray(fileName, sizeof(fileName));
        if (!SD.exists(fileName)) {
            dataFile = SD.open(fileName,FILE_WRITE);
            delay(10);
            dataFile.close();
            break;
        }
    }
}

MarkHoskins

Mon, 05 Mar 2012 18:08:42 +0000

This will probably NOT fix your problem, but I have a small suggestion. I may be off base with this, but I think in general you should NOT use the print functions provided by the File class to output data to the file. The reason being this:

From Print.cpp:

void Print::println(const String &amp;argString)
{
	print(argString);
	println();
}

void Print::print(const String &amp;argString)
{
	for (unsigned int i = 0; i &lt; argString.length(); i++)
	{
		write(argString[i]);
	}
}

As you can see, it is calling the write function for every character in the string. Since the underlying architecture is an SdFile, which has to speak SPI in 512 byte blocks, every character in your string is going to require the transfer of 1024 bytes plus overhead.

The sequence, as far as I can tell, is thus (A block is 512 bytes in size):

Request to SdFile to write byte 0 of block 0. SdFile reads block 0 from SD card. SdFile replaces byte 0 of block 0 with requested data. SdFile writes block with replaced byte to SD Card.

I think you should use the write functions directly IE: myFile.write( char_array, num_bytes );

I would be curious to see if doing this can improve your throughput.

[EDIT]: Actually looked up SanDisk ULTRA SD, and it appears that it has a 64 GB capacity?

The largest card this library supports is an SDHC card, the protocol of which can address at maximum 65536 blocks of 512 bytes each, to a maximum of 32GB.

I don't think the SD library can talk to your 64 gigabyte card.

[EDITEDIT]: It also doesn't really matter if the card is 64 GB in size, if it is an ultra SD ( that is, an SDXC ) card, it won't work with this library.


freto

Wed, 07 Mar 2012 14:00:45 +0000

Thanks for the suggestions, I tried to play with the print and write function, but found out that 512 byte are probably accumulated in memory and then written to the card. So the difference was not really significant. There is maybe upon compilation another code specific to the PIC32 to optimize this. If you try my example sketch you will see that 512 characters are written in the same millisecond, then there is a gap of 5 millisecond probably used to write to the card.

The overall writing speed is higher than I expected or need, but I am wondering how to avoid this 5 or 6 millisecond delay? If I call the flush() function after each write it takes 5 millisecond every time.

The card that does not work is the sandisk-ultra-sdhc in 8Gb version. It is probably not has tolerant has my other cards. However I tried the Sandisk-Extreme-sdhc in 16Gb and it worked!


MarkHoskins

Wed, 07 Mar 2012 18:09:58 +0000

Oh, I got confused. In my application I use the O_SYNC option when opening the SD file for writing, which is the application for which you should avoid using the print functions since it flushes after every write.

The default SD uses bit banging to get the SCLK for the SPI ( Software SPI ). I don't really know what rate it is capable of attaining.

I modified my library to use DSPI at 10mhz, and a sync takes 2 ms.

As to why your card isn't working, I haven't a clue. I'm using a Team 8GB MicroSD with an SD adapter. Adapter is passive, so it's not the capacity of the card that is the problem.


KP_OZ

Sun, 25 Mar 2012 04:14:14 +0000

Have found a solution to read and write an SD card, that works on my Chipkit UNO using MPide 0023 It ONLY works when ALL the following conditions are met :

  1. CANNOT use pin 10 as chipSelect. ( Pin 8 or 9 works) (must set chipMode(10,OUTPUT);
  2. Must have BOTH #include <SD.h> AND #include <SPI.h> at start of script
  3. Must use BOTH card.init(SPI_FULL_SPEED,chipSelect) AND SD.begin(chipSelect)
  4. SD card type - can be formatted as FAT16 or FAt32, but MUST be reported as FAT16 by Chipkit. To explain - I have 2 cards - a 16 meg and a 2 gig. Both formatted on XP. XP doesn't give a format choice for the 16 meg - too small. Only formats as FAT. Chipkit reports this as FAT12, plus gives the size, but cannot read or write. For the 2 gig, XP offers the option to format as FAT32 or FAT. Formatted as FAT32 - it works; Formatted as FAT, Chipkit reports it as FAT16, AND I can read and write to the card. (Yes - using the same computer that formatted the 16meg card).

Also proving - Coffee is an essential food ...QED.. Hope this assists ................Keith


Verdris

Sat, 07 Apr 2012 01:27:33 +0000

Has there been any official movement on the SD library? Mine and I'm sure a lot of other projects are dependent on reliable datalogging. I would love to help the effort but I have little experience in the type of programming it takes to make this all work.


togzball

Sat, 07 Apr 2012 15:32:12 +0000

I'm struggling with it too. I have chip kit UNO32 with a Sparkfun microSD card shield. I am using MPIED 0023. I'm using a FAT32 8 GB card.

So far I can get the card to report card info but can't get it to read or write a file. I was wondering if anyone had an example of writing to a file with this combination? I also was wondering if the changes talked about in this forum have been put into the newest MPIDE 0023?

My sketches seem to hang up on !SD.begin(8) in the example code.

I also would like to note that a Arduino UNO works fine with the same board and card - the SD read/write example works perfectly with my hardware and the example sketch. So it is clearly the implementation of the Chipkit UNO32 code that is causing the problem. I have tried to make the changes listed in the forum but with no luck.

Any suggestions would be great.

As of April 16, 2012 - still no changes - no luck... wish for simple working code for Chipkit uno 32 to do data logging.

Thanks Togz.


shahrul

Fri, 20 Apr 2012 12:52:34 +0000

Hi, I'm trying SD example with chipKIT Max32. I use SD Card module from LC Studio bought on ebay. I connect MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 8

I tried example CardInfo and ReadWrite, but initialize fail.

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

What should I change?


togzball

Wed, 25 Apr 2012 02:18:32 +0000

I am still having no luck with your exact problem, I have no luck and no help to get it going, so I switched to Pinguino 32 OTG - it still isn't perfect, but at least they respond to posts and someone helps out. The SD card library works there to some degree and the USB serial port has some functionality. While a bit difficult to work with, they are making progress, I see no progress in the Chipkit code. You can get a Pinguino 32 at Mouser for $30 and it has built in micro SD card reader.

Togz


EmbeddedMan

Wed, 25 Apr 2012 18:24:59 +0000

One suggestion here is to try using the very latest test build of MPIDE. There have apparently been some changes made to the SD code that are not yet in the official release, but are in the test builds. Give that a try, and report back if you still experience issues.

We really do want to get SD stable and working before we do the next major release.

*Brian


togzball

Sat, 28 Apr 2012 14:54:17 +0000

Brain,

Thanks so much for the help, this makes my chipkit much more useful. The suggestion worked. I am able to use the examples to read and write to the SD card (FAT 32, 8 GB) with my sparkfun board and my chipkit MAX32.

One more question, is it possible to import the SD library to the more stable released version of the code, or is it just better to use the beta version?

If I get more results or bugs with testing I will report them.

Thanks Togz


Jacob Christ

Sun, 29 Apr 2012 20:12:27 +0000

Brain, One more question, is it possible to import the SD library to the more stable released version of the code, or is it just better to use the beta version?

When even I get a chance I always move to the latest code. Often there are other things advancing as well and I'll be able to take advantage of them when I get the chance.

Jacob


EmbeddedMan

Sun, 29 Apr 2012 20:25:24 +0000

I agree with Jacob. I always try to use the latest test version of MPIDE. In the best case, you get the best features and bug fixes. In the worst case, something doesn't work - and you can report it to us here on the forum so we can quickly fix it for the next release!

Thanks for helping out, and I'm really, really glad it's working for you.

I've got my own SD based project coming up shortly, and I'm glad to know the libs are working properly.

*Brian


rasmadrak

Sun, 06 May 2012 23:15:35 +0000

The SD card library is a lot more stable and better in the current (2012-04-29) test release! Now it works as intended and I'm a happy camper! :)

I had to manually add the code below in File.xxx to get it just as I wanted, but I can live with that. :)

int File::read(uint8_t *buf, size_t size)
{
	return SD.file.read(buf, size);
}

togzball

Tue, 08 May 2012 03:14:37 +0000

I have an additional question about the SD card library and it's use with the SPI library (either hardware version or software version).

I am still working on my data logger program. I am targeting using the MAX6674/MAX6675 or the newer MAX31855 with the SD card to log temperature data. However I noticed that the SD card library uses the SPI library to write to the SD card. The maxim chips are are read only SPI bus parts.

My question is: Is it possible to use the SD library and the SPI bus at the same time? Instead, does one have to setup the SPI for the MAXIM chip, take the reading over SPI, then setup the SD card for write, print to the SD file and close the card for every MAX read/SD card write? The next read cycle would start with the setup of the SPI again (etc...). I'm looking for the best method.

Any example of using the SD library with a SPI bus part would be helpful. I've looked for several days but haven't found a suitable example of using the SD library and the SPI bus at the same time.

Ultimately I would like to have a board like this one below to read multiple thermocouples from.

http://ryanjmclaughlin.com/wiki/Quad_Thermocouple_Interface (A very cool board and a very nice Arduino library).

I think a lot of people could find help on this topic very useful. So far I have the serial display working with the SD card library no problem, but am in the process of getting the SPI chips from MAXIM direct (It's cheaper).

An example of using SPI bus with the SD card would be cool. If anyone knows of a good example that would be great and very helpful to Chipkit users.

Currently I'm using the newest version of the IDE and the Chipkit MAX32.

Thanks Togz


rasmadrak

Tue, 08 May 2012 12:33:33 +0000

Hi there,

Your question has nothing to do with the SD card library actually. Check out tutorials for multiple SPI devices - but it basically boils down to deactive all the slaveselect lines except for the one that you want to communicate with. Talk to A, then Talk to B etc.

Remember - you never multitask with Chipkit/Arduino.


togzball

Wed, 09 May 2012 02:58:21 +0000

Thank you for your kind reply.

It would have been nice if you could have posted a link to a recommended tutorial, obviously you know of one. I am having trouble finding a really good example.

In my thinking my question does have something to do with the SD library.
Specifically, the SD most likely uses the SPI library either hardware or software. Thus, the use of the SD library card also sets the SPI bus clock polarity, frequency and phase for proper communications with the card. However the library hides this information from the user to make it easy. So if my other SPI device requires different settings for the SPI bus, is there an easy way to keep the file open or do you have to shut it before reading sensor data? Really it is as much a question about the inner workings of the SD library as it is a multiple device SPI question. It also may relate to how the File system interacts with the SD card library.

Possibly someone has encountered this issue and has a trick or tip to make this work well. I'm sure others could use an example if it exists. Maybe one could switch the polarity, frequency, etc and - toggle the chip select lines and set them back when it is time to write to the SD card without closing the file. I was trying to avoid digging deep into the SD library if someone already knew of a solution for this kind of program.

As for your comment regarding multitasking - Although Arduino is a single core processor but there are lots of nice task schedulers - while not true simultaneous thread processing there are many examples of simple systems with Arduino. For example DuinOS is a stripped down port of FreeROTS. Also Pyxis OS and OS_WRAP are also very nice. Even with the FlexTimer 2 library I was able to use timer interrupts to schedule tasks very easily. So it seems there are some conflicting views about multitasking or sudo multitasking on Arduino.

See.
http://robotgroup.com.ar/duinos/wiki/index.php?title=Main_Page
http://www.skewworks.com/pyxis/ http://arduino.cc/playground/Code/OsWrap

Again, thanks for your nice comment.


rasmadrak

Wed, 09 May 2012 07:52:21 +0000

Hello again,

I see now that my response was indeed a little short, and maybe sounded a bit harsh. That was not my intent. I apologize for this.

I am using the SD card to read data and the displays it over SPI on a Dot-Matrix-Display. Luckily the devices uses the same clock polarity. Keeping an open file is no problem either, unless you plan to hold it open for a long time. I, for example, only allow loading a single 512 byte chunk of data before updating the screen again. Each image is loaded over three frames. The SD card library seem to be handling the SPI.begin/end natively without the users interaction, so I only do SPI.begin/end before and after updating the display. I figure it might not even be needed to end the SPI if you're not changing the clock polarity etc.

A tutorial that seem quite promising can be found here: http://tronixstuff.wordpress.com/2011/06/15/tutorial-arduino-and-the-spi-bus-part-ii/

It's really about having each device have it's own slaveselect, the rest can be shared. The simply toggle each device, do what you want. Although I'm by no means an expert on SPI communications, I figure it should be possible to "restart" the SPI with a new clock polarity before talking to a device that requires any other than standard. It seems like a normal thing to do when connecting to multiple devices. :)

Regarding the multitasking - I was referring to single instructions performed one after the other. I am aware that you can layer multitasking on the application level, but I was referring to true multi-instruction use. This is to me a great strength in programming since I know that nothing else (well, besides interrupts etc) will bother the current function.

EDIT: I checked out the OsWrap library - seem rather solid! Does it work on the Chipkit as well? It would greatly simplify my current Pinball-machine loop... :)


rasmadrak

Sat, 12 May 2012 00:33:42 +0000

Hello again -

I found a bug (and the solution) in the latest SD card library. :ugeek: It might have been reported before - but is still present.

In the file "Sd2Card.cpp" , on rows 380 and 403 it says "n = count - 1;" and " while (offset_++ < 514) spiRec();" respectively.

These should be changed to read:

n = count; and while (offset_++ < 512) spiRec();

Without these changes the last byte in each block will never be read... If only the n = count is changed, the performance will drop until 514 -> 512 bytes (its' probably error checking/double loading) .

So - I thought my bitpacking routine was faulty, but it turns out to be the library. It looked like it worked when I loaded an unpacked image, but the error was always there - just masked better.

Hope this helps anyone! :)


Jacob Christ

Sun, 13 May 2012 23:21:23 +0000

Hello again - I found a bug (and the solution) in the latest SD card library. :ugeek: It might have been reported before - but is still present.

Please post any issues found (especially ones with solutions to the github issue list. They may never get rolled into the the code if just posted on the forms.

Jacob


rasmadrak

Mon, 14 May 2012 07:30:44 +0000

Ok, I'll give it a shot. Thanks!


spencoid

Wed, 06 Jun 2012 17:02:01 +0000

i am also just interested in reading. i have downloaded all the most recent files from

https://github.com/chipKIT32/chipKIT32-MAX/tree/master/hardware/pic32/libraries/SD/utility

and replaced the ones in the MPIDE version 20110822 release SD folder in the libraries folder. i try compiling any of the example sketches and get the following error followed by a whole list of others.

This sketch or library uses AVR-specific code that may not work with the chipKIT platform. See this forum for more information on porting code to chipKIT [www.chipkit.org/forum/viewforum.php?f=7]

what does it take to get SD card basic card functionality working? i would appreciate a reference for beginners. i have gotten some pretty complicated stuff to work on the chipkit uno. i am doing signal analysis and really need the faster processor than the arduino. the few libraries i have used (LCD for example) just work. i have no idea what to do to get the SD card library to even begin to look like it will work.


spencoid

Wed, 13 Jun 2012 08:00:23 +0000

I am trying to get the SD card working and did find that the latest test IDE does support the use of the SD card library on the chipkit. However there seems to be a problem with this test IDE and the interrupt timer support. I need a high speed interrupt timer which is why I am using the chipkit but I can't use the following configuration with the test IDE. Is it possible to copy some relevant files to the old working IDE, either version 23 or 22 to make the SD card work or is there an equivalent to the following that will work with the new test IDE?

const long SAMPLERATE = 150000; const int8_t midscale = 50;

// the following is for the sampler/PWM, 10 bits PWM OpenTimer2(T2_ON | T2_PS_1_1, 1024); OpenOC1(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);

ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_3); OpenTimer1(T1_ON | T1_PS_1_1, F_CPU / SAMPLERATE); SetDCOC1PWM(midscale);


skyjumper

Sun, 15 Jul 2012 01:40:29 +0000

Hi All...

I was just wondering if anything has changed with this? Is the issue fully resolved?


spencoid

Sun, 15 Jul 2012 01:53:52 +0000

not sure what you are referring to specifically. if you mean the need to use the include that i mentioned in order to have interrupts working with the test IDE, i have no idea if this will be added back in the next release. doesn't seem to be a big problem to use the include if you need it but it die take me some searching to figure out how to get the interrupts working after trying the test IDE.


skyjumper

Sun, 15 Jul 2012 02:06:38 +0000

I meant SD card with FAT16/FAT32 support in general. I'm new here, and I don't know which version of the IDE is which. A month had passed by since the prior post and I was wondering if this library was in the current IDE or still in a beta.


spencoid

Sun, 15 Jul 2012 02:15:00 +0000

it seems that the current IDE (unless the mpide-0023-windows-20120612-test has been worked into a new release) does not have a working SD card library. the test IDE does work. i did have a strange situation in i occasionally lost bytes and could not figure out why but it always occurred at the same place in a file. it turns out that i had misunderstood the default condition of digital lines. i had assumed that they defaulted to output whereas they default to input. so i did nothing to declare the chip select pin of the SD card as output. one would think that it would just not work as per the warning in the docs but it did work only lost a byte now and then. once i declared the select pin as output, the problem was solved and i seem to have a working SD card reading program. i have not tried writing yet so... make sure you use the test IDE until a new release comes out and make sure you declare the select pin as output.


skyjumper

Sun, 15 Jul 2012 15:12:43 +0000

Okay, thank you for the update.


mamumo

Thu, 19 Jul 2012 11:58:05 +0000

Hello! I have max32 board and this micro sd module http://www.cooking-hacks.com/index.php/microsd-2gb-module-for-arduino.html I am trying to run the sample libraries, for example CardInfo, but I cant´t inizialize my card. This message appears:

Initializing SD card...initialization failed. Things to check:

  • is a card is inserted?
  • Is your wiring correct?
  • did you change the chipSelect pin to match your shield or module?
  • The card is inserted (I have not done anything more with it)

  • Wiring connection, I do this: I have used a protoboard for my module and I have connected

    max32 microsd 50(SDI) ---------- MISO 51(SDO) ---------- MOSI 52(SCK) ---------- SCK 53 (SS) ---------- SS

    Others two wires for GND and 5V.

  • And ChipSelect I don't sure that is good, I think that my CS of my module micro SD is pin 10.

Iam using the last version of MPIDE: mpide-0023-windows-20111221

Somebody knows what is my problem?? Please I need help.

Thank you!


spencoid

Thu, 19 Jul 2012 14:40:42 +0000

even if you get it to initialize, it will not work properly with the released IDE. you need the test IDE mpide-0023-20120612-test also read the rest of this thread re interrupts if you are using them.

is the card formatted to fat 32? are you specifying the correct chip select pin in the SD.begin(4) statement?


mamumo

Fri, 20 Jul 2012 08:36:00 +0000

Thanks for answering!!

I have installed this new version IDE mpide-0023-20120612. But I have a question about card formatted, my microsd is 2GB, how i have to do the formatted with FAT16 or FAT32?? and when the card was formatted I have to add any libraries to my program?(FAT32 or FAT16).

Other question is I have to add the sentence that you say SD.begin() in my program? because in the test program CardInfo isn't appear. And why you say that CS=4 ??


spencoid

Fri, 20 Jul 2012 16:51:40 +0000

you can get SD card formatting software from sdcard.org the following should let you know if you can initialize and read from the sd card. i have not tried writing to the card.

#include <SD.h> // was suggested that these need to be declared first #include <SPI.h> // this was recommended, not sure why

File SDfile; // global variable

void setup() { Serial.begin(115200); pinMode(4, OUTPUT); // must set pinmode output on SD card chip select pin which is 4 in this case if (!SD.begin(4)) { // initialize SD card with chip select pin as parmeter Serial.println("initialization failed!"); return; } else{ Serial.println("SD initialization done."); } }

void loop() { byte read_byte; unsigned long byte_count = 0; unsigned long bytes_left = 0; SDfile = SD.open('test.txt'); // need to have a file called test.txt on the SD card Serial.println('test.txt opened'); while (bytes_left = SDfile.available()) { // step through sd card file read_byte = SDfile.read(); byte_count ++; Serial.print('byte '); Serial.print(read_byte); Serial.print(' count '); Serial.println(byte_count); }
SDfile.close(); }


rasmadrak

Sun, 22 Jul 2012 17:11:32 +0000

(Just a tip, if you use the Code-tag the formatting of the pasted code will remain correct. Much easier to read code-snippets that way)


rasmadrak

Sun, 22 Jul 2012 17:15:05 +0000

you can get SD card formatting software from sdcard.org the following should let you know if you can initialize and read from the sd card. i have not tried writing to the card. #include <SD.h> // was suggested that these need to be declared first #include <SPI.h> // this was recommended, not sure why File SDfile; // global variable void setup() { Serial.begin(115200); pinMode(4, OUTPUT); // must set pinmode output on SD card chip select pin which is 4 in this case if (!SD.begin(4)) { // initialize SD card with chip select pin as parmeter Serial.println("initialization failed!"); return; } else{ Serial.println("SD initialization done."); } } void loop() { byte read_byte; unsigned long byte_count = 0; unsigned long bytes_left = 0; SDfile = SD.open('test.txt'); // need to have a file called test.txt on the SD card Serial.println('test.txt opened'); while (bytes_left = SDfile.available()) { // step through sd card file read_byte = SDfile.read(); byte_count ++; Serial.print('byte '); Serial.print(read_byte); Serial.print(' count '); Serial.println(byte_count); }
SDfile.close(); }

You will also need to have pinMode(53, OUTPUT); (if it's a Max32) defined in the setup(). If it should default to an input the SD card will not work. It should also be enough to do a "SDfile.available()" to check if there's any data available to read if you're only interested in checking if reading works.


spencoid

Sun, 22 Jul 2012 17:29:12 +0000

thanks for the tip on the code tag. i thought you had to attach a file to keep the formatting and was too lazy to make one. the tag will make it much easier to post a readable snippet.


mamumo

Mon, 23 Jul 2012 06:37:18 +0000

Thank you all for answering.

I have tried all you say but no way to get card initialization. I think maybe my micro SD module is damaged.

Anyway thank you again at all persons who have spent time answering me.


alvesjc

Mon, 08 Oct 2012 00:29:50 +0000

Hi!.

Can i do a raw bitmap reading with this lib?


Jacob Christ

Mon, 08 Oct 2012 02:33:12 +0000

You can read any file. Files are just returned as a stream of bytes.

Jacob


alvesjc

Mon, 08 Oct 2012 11:26:01 +0000

Hi Jacob.

Ok, I've to figure out why implementing the SD lib to read the file, I get corrupted picture.

Thanks.

Regards,

Joao


Jacob Christ

Mon, 08 Oct 2012 18:49:55 +0000

My guess is your using an old version of the library. I suggest using the latest release candidate.

Look at this thread:

http://www.chipkit.org/forum/viewtopic.php?f=20&t=1495

Jacob


alvesjc

Wed, 10 Oct 2012 01:58:44 +0000

Hi.

That's the version I'm running.

I've completely rewritten the function to use SD library. I'm using one version of the Lib from Henning Karlsen that is used for arduino. I've removed the calls for tinyfat and make it use the SD lib directly.

I've managed to read the files and put it in TFT with myFile.read() function.

But some pictures get corrupted, partially corrupted.

The files are good, as they show up well when using arduino.

Is there any chance of this library being crashing with some characters from the picture data?

The function is this:

word loadImages(int x, int y, int sx, int sy, char *filename)
{
	File myFile;
	int cx, cy, cp;
	word temp, result;
	byte r,g,b;

  regtype *P_CS;
  regsize B_CS;
  		P_CS	= portOutputRegister(digitalPinToPort(84));
		B_CS	= digitalPinToBitMask(84);

	myFile=SD.open(filename);

        cbi(P_CS, B_CS);
        if (myFile.available()) 
        { 
            
              for (int y=0 ; y&lt;sy; y++)  
              {
                for (int x=0 ; x&lt;sx; x++)  
                {    
                  myGLCD.setXY(x,y,x,y);
                  myGLCD.LCD_Write_DATA(myFile.read(),myFile.read());
                }
              }    
        }

	myFile.close();
	sbi(P_CS, B_CS);
	return 0;
}

This myFile.read(), performs a raw read right?


alvesjc

Tue, 27 Nov 2012 23:58:56 +0000

Hi again.

Well it turns out to be a speed problem. I was using a old card that wasn't handling the speed. With a more recent card, faster one, is working without errors.

One thing I don't understand, is why the function that sets the speed, has not been ported and is commented.

This explains why i change the speed in the init but it doens't change a thing in card reading behaviour.

The function is in sd2card.cpp and looks like this:

uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
  //if (sckRateID &gt; 6) {
  //  error(SD_CARD_ERROR_SCK_RATE);
  //  return false;
  //}
  //// see avr processor datasheet for SPI register bit definitions
  //if ((sckRateID &amp; 1) || sckRateID == 6) {
  //  SPSR &amp;= ~(1 &lt;&lt; SPI2X);
  //} else {
  //  SPSR |= (1 &lt;&lt; SPI2X);
  //}
  //SPCR &amp;= ~((1 &lt;&lt;SPR1) | (1 &lt;&lt; SPR0));
  //SPCR |= (sckRateID &amp; 4 ? (1 &lt;&lt; SPR1) : 0)
  //  | (sckRateID &amp; 2 ? (1 &lt;&lt; SPR0) : 0);
  return true;
}

How do I change SPI speed in this lib?


alvesjc

Wed, 28 Nov 2012 14:34:10 +0000

Can someone help?

Regards


mkirby

Mon, 17 Dec 2012 23:12:26 +0000

I am not familiar with this specific library, but I have written code to set a SPI controller to a given frequency. Attached is a SPI library I wrote for MPLAB, but the concept should be the same in your case. Take a look at the end of the spiInitialize() function in spiPort.c. From there you'll want to follow the short functions DclockGetPbClock() and DclockGetSysClock(). Let me know if you have any questions.