chipKIT® Development Platform

Inspired by Arduino™

sd card hot swap???

Created Mon, 18 Jun 2012 07:26:30 +0000 by spencoid


spencoid

Mon, 18 Jun 2012 07:26:30 +0000

I have been trying everything i can think of to write code that allows for changing SD cards while the uno is running. i finally got the SD card reading correctly, i think but i want to be able to pause the program and change cards without rebooting. Does anyone have an example of code that allows this? I have tried every combination of opening closing initializing that I can think of but i can not open a file on the card once i remove it and insert it again/

This is critical to my project so hopefully someone can suggest how to get it to work.


rasmadrak

Wed, 20 Jun 2012 10:02:27 +0000

Sorry for being unhelpful, but I asked the very same question a while ago and it seems that no one has done this. In fact, the SD library doesn't seem to allow it either.

It seems utterly weird to me to have a .begin() but not a .end()... :(


spencoid

Wed, 20 Jun 2012 16:54:14 +0000

there are a lot of weird things about Arduino. i am used to programming in a complete language with an excellent IDE and get really annoyed when obvious features are missing. i do understand that Arduino is mainly for dummies like myself and that no one takes it to seriously.

i really need to be able to change SD cards so would appreciate any hacks that others can think of to allow it. if i reboot the controller, all is fine after an sd card change. is it possible to do a soft reboot from the program? every time the card needs to be changed, parameters can be cached in on volatile memory and the program re-booted?

or does anyone plan on adding a reset or end function to the SD library or have any suggestions on how to do that?


nik999389

Wed, 20 Jun 2012 18:09:08 +0000

This can be done, the only thing is that the variables your trying to store on the uno32 are not always going to stay on there after a reset. Look at this thread:

[url]http://www.chipkit.org/forum/viewtopic.php?f=19&t=1413[/url]

Other than that you can set up an interrupt to toggle the reset pin on the processor itself. That is proven to work. Try it out, see what you can do and let us know how it goes.


spencoid

Wed, 20 Jun 2012 18:42:16 +0000

can't you write to flash memory on the uno? no problem adding external eeprom other than trying to find enough lines. i guess i would just need one more select line for the eeprom but i am sort of out of lines already.

is there a software reset that can be done from an interrupt or are you suggesting connecting a digital output to the reset line? i am also pretty much out of interrupt lines so would prefer to reset from within the program loop.


nik999389

Wed, 20 Jun 2012 20:20:55 +0000

You should be able to but as the thread above suggests there are some limitation that you should be aware of. Also sparkfun sells 256kb of eeprom that you can communicate with using I2C.

[url]http://www.sparkfun.com/products/525[/url]

As for the reset; Yes, I was suggesting hooking up an output pin to the reset line, You don't have to do it through an interrupt but you would have to find an efficient way of telling when the SD card is no more, then save you values and reset.

What exactly are you trying to make?


spencoid

Wed, 20 Jun 2012 20:45:18 +0000

trying to read an sd card that has been removed returns an error. i can make this do the reboot. just have to find another pin. i assume the reset pin goes low for a reset.

pinMode(8, OUTPUT; digitalWrite(8, HIGH);

myFile = SD.open("test.txt"); if (myFile) { myFile.seek(0); Serial.println("file opened");
} else{ Serial.println("re-booting controller"); digitalWrite(8, LOW); // connected to reset pin }

i probably can get by with no caching of data. the user needs to know that position information will be lost if the card is changed.

i am making a motor control system that lets you record motion on the pc using the mouse and then save the file to the sd card so the machine can play back the recorded motion. i am using servos with encoders and will eventually write the record program for the microcontroller so i can monitor the motion while recording it all on the machine. want to get it all working before i write the recorder in arduino because i am much better at perl.


rasmadrak

Thu, 21 Jun 2012 09:34:50 +0000

It should be possible to re-run the constructor of the "SD", but I have not investigated this further. Anyone?


spencoid

Thu, 21 Jun 2012 14:17:29 +0000

by "re-run the constructor of the "SD"" do you mean "SD.begin" ? that doesn't work, it returns an error if the card had been removed after it was initialized previously. i think someone needs to write a de-constructor".


nik999389

Thu, 21 Jun 2012 14:28:33 +0000

I agree, there needs to be a way to stop the interaction between the SD card to free up space on the SPI bus and also to be able to add and remove SD cards on the go.

But anyways, did that script end up working for you? if not I found a good way to reset your program (not the whole chip), but that might be just what you need because I don't think it clears the cache or anything just starts the program over.

void(* resetFunc) (void) = 0; //declare reset function @ address 0 ... resetFunc(); //call reset ...

Try this and let me know if it works


spencoid

Thu, 21 Jun 2012 15:17:52 +0000

definitely does not work. running this reset function screws the program up completely making it difficult to even reload a new program.

i am OK with the reset line approach until they write a decent SD library with a release function.


nik999389

Fri, 22 Jun 2012 15:18:00 +0000

Ok well, sorry for the bad code. The only problem with the hardware reset is that as soon as you reset the uC the first thing it does is set all the pins to inputs and therefore terminating the reset process... Is this happening to you?


spencoid

Fri, 22 Jun 2012 18:19:04 +0000

no, it does complete the reset and the main loop starts right up again.

i will have to put a bunch of waits in the program when an attempt is made to read the card after swapping so the user is warned that the system will reboot instead of just doing it automatically??? of course, the user might not be watching. this is all going to be a real pain to try to figure out how to advise the user and have things happen pretty much automatically. would sure be easier if they just fixed the library and added some decent functionality.

ANY PLANS TO DO THIS CHIPKIT PEOPLE????????


rasmadrak

Sat, 23 Jun 2012 21:34:14 +0000

The problem isn't actually Digilent's, they're basing their library of the Arduino one - which in turn is based on a several year old version of the SDFat library.

If my wishes were granted I would like to see the following "setup":

SDCard card1; card1.begin(10); //pin 10 card1.open("somefile"); card1.write("writing text to file"); //lots of different writes card1.read(...); //lots of different read-functions, i.e until newline, number of bytes etc card1.close(); //closes the current file card1.begin(10); //forces a reinit of the card, or if you prefer - card1.init(); //forces a reinit of the card card1.end(); //releases any card info and destroys 'card1'

It should also be possible to have SDCard card1, something2, anothercard3 etc. I realize that the SD-wrapper is made to be simple, but it's severely lacking in terms on functionality.

If (or when) a library rewrite is being made - please think of the humble functions above. Thanks!


rasmadrak

Sat, 23 Jun 2012 21:39:06 +0000

By the way,

Is it possible to run "SDClass SD" manually, i.e "SDClass SD2; SDClass SDSomething;" ... ? I have not checked this myself and is unable to at the moment, but unless the SDClass uses a lot of other global variables it should work to create the SD card when needed and destroy/re-create after a swap.

Detecting the card swap is simple enough (read the card state pin) so if this works it should be a walk in the park.

A lot of IF's! :)


Edit:

The "file.cpp" seems to need a rewrite to support other variables than the global SD, but it should be simple enough.


EmbeddedMan

Sun, 24 Jun 2012 05:17:27 +0000

Also note that with microSD you don't normally have a card detect line. And most SD card connectors that I've seen on shields don't bring out the card detect line. So you have to do the eject/reinsert detection in software, probably by pinging the card once a second or so to see if its still there.

*Brian


spencoid

Sun, 24 Jun 2012 18:59:33 +0000

but the problem still remains that you can't re-establish an SD card connection without rebooting the program, at least with the current SD card library.

are you proposing something that might get around this? so, you ping the card with an interrupt timer and get some results as to whether the card is there or not but what do you do to allow it to be read?

i would like a complete solution to hot swapping of SD cards. is this just not possible without a re-write of the SD card library?

is this in the works? i would think that most of the SD card users doing data logging etc would want this funtionality?


rasmadrak

Sun, 24 Jun 2012 20:29:52 +0000

Hmm.. The SD-card module I'm using is a regular SD-card one, so there's a CD-pin available. As for the pure microSD ones - I have no clue. According to this site [url]http://www.interfacebus.com/MicroSD_Card_Pinout.html[/url], a card detect pin should be available on pin #2. EDIT: Apparently, it's only present when in 4-bit mode, not in 1-bit (SPI) mode which we're talking about. Bummer.

Global variables is a big no-no in my world... :) So I'm actually thinking about remaking the current SD card wrapper library someday to support better handling of multiple/non static cards, but time is limited at the moment. I'm currently redesigning the electronics in my pinball machine to be an all-Chipkit one instead of a Chipkit/Arduino hybrid, and besides that my daughter takes the rest of my time...

When the SD card library once again becomes a priority for my project I'll look in to it, however.


Verdris

Wed, 27 Jun 2012 19:23:41 +0000

Could you rig a pushbutton as an external interrupt and have that routine call SD.begin(pin) again? Then just swap cards, push button, and go.


spencoid

Wed, 27 Jun 2012 19:51:34 +0000

first, i have no available interrupts, all used for other important functions but could double up with some status flags to run different code.

however, running sd. begin does not seem to work from any other part of the code if the card was removed. are you saying that it will work only if run from an interrupt routine? i am almost sure i tried including sd.begin from within other interrupt routines and it did not work.

can you provide a simple tested sketch that will demonstrate the hot swapping of SD cards?


rasmadrak

Thu, 28 Jun 2012 11:19:50 +0000

The problem is that there's no end() function. The begin function (or some subpart of it) will not reinitialize itself but rather return right away causing begin() to fail.

If you would copy the SD card from an identical card to another in raw, then the SD.begin() would probably work since all the pointers and internal variables would still be valid. With a new card there's no valid pointers to card data.

As I said before - the SD card wrapper is a statically created (global) variable. The subfunctions to close each of it's subparts are probably already there, but the wrapper doesn't use them. It is intentionally designed to function this way.