232 to SPI losing data.

Hi,

I have a 232 connection converted to ttl coming into my arduino uno serial rx and tx.

This then prints to a file on my microsd shield. The text i send to the microSD shield is 100 bytes long. This works fine if i am using the speed of 4800. Whenever I try to use 9600 I seem to lose data. Can anyone tell me why this is and how I can overcome it?

The code im using:

//Used for string manipulations
#include <string.h>         
//Add the SdFat Libraries
#include <SdFat.h>
#include <SdFatUtil.h> 
#include <ctype.h>

//command prefix - control z asci character
#define cntrlZ  0x1A   

//Will hold the incoming character from the Serial Port.
char incoming_char=0;      

//variables for storing characters to send to SD card
char textToSend[11];
int index = 0;

//Create the variables to be used by SdFat Library
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

void setup()
{
  //Initialize serial ports for communication.
  Serial.begin(9600);
    
  pinMode(10, OUTPUT);       //Pin 10 must be set as an output for the SD communication to work.
  card.init();               //Initialize the SD card and configure the I/O pins.
  volume.init(card);         //Initialize a volume on the SD card.
  root.openRoot(volume);     //Open the root directory in the volume. 
}

void loop() 
{ 
  //If a character is coming from the terminal to the Arduino.
  if(Serial.available() >0)
  {

    incoming_char=Serial.read();  //Get the character coming from the terminal
    textToSend[index] = incoming_char;
    ++index;
    
    if(index == 10)
    {      
      file.open(root, "590.txt", O_CREAT | O_APPEND | O_WRITE);    //Open or create the file 'name' in 'root' for writing to the end of the file.
      file.print(textToSend);    //Write the 'contents' array to the end of the file.
      file.close();            //Close the file.
      index = 0;
    }   
  } 
}

Sorry, 100kb of data.

This works fine if i am using the speed of 4800. Whenever I try to use 9600 I seem to lose data.

Coming in from where? Perhaps whatever is sending the data can't cope with the higher speed.

      file.print(textToSend);    //Write the 'contents' array to the end of the file.

The overload of the print() function that accepts a char array expects the array to be NULL terminated. Yours is not, potentially writing garbage to the file.

The text i send to the microSD shield is 100 bytes long.

Sorry, 100kb of data.

It is neither one. You are writing 10 bytes at a time. That is the critical (and problematic) value.

Opening a file on an SD card, writing to it, and closing it takes time. Writing 10 bytes or 100 bytes or 1000 bytes is not the time consumer. It is the opening and closing the file. Try a larger array size, and write more data each time the file is opened.

Coming in from where?

Sorry, let me clear it up a bit.

I have an rs232 connection from my computer at 9600 to my arduinos (uno) serial connection. The computer then sends 100 kb's. I would like to store this 100kb straight to my SD shield. There is no flow control (out of my control) between the computer sending the data and the uno.

The overload of the print() function that accepts a char array expects the array to be NULL terminated.

Good point I will fix that up.

Opening a file on an SD card, writing to it, and closing it takes time. Writing 10 bytes or 100 bytes or 1000 bytes is not the time consumer. It is the opening and closing the file. Try a larger array size, and write more data each time the file is opened.

Ok will run some simple tests.

Thanks for the feedback.

ok, so i got it working (with some help, thanks paul).

Basically, I removed the open and close to the start and end of the sketch and also increased the size of the array of data being sent to the SPI.

If you make the textToSend in the sketch less than say, 150 bytes, you start to see some strange behaviour, I dont really understand why increasing the data seems to eliminate data loss and would love if someone could explain it to me.

Here is a working sketch that recieves up to 100kb from rs232 (put through a max 220 to TTL converter) and saves it to a micro SD card. The only thing left to do is clear up the array before closing the file, as the end of the array will contain garbage.

//Used for string manipulations
#include <string.h>         
//Add the SdFat Libraries
#include <SdFat.h>
#include <SdFatUtil.h> 
#include <ctype.h>

//command prefix - control z asci character
#define cntrlZ  0x1A   

//Will hold the incoming character from the Serial Port.
char incoming_char=0;      

//variables for storing characters to send to SD card
char textToSend[201];
char xmlData[8];
int index = 0;

//Create the variables to be used by SdFat Library
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

void setup()
{
  //Initialize serial ports for communication.
  Serial.begin(9600);
  
//  textToSend[101] = null;
//  xmlData[8] = null;
  
  pinMode(10, OUTPUT);       //Pin 10 must be set as an output for the SD communication to work.
  card.init();               //Initialize the SD card and configure the I/O pins.
  volume.init(card);         //Initialize a volume on the SD card.
  root.openRoot(volume);     //Open the root directory in the volume.
  Serial.println("Opening file...");      
  file.open(root, "590.txt", O_CREAT | O_APPEND | O_WRITE);    //Open or create the file 'name' in 'root' for writing to the end of the file. 
  Serial.println("File opened!");      
}

void loop() 
{ 
  //If a character is coming from the terminal to the Arduino.
  if(Serial.available() >0)
  {

    incoming_char=Serial.read();  //Get the character coming from the terminal
    //searching for end of file
    xmlData[0] = xmlData[1];
    xmlData[1] = xmlData[2];
    xmlData[2] = xmlData[3];
    xmlData[3] = xmlData[4];
    xmlData[4] = xmlData[5];
    xmlData[5] = xmlData[6];
    xmlData[6] = incoming_char;
    
    //Serial.println("XML Data: ");
    //Serial.print(xmlData);
    String endOfFile = xmlData;
    
    textToSend[index] = incoming_char;
    
    ++index;
    
    if(index == 200)
    {
      //Serial.println("Reached 100 writing to file");      
      file.print(textToSend);    //Write the 'contents' array to the end of the file.
      index = 0;
    }   
    if (endOfFile.indexOf("</data>") > -1)
    {
      file.print(textToSend);    //Write the 'contents' array to the end of the file.
      delay(500);
      file.close();            //Close the file.
      index = 0;
      Serial.println("Closed file");      
    }
  } 
}