Go Down

Topic: SD card destroyed (Read 1 time) previous topic - next topic

fidamon

i made an arduino controlled GPS that writes to a file on SD card every 30 seconds my cars position
the problem is when i keep it working for more than 2 hours the Sd card is destroyed
on shorter drives (half an hour) it works properly
any hint ??
thank you

diogotec

What do you mean "the SD card is destroyed"?
Also, give us more insight on what SD-card module u are using, the code you are using to save the data, etc!

Nick_Pyner

It probably isn't. You either have a code problem, like use of Strings or something, or English is not your main language. Either way, the SD is almost certainly innocent.

fidamon

thanks for your replies
yes english  is not my first language
what i mean by SD card is destroyed : when i try to read  the file on it i get the message "this drive needs to be formatted " and it can't be formatted
the code i use :
Code: [Select]


/*************************************************************************
 * //Function to write to File
 *************************************************************************/
void filereg(  ) {
  myFile = SD.open("history.txt", FILE_WRITE);
  Serial.println(RawStr);
     prevCompass = compassVal;

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to history.txt...");
    myFile.println(RawStr);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening history.txt");
  }
  if (SpeedStr.toInt()==0){
  writecount = -3000;}
  else {  writecount = 0;}
}


notice when i use it for a short while no broplem , the problem happens in long distance
and i am sure the SD card is inoccent
thanks again

el_supremo

Quote
the code i use
That is only a small snippet from the code that you use. Post all of it.

Code: [Select]
  if (SpeedStr.toInt()==0){
This suggests that you are using the String class.

Quote
notice when i use it for a short while no broplem
That is a common symptom of running out of ram. Using the String class (as has been mentioned) is often a problem.

But unless you post all your code, we're all just guessing.

Pete
Don't send me technical questions via Private Message.

Nick_Pyner

Have you checked
http://forum.arduino.cc/index.php?topic=228201.0
?

Get rid of Strings. A simple myfile.print(variable); usually suffices and will run for as long as there is space on  the card.

fidamon

well that is my code
Code: [Select]

 
 /* SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 10
 */



#include <SPI.h>
#include <SD.h>

#include <LiquidCrystal.h>
#include <string.h>
#include <ctype.h>
//#include <SoftwareSerial.h>
// initialize the library with the numbers of the interface pins

//SoftwareSerial mySerial(2, 3); // RX, TX
//LiquidCrystal lcd(12, 13, A0, A1, A2, A3);
LiquidCrystal lcd(18, 19, 14, 15, 16, 17);

bool    cardfound = false;
File    myFile;
int     writecount = 0;
char    linea[250] = " ";
int     prevCompass = 0;
int     compassVal = 0;
int     cont = 0;
int     conta = 0;
int     indices[13];
String  RawStr = "";
//String  filenam = "";
String  Hstr = "$GPRMC";
String  LatStr = "";
String  TimeStr = "";
String  SpeedStr = "";
String  compastr = "";
String  LonStr = "";
String  OKStr =  "";
/*************************************************************************
 * //setup
 *************************************************************************/
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  Serial.begin(9600);
  //mySerial.begin(9600);

  /*******************************************************************/
  pinMode(9, OUTPUT);
  digitalWrite(9 , HIGH);
  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    LCDKP( 0 , 0 , "initialization  "  , true );
    LCDKP( 0 , 1 , "failed! "  , false );

    return;
  }
  //  Serial.println(cardfound );
else {
  Serial.println("initialization done.");
  cardfound = true ;
  LCDKP( 0 , 0 , "Memory initiated" , true );
  LCDKP( 0 , 1 , "Fidamon Systems" , false );
}
/***********press button to change display***************************/
  pinMode(7, OUTPUT);
 digitalWrite(7 , HIGH);
 pinMode(5, OUTPUT);
 digitalWrite(5 , LOW);
 pinMode(6, INPUT);

  /******************************************************************
 // re-open the file for reading:
  myFile = SD.open("history.txt");
//  myFile = SD.open(filenam);
  if (myFile) {
    Serial.println("history.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 history.txt");
  }
 
}

void loop() {
  if (digitalRead(6) == LOW) { writecount=131;  }
// if (mySerial.available()) {
   if (Serial.available()) {
   //   Serial.write(mySerial.read());
 //   linea[conta] = mySerial.read();      // If there is serial port data, it is put in the buffer
     linea[conta] = Serial.read();      // If there is serial port data, it is put in the buffer
   conta++;

    if (linea[conta - 1] == 13) {       // If the received byte is = to 13, end of transmission
      RawStr = String(linea);

      // note: the actual end of transmission is <CR><LF> (i.e. 0x13 0x10)
      //Serial.println("");
      Hstr = RawStr.substring(1, 7);
      cont = 0;
      conta = 0;
      //  bien = 0;

    }

    if (Hstr == "$GPRMC") {

      for (int i = 0; i < 250; i++) {
        indices[cont] = 0;
        if (linea[i] == ',') { // check for the position of the  "," separator
          // note: again, there is a potential buffer overflow here!
          indices[cont] = i;
          cont++;
        }
        if (linea[i] == '*') { // ... and the "*"
          indices[12] = i;
          cont++;
          i = 301;
        }
      }
           RawStr = RawStr.substring(1, indices[12] + 2);

      RawStr.trim();
      TimeStr = RawStr.substring(indices[0], indices[1]);
      OKStr = RawStr.substring(indices[1], indices[2] - 1);
      LatStr = RawStr.substring(indices[2]  , indices[4]-1);

      LonStr = RawStr.substring(indices[4] , indices[6]-1);

      SpeedStr = RawStr.substring(indices[6], indices[7]);
      compastr = RawStr.substring(indices[7], indices[8]);
        TimeStr = loctime(TimeStr, LonStr) ;
    compassVal=compastr.toInt();
//       if (abs(prevCompass - compassVal)>45){writecount=231;}
      compastr =directionS (compassVal);
      SpeedStr = String(speedkph(SpeedStr.toFloat()));
      if (SpeedStr.toInt()>0){
      if (writecount<0){  writecount += 3000;}}
         RawStr = RawStr.substring(indices[8] , indices[9]-1);
RawStr =  TimeStr + "," + OKStr + "," + LatStr + "," + LonStr  + "," + SpeedStr  + "," + compastr  + "," + RawStr   + "," +  writecount ;
      writecount += 1;
      if (writecount > 30)      {  filereg( );      }

   switch (writecount) {

      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
             LCDKP( 0 , 0 , "Lon " + LonStr , true );
                LCDKP( 0 , 1 , "Lat  " +  LatStr , false );
             LCDKP( 3 , 1 ,   OKStr , false );
        break;
        default:
      LCDKP( 0 , 0 , "Tim " + TimeStr , true );
       LCDKP( 14 , 0 ,  String( writecount) , false );
      LCDKP( 15 , 0 ,   OKStr , false );
     LCDKP( 0 , 1 , "Spd " +  SpeedStr  + " "  +  compastr , false );
           break;  }

      Hstr = "";
      for (int i = 0; i < 250; i++) { //
        linea[i] = 0;
      }
    }

  }
}
/*************************************************************************
 * //Function to werite to LCD
 *************************************************************************/
void LCDKP(int col , int row, String prntstr , boolean cls ) {
  if (cls == true) {
    lcd.clear();
  }

  lcd.setCursor(col, row);
  lcd.print(prntstr);


}
/*************************************************************************
 * //Function to calculate the speed in Kilometer per hour
 *************************************************************************/
float speedkph(float knots)
{
  float kmfactor = 0.556;
  float kmphour = 0;
  kmphour = knots / kmfactor;
  return kmphour;




/*************************************************************************
 * //Function to write to File
 *************************************************************************/
void filereg(  ) {
  myFile = SD.open("history.txt", FILE_WRITE);
  Serial.println(RawStr);
     prevCompass = compassVal;

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to history.txt...");
    myFile.println(RawStr);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening history.txt");
  }
  if (SpeedStr.toInt()==0){
  writecount = -3000;}
  else {  writecount = 0;}
}

el_supremo

That code does not compile.

Pete
Don't send me technical questions via Private Message.

fidamon

i had to  dlete parts because  it woos too big for the forum

fidamon

#9
Aug 04, 2017, 05:57 pm Last Edit: Aug 04, 2017, 06:59 pm by fidamon
part 1 from code

Code: [Select]
/*
* LCD RS pin to       pin A4
* LCD Enable pin to   pin A5
* LCD D4 pin to       pin A3
* LCD D5 pin to       pin A2
* LCD D6 pin to       pin A1
* LCD D7 pin to       pin A0
* LCD R/W pin to ground
* 10K resistor:
* ends to Vin and ground
* wiper to LCD VO pin (pin 3)

Example code for connecting a Parallax GPS module to the Arduino

Listen for the $GPRMC string and extract the GPS location data from this.
Display the result in the Arduino's serial monitor.

* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 10
*/



#include <SPI.h>
#include <SD.h>

#include <LiquidCrystal.h>
#include <string.h>
#include <ctype.h>
//#include <SoftwareSerial.h>
// initialize the library with the numbers of the interface pins

//SoftwareSerial mySerial(2, 3); // RX, TX
//LiquidCrystal lcd(12, 13, A0, A1, A2, A3);
LiquidCrystal lcd(18, 19, 14, 15, 16, 17);

bool    cardfound = false;
File    myFile;
int     writecount = 0;
char    linea[250] = " ";
int     prevCompass = 0;
int     compassVal = 0;
int     cont = 0;
int     conta = 0;
int     indices[13];
String  RawStr = "";
//String  filenam = "";
String  Hstr = "$GPRMC";
String  LatStr = "";
String  TimeStr = "";
String  SpeedStr = "";
String  compastr = "";
String  LonStr = "";
String  OKStr =  "";
/*************************************************************************
* //setup
*************************************************************************/
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);

Serial.begin(9600);
//mySerial.begin(9600);

/*******************************************************************/
pinMode(9, OUTPUT);
digitalWrite(9 , HIGH);
Serial.print("Initializing SD card...");

if (!SD.begin(10)) {
 Serial.println("initialization failed!");
 LCDKP( 0 , 0 , "initialization  "  , true );
 LCDKP( 0 , 1 , "failed! "  , false );

 return;
}
//  Serial.println(cardfound );
else {
Serial.println("initialization done.");
cardfound = true ;
LCDKP( 0 , 0 , "Memory initiated" , true );
LCDKP( 0 , 1 , "Fidamon Systems" , false );
}
/***********press button to change display***************************/
pinMode(7, OUTPUT);
digitalWrite(7 , HIGH);
pinMode(5, OUTPUT);
digitalWrite(5 , LOW);
pinMode(6, INPUT);

/******************************************************************
// re-open the file for reading:
myFile = SD.open("history.txt");
//  myFile = SD.open(filenam);
if (myFile) {
 Serial.println("history.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 history.txt");
}
/*******************************************************************/

}

/*************************************************************************
* //loop
*************************************************************************/
void loop() {
if (digitalRead(6) == LOW) { writecount=131;  }
// if (mySerial.available()) {
if (Serial.available()) {
//   Serial.write(mySerial.read());
//   linea[conta] = mySerial.read();      // If there is serial port data, it is put in the buffer
  linea[conta] = Serial.read();      // If there is serial port data, it is put in the buffer
conta++;

 if (linea[conta - 1] == 13) {       // If the received byte is = to 13, end of transmission
   RawStr = String(linea);

   // note: the actual end of transmission is <CR><LF> (i.e. 0x13 0x10)
   //Serial.println("");
   Hstr = RawStr.substring(1, 7);
   cont = 0;
   conta = 0;
   //  bien = 0;

 }

 if (Hstr == "$GPRMC") {

   // check for the position of the  "," separator*******************************************************
   for (int i = 0; i < 250; i++) {
     indices[cont] = 0;
     if (linea[i] == ',') { // check for the position of the  "," separator
       // note: again, there is a potential buffer overflow here!
       indices[cont] = i;
       cont++;
     }
     if (linea[i] == '*') { // ... and the "*"
       indices[12] = i;
       cont++;
       i = 301;
     }
   }
   //*******************************************************************************************************
   RawStr = RawStr.substring(1, indices[12] + 2);

   RawStr.trim();
   TimeStr = RawStr.substring(indices[0], indices[1]);
   OKStr = RawStr.substring(indices[1], indices[2] - 1);
   LatStr = RawStr.substring(indices[2]  , indices[4]-1);
//      LatStr =MintoDec("0"+LatStr );
   LonStr = RawStr.substring(indices[4] , indices[6]-1);
//      LonStr =MintoDec(LonStr );
   SpeedStr = RawStr.substring(indices[6], indices[7]);
   compastr = RawStr.substring(indices[7], indices[8]);
  // filenam = RawStr.substring(indices[8] , indices[9]-1);
  // filenam =filenam + ".txt";
   TimeStr = loctime(TimeStr, LonStr) ;
 compassVal=compastr.toInt();
//       if (abs(prevCompass - compassVal)>45){writecount=231;}
   compastr =directionS (compassVal);
   SpeedStr = String(speedkph(SpeedStr.toFloat()));
   if (SpeedStr.toInt()>0){
   if (writecount<0){  writecount += 3000;}}
      RawStr = RawStr.substring(indices[8] , indices[9]-1);
RawStr =  TimeStr + "," + OKStr + "," + LatStr + "," + LonStr  + "," + SpeedStr  + "," + compastr  + "," + RawStr   + "," +  writecount ;
   writecount += 1;
   if (writecount > 30)      {  filereg( );      }

switch (writecount) {

   case 2:
   case 3:
   case 4:
   case 5:
   case 6:
          LCDKP( 0 , 0 , "Lon " + LonStr , true );
             LCDKP( 0 , 1 , "Lat  " +  LatStr , false );
          LCDKP( 3 , 1 ,   OKStr , false );
     break;
     default:
   LCDKP( 0 , 0 , "Tim " + TimeStr , true );
    LCDKP( 14 , 0 ,  String( writecount) , false );
   LCDKP( 15 , 0 ,   OKStr , false );
  LCDKP( 0 , 1 , "Spd " +  SpeedStr  + " "  +  compastr , false );
        break;  }

   Hstr = "";
   for (int i = 0; i < 250; i++) { //
     linea[i] = 0;
   }
 }

}
}

el_supremo

Add the code tags

Pete
Don't send me technical questions via Private Message.

fidamon

my code part 2

Code: [Select]

}
/*************************************************************************
 * //Function to werite to LCD
 *************************************************************************/
void LCDKP(int col , int row, String prntstr , boolean cls ) {
  if (cls == true) {
    lcd.clear();
  }

  lcd.setCursor(col, row);
  lcd.print(prntstr);


}
/*************************************************************************
 * //Function to calculate the distance between two waypoints
 *************************************************************************/
float calc_dist(float flat1, float flon1, float flat2, float flon2)
{
  float dist_calc = 0;
  float dist_calc2 = 0;
  float diflat = 0;
  float diflon = 0;

  //I've to spplit all the calculation in several steps. If i try to do it in a single line the arduino will explode.
  diflat = radians(flat2 - flat1);
  flat1 = radians(flat1);
  flat2 = radians(flat2);
  diflon = radians((flon2) - (flon1));

  dist_calc = (sin(diflat / 2.0) * sin(diflat / 2.0));
  dist_calc2 = cos(flat1);
  dist_calc2 *= cos(flat2);
  dist_calc2 *= sin(diflon / 2.0);
  dist_calc2 *= sin(diflon / 2.0);
  dist_calc += dist_calc2;

  dist_calc = (2 * atan2(sqrt(dist_calc), sqrt(1.0 - dist_calc)));

  dist_calc *= 6371000.0; //Converting to meters
  return dist_calc;
}
/*************************************************************************
 * //Function to calculate the speed in Kilometer per hour
 *************************************************************************/
float speedkph(float knots)
{
  float kmfactor = 0.556;
  float kmphour = 0;
  kmphour = knots / kmfactor;
  return kmphour;
}
/*************************************************************************
 * //Function to calculate the local time
 *************************************************************************/
String loctime(String gpsTime, String lonstr)
{
  String mytime = "";
  int hrs = 0;
  int mnts = 0;
  int scnds = 0;
  int grntsh = 0;

  hrs = gpsTime.substring(0, 2).toInt();
  mnts = gpsTime.substring(2, 4).toInt();
  scnds = gpsTime.substring(4, 6).toInt();
  grntsh = lonstr.substring(0, 3).toInt();
  grntsh *= 4;
  mnts += grntsh;
  grntsh = mnts / 60 ;
  mnts %= 60;
  hrs += grntsh;
  if (hrs > 23)
  {
    hrs -= 24;
  }
  if (hrs > 12)
  {
    hrs -= 12;
  }
  if (hrs < 10)
  {
    mytime =  "0";
  }
  mytime = mytime + String(hrs) + ":";
  if (mnts < 10)
  {
    mytime = mytime + "0";
  }
  mytime = mytime + String(mnts) + ":";
  if (scnds < 10)
  {
    mytime = mytime + "0";
  }
  mytime = mytime + String(scnds);

  return mytime;
}
/*************************************************************************
 * //Function to calculate the cheksum
 ************************************************************************

String cheskStr (String rawstr)
{
  int checksum = 0 ;
  for (int i = indices[0]; i < indices[12]; i++) {

    //     checksum = checksum Xor Convert.ToByte(Character)
  }
}*/
/*************************************************************************
  //Function to calculate Direction
*************************************************************************/

String directionS (int compassa)
{
  String mydirect = "";
  if (compassa > 357) {
    mydirect = "N";
  }
  else {
    if (compassa > 315) {
      mydirect = "N " + String(360 - compassa) + " W" ;
    }
    else {
      if (compassa > 272) {
        mydirect = "W " + String( compassa - 270) + " N" ;
      }
      else {
        if (compassa > 268) {
          mydirect = "W "  ;
        }
        else {
          if (compassa > 225) {
            mydirect = "W " + String(270 - compassa) + " S" ;
          }
          else {
            if (compassa > 182) {
              mydirect = "S " + String( compassa - 180) + " W" ;
            }
            else {
              if (compassa > 178) {
                mydirect = "S " ;
              }
              else {
                if (compassa > 135) {
                  mydirect = "S " + String(180 - compassa) + " E" ;
                }
                else {
                  if (compassa > 92) {
                    mydirect = "E " + String( compassa - 90) + " S" ;
                  }
                  else {
                    if (compassa > 88) {
                      mydirect = "E ";
                    }
                    else {
                      if (compassa > 45) {
                        mydirect = "E " + String(90 - compassa) + " N" ;
                      }
                      else {
                        if (compassa > 2) {
                          mydirect = "N " + String(  compassa) + " E" ;
                        }
                        else {

                          mydirect = "N ";

                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }



  return mydirect;
}





/*************************************************************************
 * //Function to write to File
 *************************************************************************/
void filereg(  ) {
  myFile = SD.open("history.txt", FILE_WRITE);
  Serial.println(RawStr);
     prevCompass = compassVal;

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to history.txt...");
    myFile.println(RawStr);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening history.txt");
  }
  if (SpeedStr.toInt()==0){
  writecount = -3000;}
  else {  writecount = 0;}
}
/*************************************************************************
 * //Function to Convert from degres minutes to decimal 
 *************************************************************************/
String MintoDec(String xx   ) 
{
  String ss= xx;
int intVal= ss.toInt();

ss.replace(".", "");
intVal =intVal /100 ;
ss =ss.substring(3);
ss.trim() ;
int MinVal= ss.toInt();
 
MinVal = MinVal * 100 / 60;
ss =String(intVal)+ "." + String(MinVal) ;


return  ss ;
}


el_supremo

Add code tags to your message #9. Just highlight all the code and hit the </> icon.

Pete
Don't send me technical questions via Private Message.

pito

Not related to your issue - I would recommend you to use double with your float calcs.

el_supremo

In part 1 of your code there is an extra }. Delete the } at the end of that file.
If you are using a NANO or UNO or similar, I suspect that your use of the String class is causing the problem.
Change all uses of the String class to C strings and it should solve the problem.

Pete
Don't send me technical questions via Private Message.

Go Up