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
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!
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.
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 :
/*************************************************************************
* //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
the code i use
That is only a small snippet from the code that you use. Post all of it.
if (SpeedStr.toInt()==0){
This suggests that you are using the String class.
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
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.
well that is my code
/* 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;}
}
That code does not compile.
Pete
i had to dlete parts because it woos too big for the forum
part 1 from code
/*
* 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;
}
}
}
}
Add the code tags
Pete
my code part 2
}
/*************************************************************************
* //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 ;
}
Add code tags to your message #9. Just highlight all the code and hit the </> icon.
Pete
Not related to your issue - I would recommend you to use double with your float calcs.
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
Electrical systems in cars are extremely noisy and can destroy unprotected electronics.
Post a wiring diagram.
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
i'll be more thankful if you send a link about the C strings or an example
and how does a ram problem destroy the SD card hardware that it become unformattable
What kind of cardreader do you use with the Arduino?
SD cards are 3.3V; using 5V power and signals can damage it after a while.
Thank you all for your answers
i think a very helping site is :>