Pages: [1]   Go Down
Author Topic: Send file to microsd on Arduino UNO with Micro SD shield  (Read 3110 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello! I would like to simply send a file from my pc to the microSD card i have on my microSD shield using the serial connection. I have searched the web for countless hours without learning the way to accomplish this smiley-sad . I have read the basic tutorials that are available for managing the micro SD shield but somehow i still havent learnt what i need to know. Its probably something obvious that i havent understood yet.

Why I would like to send a file?:
 Im working on a school project (hence the nooby question) where i need to send a jpeg file which is created on the pc to the memory card on the micro Sd shield. In the first step of the project i need to be able to do it over the serial connection through the USB cable , and in the later stage of the project sending the file should be done wirelessly (with a wifi shield  including the small antenna).

If anybody can give some directions or point me to a tutorial that shows me have to do this I would highly appreciate it! I am very thankful for any kind of help I can recieve! smiley

Additional info : I have the Arduino UNO board and the sparkfun Micro Sd shield and a 2 gb Micro SD card (properly formatted)  
« Last Edit: May 15, 2012, 07:50:06 am by mullenr1 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Hello! I would like to simply send a file from my pc to the microSD card i have on my microSD shield using the serial connection.
You can't do this directly. You can send data from the PC to the serial port. The Arduino can read serial data. The Arduino can open a file on the SD card. The Arduino can write data to the SD card. The Arduino can close the file on the SD card.

There are examples for reading serial data. There are examples for writing to the SD card.

It is trivial to combine them.

What (Arduino related) part(s) are you having trouble with?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you ! I feel really stupid now when its put so simple smiley But this helps me out alot because i think i imagined it to be more complicated than it has to be.

I guess i cant tell you which part im having trouble with because I havent even been able to get started really. But as I said you have already helped me out alot PaulS by just writing your post smiley.

 I have found some examples and im gonna try to whip up the code I think I need,  and perhaps i can post here again if I run in to trouble? smiley

Thanks alot PaulS!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried combining the following code to achieve what im trying but it didnt go as I planned:

http://arduino.cc/en/Serial/read
http://arduino.cc/en/Tutorial/ReadWrite

my code:
Code:
/*
  SD card read/write
 
 This example shows how to read and write data to and from 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
 updated 2 Dec 2010
 by Tom Igoe
 
 This example code is in the public domain.
     
 */
 
#include <SD.h>

File myFile;
int incomingByte = 0;

void setup()
{
  Serial.begin(9600);
  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.");
 

}

void loop()
{
          // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);
               
               
                 
                 
                 
                 
   // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);
 
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println(incomingByte);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
 
  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
   
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

        }
}
 

Perhaps you can tell me if this is completely wrong or tell me how to make it work because the result of the code above was the following.

I used the "send file" function in a Terminal program (the one i use is called Terra Term) to send a text file that I created on my PC which I want replicated on the micro SD card with the words "Hello! Test" in it.  , and the code created a file test.txt on the micro sd card. But when i inserted it in my memory card reader and opened the file it contained only numbers it did not contain any text (it was supposed to say "Hello! Test" ).

Do you have any advice for me how to replicate the file I have on the computer on the Micro SD card ? Ultimately I want to write to a jpeg file and be able to open the jpeg file on my computer when i insert my memory card   
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
                incomingByte = Serial.read();
What does the Serial.read() function return? Why?

It returns an int, because not everyone is smart enough to check that there is a byte to read before actually reading. Since all values in a byte are legitimate values, the only way to indicate an error condition is two return two bytes, one of which indicates the error.

Since you DO check that there is something to read before doing the read, you only need to allocate ONE byte to hold the output. That byte should be typed as a char.

Code:
    myFile.println(incomingByte);
You want each character written on a separate line? Why?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you very much PaulS ! with your help I finally managed to replicate a textfile from my pc to the arduino+microSD!

But my next question will be how do I manage the same thing with a jpeg file? e.g. how do I copy a jpeg picture from my computer to the arduino sd card?

To get the "textfile sending code" to work I did as you said and changed the file allocation and the type of the incomingByte to a char.
Should this stay the same when i want to send a jpeg file?

And I guess renaming test.txt to "test.jpg" in the following line is a good idea?:
myFile = SD.open("test.jpg", FILE_WRITE);

The latter is what I've already tried but when i Inserted the SD card in my computer it couldn't open and display the picture.

As always I am incredibly thankful for your help!

   
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When sending character data, the data should be typed as a char, and written using the print() method.

When sending binary data, the data should be typed as a byte, and written using the write() method.

Since the only thing that really knows ASCII vs. binary is you, because you can read one but not the other, typing the data as byte and using write() to write to the file will work for both cases, The only difference will be that when you open the files to read them, YOU (not the computer) will only be able to read one of them.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok so I changed the type to Byte and also from print() to write() but I still cant open and display the image on my computer. Perhaps I didnt understand the last part of what you wrote?


My code and how it looks now:
Code:
/*
  SD card read/write
 
 This example shows how to read and write data to and from 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
 updated 2 Dec 2010
 by Tom Igoe
 
 This example code is in the public domain.
     
 */
 
#include <SD.h>

File myFile;
byte incomingByte = 0;

void setup()
{
  Serial.begin(9600);
  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.");
 

}

void loop()
{
          // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);
               
               
                 
                 
                 
                 
   // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.jpg", FILE_WRITE);
 
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.jpg...");
    myFile.write(incomingByte);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.jpg");
  }
 
  // re-open the file for reading:
  myFile = SD.open("test.jpg");
  if (myFile) {
    Serial.println("test.jpg:");
   
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.jpg");
  }

        }
}
 

This is what happens when I try to open the file: (its in swedish but i think you get the idea)
http://i46.tinypic.com/b9isyv.jpg
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Opening and closing the file for each byte is rarely a good idea. Do something like this, instead:
Code:
if(Serial.available() > 0)
{
   // Open the file

   while(Serial.available() > 0)
   {
      incomingByte = Serial.read();
      myFile.write(incomingByte);
   }

   // Close the file
}
It takes time to send the information out the serial port, and to open, find the end of the file, and close the file. It is likely that during that time, data is coming in faster than it can be written to the file, so some gets lost because there is not room in the buffer to hold it.

You've only shown us the code that receives and uses the data. You have not shown us the code that sends the data. Jpeg files can have embedded NULLs. If the sender doesn't send them, or worse, stops when it encounters one, then the received data will not match the source data.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks im gonna try that!

Quote
You have not shown us the code that sends the data

Thats because Im using a function in the Terminal program that I use for sending files. The program is called Terra Term. I hope that it sends the embedded Nulls because writing code to send data is something I have no idea about how to do smiley-sad

this is how what it looks like from my terminal program :
http://i50.tinypic.com/2ronoy9.jpg
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is this how you meant I should write it? :

Code:
/*
  SD card read/write
 
 This example shows how to read and write data to and from 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
 updated 2 Dec 2010
 by Tom Igoe
 
 This example code is in the public domain.
     
 */
 
#include <SD.h>

File myFile;
byte incomingByte = 1;

void setup()
{
  Serial.begin(9600);
  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.");
 

}

void loop()
{
          // send data only when you receive data:
   //     if (Serial.available() > 0)
                // read the incoming byte:
     //           incomingByte = Serial.read();

                // say what you got:
       //         Serial.print("I received: ");
         //       Serial.println(incomingByte, DEC);
               
               


 
  if (Serial.available() > 0) {
    myFile = SD.open("test.jpg", FILE_WRITE);
   
     while(Serial.available() > 0)
   {
     incomingByte = Serial.read();
     myFile.write(incomingByte);
     Serial.print("Writing to test.jpg...");
   
   }
   
    // close the file:
    myFile.close();
    Serial.println("done.");
  // else
    // if the file didn't open, print an error:
    //Serial.println("error opening test.jpg");
  //
 
 
  // re-open the file for reading:
  myFile = SD.open("test.jpg");
  if (myFile) {
    Serial.println("test.jpg:");
   
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.jpg");
  }
 
   }
   
   


        }

 



It still doesnt work though smiley-sad. Any ideas or feedback on the code ?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    while(Serial.available() > 0)
   {
     incomingByte = Serial.read();
     myFile.write(incomingByte);
     Serial.print("Writing to test.jpg...");
    
   }
For every character that you read, you send 22 characters to the serial port. Read one, that's 22 characters sent. Read 2, that's 44 characters sent. Read 3, that's 66 characters sent, and the outgoing buffer is full, so a block might occur, until 3 characters have been sent (which might have happened). Read the 4th character, and you block.

Sending the same message after reading each and every character is, of course, going to cause you problems. In addition to being unnecessary.

Quote
I hope that it sends the embedded Nulls because writing code to send data is something I have no idea about how to do
Reading the documentation should be within your skill set, though. Configuring the software should be, too.

Making assumptions about what the PC software is doing is not a good idea. Dig in, and find out.

Edit: Corrected typo. It might actually be a goof idea; it is not a good idea.
Logged

Pages: [1]   Go Up
Jump to: