Pages: [1]   Go Down
Author Topic: Help with programming - SD card logger stops logging after a while.  (Read 228 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello all.
I am not very familiar with Arduino world however for one my projects I am using arduino UNO with GPS module, Ultrasonic sensor and 3 axis accelerometer (although I am only using one (Z)axis.) From many different programs available on internet I have compiled a working program for the application. It is mostly bits and pieces taken from here and there. The way the program works is it logs one line of GPS NMEA (GPRMS) sentence every second on SD card. Between each teo GPS lines it logs 10 lines of sensors (accelerometer and Ultrasonic Sensor). The program is working okay like this. But after a while it stops logging. I have already ruled out the possibility of bad connection to the power source.

I am attaching my whole code here, see if you can help me with it. Also any other changes which can optimize my program are welcome.

Thank you.
Code:
#include <SD.h>
#include <SoftwareSerial.h>

// power saving modes

#define LOG_RMC_FIXONLY 0    // set to 1 to only log to SD when GPS has a fix
#define SHOW_SERIAL     1    // 0 if no serial view is required i.e. when biking, when connected to computer use 1.
#define SENSOR_FILTER   10   // number of readings to average for filtering
#define SENSOR_READINGS 10   // number of sensor readgins between two GPS readings

/* EXAMPLE

$PSRF103,<msg>,<mode>,<rate>,<cksumEnable>*CKSUM<CR><LF>

<msg> 00=GGA,01=GLL,02=GSA,03=GSV,04=RMC,05=VTG
<mode> 00=SetRate,01=Query
<rate> Output every <rate>seconds, off=00,max=255
<cksumEnable> 00=disable Checksum,01=Enable checksum for specified message
Note: checksum is required

Example 1: Query the GGA message with checksum enabled
$PSRF103,00,01,00,01*25

Example 2: Enable VTG message for a 1Hz constant output with checksum enabled
$PSRF103,05,00,01,01*20

Example 3: Disable VTG message
$PSRF103,05,00,00,01*21

*/
// Following are the configurations for GPS. DO NOT DELETE.
#define SERIAL_SET   "$PSRF100,01,4800,08,01,00*0E\r\n"

#define GGA_ON   "$PSRF103,00,00,01,01*25\r\n"// GGA-Global Positioning System Fixed Data, message 103,00
#define GGA_OFF  "$PSRF103,00,00,00,01*24\r\n"

#define GLL_ON   "$PSRF103,01,00,01,01*26\r\n"// GLL-Geographic Position-Latitude/Longitude, message 103,01
#define GLL_OFF  "$PSRF103,01,00,00,01*27\r\n"

#define GSA_ON   "$PSRF103,02,00,01,01*27\r\n"// GSA-GNSS DOP and Active Satellites, message 103,02
#define GSA_OFF  "$PSRF103,02,00,00,01*26\r\n"

#define GSV_ON   "$PSRF103,03,00,01,01*26\r\n"// GSV-GNSS Satellites in View, message 103,03
#define GSV_OFF  "$PSRF103,03,00,00,01*27\r\n"

#define RMC_ON   "$PSRF103,04,00,01,01*21\r\n"// RMC-Recommended Minimum Specific GNSS Data, message 103,04
#define RMC_OFF  "$PSRF103,04,00,00,01*20\r\n"

#define VTG_ON   "$PSRF103,05,00,01,01*20\r\n"// VTG-Course Over Ground and Ground Speed, message 103,05
#define VTG_OFF  "$PSRF103,05,00,00,01*21\r\n"

#define DDM_ON   "$PSRF105,01*3E\r\n"// Switch Development Data Messages On/Off, message 105
#define DDM_OFF  "$PSRF105,00*3F\r\n"

#define WAAS_ON    "$PSRF151,01*3F\r\n"// useful in US, but slower fix
#define WAAS_OFF   "$PSRF151,00*3E\r\n"


// Use pins 2 and 3 to talk to the GPS. 2 is the TX pin, 3 is the RX pin
SoftwareSerial gpsSerial =  SoftwareSerial(2, 3);
// Set the GPSRATE to the baud rate of the GPS module. Most are 4800
#define GPSRATE 4800


// Set the pins used
#define powerPin 4
#define chipSelect 10


#define BUFFSIZE 90
char buffer[BUFFSIZE];
bool fix = false; // current fix data
bool gotGPRMC;    //true if current data is a GPRMC strinng
uint8_t i;

const int zpin = A2;                  // z-axis
const int Sonarpin = 9;                  // Sonar sensor, PW pin
//char stringSensor[20];
File logfile;

void setup() {
  Serial.begin(9600);
  Serial.println("\r\nGPSlogger");
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, LOW);


  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card init. failed!");
  }


  strcpy(buffer, "LOG00.TXT");
  for (i = 0; i < 100; i++) {
    buffer[3] = '0' + i/10;
    buffer[4] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (!SD.exists(buffer)) {
      break;
    }
  }

  logfile = SD.open(buffer, FILE_WRITE);
  Serial.println(buffer);
 
  // connect to the GPS at the desired rate
  gpsSerial.begin(GPSRATE);
 
  gpsSerial.print(SERIAL_SET);
  delay(250);

//Write following configurations to GPS module
 gpsSerial.print(DDM_OFF);
 delay(250);
 gpsSerial.print(GGA_OFF);
 delay(250);
 gpsSerial.print(GLL_OFF);
 delay(250);
 gpsSerial.print(GSA_OFF);
 delay(250);
 gpsSerial.print(GSV_OFF);
 delay(250);
 gpsSerial.print(RMC_ON);
 delay(250);
 gpsSerial.print(VTG_OFF);
 delay(250);
 gpsSerial.print(WAAS_OFF);
}


void loop() {
  //Serial.println(Serial.available(), DEC);
  char inBuffer[BUFFSIZE];    // buffer used to read NMEA lines from GPS
  memset(inBuffer, 0, sizeof(inBuffer));
/*  inBuffer = ;
  outBuffer[0] = '\0';*/ 
  int sizeBuffer = 0;

  // read one 'line'
  while (!gpsSerial.available()){
  }
 
  char c = gpsSerial.read();
  if (c != '$') {
    return;
  }

    sizeBuffer = gpsSerial.readBytesUntil('\n', inBuffer, BUFFSIZE);  // read one NMEA line from GPS until end of line

    // find out if we got a fix
    char *p = inBuffer;
    p = strchr(p, ',')+1;
    p = strchr(p, ',')+1;       // skip to 3rd item
       
    if (p[0] == 'A') {
      fix = true;
    } else {
        fix = false;
    }
   
    if (LOG_RMC_FIXONLY) {
      if (!fix) {
        return;
      } //if (!fix)
    } //if (LOG_RMC_FIXONLY)
   
    if (SHOW_SERIAL) {
      Serial.println(inBuffer);
    }   
   
    // Lets log it!
    logfile.write((uint8_t *) inBuffer, sizeBuffer);    //write the string to the SD file
    logfile.write('\n');
    logfile.flush();
     
  for (uint8_t cnt = 0; cnt < SENSOR_READINGS; cnt++) {
    String stringSensor = "";
    int Zvolts = 0;
    int Sonarmm = analogRead(A0);
    delay(10);
    //int Sonarmm = pulseIn(Sonarpin, HIGH);
    for (uint8_t cntf = 0; cntf < SENSOR_FILTER; cntf++) {     
        Zvolts = Zvolts + analogRead(A2);
        delay(5);
    }
    stringSensor += String(Zvolts);
    stringSensor += ",";
    stringSensor += String(Sonarmm);
    logfile.println(stringSensor);
    logfile.flush();

    if (SHOW_SERIAL) {
      Serial.println(stringSensor);
    }//if (SHOW_SERIAL)
  }
}

/* End code */


Logged

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

Quote
But after a while it stops logging.
Possibly because it runs out of memory.

String and SD don't really belong in the same sketch.
Logged

Offline Offline
Edison Member
*
Karma: 43
Posts: 1548
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The original code seems to have been using a C string instead of the String class:
Code:
//char stringSensor[20];

Change your code so that it uses C strings and the problem with String class garbage collection will go away.

Pete
Logged

Where are the Nick Gammons of yesteryear?

Pages: [1]   Go Up
Jump to: