Go Down

Topic: SdFat writes weird stuff to binary on SD (Read 767 times) previous topic - next topic

Bi0H4z4rD

Jan 26, 2013, 07:37 pm Last Edit: Jan 26, 2013, 08:00 pm by Bi0H4z4rD Reason: 1
I had a code that ran with standard SD library fine, which would write all binary bytes read on serial to a file on sd. The sketch for the function was:

Code: [Select]
   
//SDcounter is the number of bytes stored in buffer
byte SDbuffer[512];//Buffer to be saved on SD
int sdloop=0;
   while (sdloop < SDcounter){
   myFile.write(SDbuffer[sdloop]);
  sdloop++;
   }


Then i upgraded to SdFat and tried with the same function, but it writes the file with the correct size, but the data in it is completely wrong.

And if i try this:

Code: [Select]
myFile.write(SDbuffer, SDcounter);

it will print a file full of "0x00, 0x33, 0x00, 0x33.......".

Could someone please give a hand to let me know what am i doing wrong?

BR

PaulS

Quote
Could someone please give a hand to let me know what am i doing wrong?

Sorry, no. Perhaps you could take those snippets over to snippets-r-us.com. Here, we need to see all of your code.

Bi0H4z4rD

#2
Jan 27, 2013, 01:31 am Last Edit: Jan 27, 2013, 01:58 pm by Bi0H4z4rD Reason: 1
original code:

Code: [Select]
byte SDbuffer[512];//Buffer to be saved on SD
word SDcounter=0;//counter to know how many bytes will be written to the SD
#include <SD.h>
File myFile;
byte c;

void error_P(const char* str) {   
  PgmPrint("error: ");   
  SerialPrintln_P(str);   
  if (card.errorCode())
    {     
      PgmPrint("SD error: ");     
      Serial.print(card.errorCode(), HEX);     
      Serial.print(',');     
      Serial.println(card.errorData(), HEX);   
    }   
  while(1);
}

void setup()
{
Serial.begin(115200);
Serial2.begin(9600);
pinMode(53, OUTPUT);
 Serial.println("Initializing SD card...");
 if (!SD.begin(4))
   {
     Serial.println("initialization failed!");
     Serial.println("Please check that SD card is inserted and formatted as FAT16");
     fail=1;
      while (fail){}
   }
myFile = SD.open("log.bin", O_CREAT | O_WRITE);//We do it the fast way
Serial.println("starting to log...");
}

void loop()
{

 while (SDcounter<513)
 {
  while (Serial2.available() < 1)
  {}
  c = Serial2.read();
  SDbuffer[SDcounter]=c;
 SDcounter++;
 }
 int sdloop=0;
 myFile= SD.open("log.bin", FILE_READ);
if (!myFile){
   // if the file didn't open, print an error:
   Serial.println("Error writing to SD card, please check it is not write protected");
   return;
 }

   while (sdloop < SDcounter){
   myFile.write(SDbuffer[sdloop]);
  sdloop++;
   }
   SDcounter=0;
myFile.close();
}


new code:

Code: [Select]
byte SDbuffer[512];//Buffer to be saved on SD
word SDcounter=0;//counter to know how many bytes will be written to the SD
#include <SdFat.h>
#include <SdFatUtil.h>
SdFat SD;
Sd2Card card;
SdVolume volume;
SdFile root;
const uint8_t SD_CHIP_SELECT = 53;
SdFile myFile;
byte SDbufferFlag;
// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

byte c;

void error_P(const char* str) {   
  PgmPrint("error: ");   
  SerialPrintln_P(str);   
  if (card.errorCode())
    {     
      PgmPrint("SD error: ");     
      Serial.print(card.errorCode(), HEX);     
      Serial.print(',');     
      Serial.println(card.errorData(), HEX);   
    }   
  while(1);
}

void setup()
{
Serial.begin(115200);
Serial2.begin(9600);
 Serial.print("Initializing SD card...");
 //SD card INIT
 if (!card.init(SPI_HALF_SPEED)) error("card.init failed");
 // initialize a FAT volume  
 if (!volume.init(&card)) error("volume.init failed");  
 // open the root directory  
 if (!root.openRoot(&volume)) error("openRoot failed");
 Serial.println("Done!");
}

void loop()
{

 while (SDcounter<513)
 {
  while (Serial2.available() < 1)
  {}
  c = Serial2.read();
  SDbuffer[SDcounter]=c;
 SDcounter++;
 }
 int sdloop=0;
 if (!myFile.open(&root,"log.bin", O_RDWR | O_CREAT)) {
   // if the file didn't open, print an error:
   Serial.println("Error writing to SD card, please check it is not write protected");
   return;
 }

   while (sdloop < SDcounter){
   myFile.write(SDbuffer[sdloop]);
  sdloop++;
   }
   SDcounter=0;
myFile.close();
}


BR

PaulS

One thing I'd like to introduce you to is the for statement. The while statement is meant to loop a variable number of times, until some condition becomes true. The for loop is meant to loop a fixed number of times.

There are places you are using a while loop to iterate a fixed number of times. Those would be more intuitive as for loops.

The two blocks of code do not open the file the same way.

In the first code, you open the file in setup(). Then, without closing the file, you try to open the file again in loop (read-only). Then, you write to the file (that you tried to open read-only).

The whole purpose of doing buffered writes to the file is because writing one byte at a time is slow. Writing an entire array at once is faster. You are defeating the purpose of collecting the data in an array if you then write one element of the array to the file at a time.

Bi0H4z4rD

#4
Jan 27, 2013, 03:34 pm Last Edit: Jan 27, 2013, 03:39 pm by Bi0H4z4rD Reason: 1
It was a hardware fault. I just fixed it, and now both codes posted work perfectly with the fix you mention aswell.

Anyway, i am interested on what you mention in writing a byte at a time.

I would really appreciate if you could let me know the correct syntax to write the entire buffer at a time.


BR

Go Up