Adafruit Ultimate GPS on Mega Not Writing to SD

I am building a GPS tracking project to be used in agriculture. I am in way over my head but am very persistent (a common problem for farmers). I started out with the Adafruit Ultimate GPS Shield on an Uno. The Uno limited memory was a problem as the lat/long data will be used in calculations to show location relative to numbered tree rows. The Uno version did write to the SD card. Then switched to a Mega 2560 and have gotten all of the functions to work except writing data to the SD card. Hopefully there is an easy fix in the sketch.

The hardware is:
Arduino R3 2560
Adafruit Ultimate GPS shield
Adafruit Standard LCD 20X4 Product 198 with i2C/SPI back pack

QGP Waterproof 28dB Gain Antenna (Amazon)

Attached images show the LCD display and the Mega with shield.

Wiring numbers are the actual pin numbers printed on the MEGA .

Wiring is:
I2C back pack…5V to 5V, GND to GND, CLK to 21, DAT to 20

Ultimate GPS Shield:…3V to 14, CD to 14, CCS to 15, PPS to 16, PPS to 17, TX to 19, RX to 18…not a typo TX to 19, RX to 18….

Currently LCD displays time, Lat, Long, Speed…works well in the field but won’t write to SD card.

Serial monitor displays correctly.

Here is the current version of the sketch.

#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h> 
//#include <SDADA.h>
#include <avr/sleep.h>
#include <Adafruit_LiquidCrystal.h>


#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);
Adafruit_LiquidCrystal lcd(0);


#define GPSECHO  true

 boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy



#define chipSelect 10
#define ledPin 13
 uint32_t timer = millis();
File logfile;



void error(uint8_t errno) {
  /*
  if (SD.errorCode()) {
   putstring("SD error: ");
   Serial.print(card.errorCode(), HEX);
   Serial.print(',');
   Serial.println(card.errorData(), HEX);
   }
   */
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}


void setup()  
{


 
  Serial.begin(115200);
  delay(1000);
lcd.begin(20, 4); // pins for lcd, analog 4,5
  delay(500);

lcd.setBacklight(HIGH);
 
 
 lcd.print("Wait for it..");
  delay(500);

  
  GPS.begin(9600);
    delay(500);

  
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  
  GPS.sendCommand(PGCMD_ANTENNA);

  delay(1000);
   mySerial.println(PMTK_Q_RELEASE);
 Serial.println("\r\nUltimate GPSlogger Shield");
  pinMode(ledPin, OUTPUT);

  // make sure that the default chip select pin is set to
  
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect, 11, 12, 13)) {
  //  if (!SD.begin(chipSelect)) {      // if you're using an UNO, you can use this line instead
    Serial.println("Card init. failed!");
    error(2);
  }
  char filename[15];
  strcpy(filename, "GPSLOG00.TXT");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }
  }

  logfile = SD.open(filename, FILE_WRITE);
  if( ! logfile ) {
    Serial.print("Couldnt create "); 
    Serial.println(filename);
    error(3);
  }
  Serial.print("Writing to "); 
  Serial.println(filename);

 
}

void loop()                     // run over and over again
{
 
  char c = GPS.read();
  
  if ((c) && (GPSECHO))
    Serial.write(c); 
  
  
  if (GPS.newNMEAreceived()) {
      
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  
  if (timer > millis())  timer = millis();

  
  if (millis() - timer > 2000) { 
    timer = millis(); // reset the timer
    
    Serial.print("\nTime: ");
    Serial.print(GPS.hour, DEC); Serial.print(':');
    Serial.print(GPS.minute, DEC); Serial.print(':');
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    Serial.println(GPS.milliseconds);
    Serial.print("Date: ");
    Serial.print(GPS.day, DEC); Serial.print('/');
    Serial.print(GPS.month, DEC); Serial.print("/20");
    Serial.println(GPS.year, DEC);
    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality); 
    if (GPS.fix) {
      Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", "); 
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);      
      Serial.print("Speed (knots): "); Serial.println(GPS.speed);
      Serial.print("Angle: "); Serial.println(GPS.angle);
      Serial.print("Altitude: "); Serial.println(GPS.altitude);
      Serial.print("Satellites: "); Serial.println((int)GPS.satellites);

 lcd.setCursor(0, 0);
float lat = GPS.latitude*0.01;
 lcd.print("Lat:   ");
lcd.print (lat,0);
lcd.print (".");
float decpart;
decpart=lat -(int(lat));
float decparted=decpart/60;
lcd.print (decparted*10000000000,0);

float lon = GPS.longitude*0.01;
 lcd.setCursor(0, 1);
 lcd.print("Long: ");
lcd.print (lon,0);
float decpart1;
decpart1=lon -(int(lon));
float decparted1=decpart1/60;
if(decparted1<.1)      
lcd.print (".0");
lcd.print (decparted1*10000000000,0);

float speed = GPS.speed;
 lcd.setCursor(0, 2);
 lcd.print("Speed(mph): ");
lcd.print (int(speed)/1.151, 4);

lcd.setCursor(0, 3);
int ghour = GPS.hour; 
int gminute = GPS.minute; 
lcd.print("Time:        ");
if(ghour<8)  //8 for ca
lcd.print (int(ghour+17)); //17 for ca
else
lcd.print (int(ghour-7));// 7 for ca
lcd.print (":");
if(gminute<10)
  lcd.print ("0"); 
lcd.print (int(gminute), DEC);
  
      Serial.println("Log");




 

  



   
    
    }
  }
}

Thanks in advance for any and all help.

You never write anything to logfile and you never close it.

Pete

Thanks for the reply...as I said I am in way over my head, being a complete newb at this and a 68 year old farmer. Your response is a case of "pearls before swine"...can you expand your answer or show me the needed commands and where I would add it...I am trying to Google your suggestion for more help...

To print to the SD file, once it is open, you can use statements similar to Serial.print.

  logfile.print("Location: ");

println also works.

When you have finished writing to the SD card, you must close the file:

  logfile.close();

If you don't do this, the file may not be written, or only part of it will be written.

Pete

Images embedded for our convenience:

Technique described here.

Where did you get “Adafruit_lcd.h”? That must be extremely old, maybe as old as you are. :wink:

To get the best answers, provide links to the libraries, or attach the LCD library files to your post. Press the Preview button to get the complete post editor window, the select Attachments and other options.

el_supremo:
When you have finished writing to the SD card, you must close the file:

Some people add a switch that you can read in the sketch for “shutdown”. That’s a good time to close the file.

You can also periodically flush the file:

    logfile.flush();

This leaves the file open for writing more records. You can call this after each GPS update, if you want. It takes a little more time, but you’re only getting updates once per second.

You don’t need the SoftwareSerial include statement, because a Mega has 4 HardwareSerial ports. You are connecting to Serial1 (pins 18 & 19) and using it through a #define, so just delete the include statement.

You might be interested in my NeoGPS library. It’s smaller, faster, more accurate and more reliable than all other GPS libraries. Even if you don’t use it, there are lots of tips on the Troubleshooting page.

I have attached a NeoGPS version of your sketch. It calculates the timezone correctly, including offsets into a different day, month or year, and the Daylight Saving Time changeover (for the USA). It also writes the GPS data to the SD logfile and flushes it once per second.

Your original sketch uses 23350 bytes of program space and 1898 bytes of RAM.
The NeoGPS version uses 22834 bytes of program space and 1247 bytes of RAM.

If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch → Include Library → Manage Libraries.

Cheers,
/dev

Farmer1949.ino (7.22 KB)

Thanks for all the good input. Will try to implement it in the morning. I'd work on it now, but being sooo old, I need my sleep...LOL

-dev

Thanks so much for the updated sketch it worked first time! Something that I have never experienced before!!!

You saved me several days of floundering and frustration. I know I will be back for more help. Thanks again!!

Hey guys,

Thanks for the help. I'm working on this with my dad. Finally have some time to work on it and you guys moved us to the next problem. El Supremo had it right in the first post. I missed those two lines when combining sketches. And I'm also excited to try the Neo GPS library.

We're now looking to plot some rows. We have the data points for a few and need to plot an AB line. Is there a program to help with this from points? Or is it some good old fashioned y=ax+b ? Any more great tips would be appreciated.

Thanks again El Supremo and -dev. You really made our weekend more productive.

The data you seem to be collecting are latitude/longitude, date/time and speed. How do you intend to plot them and what sort of equation are you expecting to get? You could use Excel to plot data and also come up with a regression line but I don't know Excel well enough to help.

Pete

I was thinking i could convert the lat and long points into decimal degrees. Then I could use a couple of points to create the abline. Just a linear equation with the points. Then further rows would be identified by their offset distance. How hard could it be, right?