HC-SR04, GPS, and SD card reader with Arduino MEGA

I’m almost done with this project. I have gotten everything to work except when the Arduino is uploading the HC-SR04 distance measurements to the SD card, they aren’t accurate. It will give an accurate reading here or there but it either will default to 18cm or 0cm. I’ll upload the code. The function SDCARD1() is the code to upload the measurement from the HC-SR04 to the SD card. I tried including that code into the Ping function itself but it still didn’t work. It seems like the SD card upload is the part messing it up because the Serial.prints I use in the Ping function code are all accurate for these measurements. Any suggestions?

#include <NewPing.h> 
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <SPI.h> 
SoftwareSerial mySerial(11,10); 
Adafruit_GPS GPS(&mySerial); 

char c; 
String NMEA1;
String NMEA2;

#define TRIGGER_PIN 31
#define ECHO_PIN 33
#define MAX_DISTANCE 200 
#define pingSpeed 2000 
#define chipSelect 53 
unsigned long pingTimer1, pingTimer2, pingTimer3, pingTimer4; 
NewPing sonar(31,33,65); 

File myFile; 

void setup() {
  Serial.begin(115200); 
  pingTimer1 = millis() + pingSpeed; 
  pingTimer2 = pingTimer1 + (pingSpeed/2);
  pingTimer3= pingTimer2 + pingSpeed;
  pingTimer4= pingTimer3 + pingSpeed; 
  GPS.begin(9600); 
  GPS.sendCommand("$PGCMD,33,0*6D");
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);

  if(!SD.begin(53)) {
    Serial.println(F("not beginning"));
    return;
  }
  Serial.println(F("its working")); 
  
  
 
  if(! SD.remove("ultrad.txt")){
    Serial.println(F("ultra not working"));
    
  }
  
  if(!SD.remove("gps.txt")){
  Serial.println(F("gps not working"));
  return;
  }
}

void loop() {

if(millis()>= pingTimer1) {
  pingTimer1 += pingSpeed; 
  Ping();
}

if (millis() >= pingTimer2) {
  pingTimer2 = pingTimer1 + (pingSpeed/2);
  GPSdata(); 
}

if (millis() >= pingTimer3) {
  pingTimer3 = pingTimer2 + pingSpeed; 
  SDCARD1(); 
}

if(millis() >= pingTimer4) {
  pingTimer4 = pingTimer3 + pingSpeed;
  SDCARD2(); 
}
}

void Ping(){
 delay(50);
 Serial.print(F("Ping: ")); 
 Serial.print(sonar.ping_cm()); 
 Serial.println(F("cm"));

}

void GPSdata() { 
   
  clearGPS();
  while(!GPS.newNMEAreceived()) { //loop until you have a good NMEA sentence
    c=GPS.read(); 
  }
  GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
  NMEA1=GPS.lastNMEA();

  while(!GPS.newNMEAreceived()) { //loop until you have a good NMEA sentence
    c=GPS.read(); 
  }
  GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
  NMEA2=GPS.lastNMEA();

  Serial.print(GPS.latitude); 
  Serial.print(F(",")); 
  Serial.println(GPS.longitude);
  Serial.print(GPS.hour, DEC);Serial.print(':'); 
  Serial.println(GPS.minute, DEC);

 
 
}

void clearGPS() {

   while(!GPS.newNMEAreceived()) { //loop until you have a good NMEA sentence
    c=GPS.read(); 
  }
  GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
  while(!GPS.newNMEAreceived()) { //loop until you have a good NMEA sentence
    c=GPS.read(); 
  }
  GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
   while(!GPS.newNMEAreceived()) { //loop until you have a good NMEA sentence
    c=GPS.read(); 
}
}

void SDCARD1(){
  
  myFile = SD.open("ultrad.txt", FILE_WRITE); 
  myFile.print(sonar.ping_cm());
  myFile.print(","); 
  myFile.print("cm");
  myFile.print(",");
  myFile.print(GPS.hour, DEC);myFile.print(':'); 
  myFile.println(GPS.minute, DEC);  
  myFile.close(); 
}  

 
void SDCARD2(){  
  myFile = SD.open("gps.txt", FILE_WRITE); 
  myFile.print(GPS.latitude);
  myFile.print(","); 
  myFile.print(GPS.longitude);
  myFile.print(","); 
  myFile.print(GPS.hour, DEC);myFile.print(':'); 
  myFile.println(GPS.minute, DEC);  
  myFile.close();
}

Any suggestions?

Ok, I'll try to help again...

1) SoftwareSerial interferes with NewPing. Your Mega has 4 serial ports, so why are you using SoftwareSerial? Connect the GPS module to Serial1, Serial2 or Serial3 (pins 14-19).

2) Your "pingTimers" aren't sequenced correctly, and they aren't coordinated with the GPS clock.

3) Don't use String™. Use char arrays instead, but...

4) Don't use Adafruit_GPS and you won't even need Strings or char arrays. It also interferes with NewPing.

5) I gave you a sketch on your other post that was small enough to fit on an UNO. Did you try it?

Sometimes, being "almost done" is as close as you'll get with a certain program structure.

Cheers, /dev

I thought that my sketch would work eventually so I did not try it. I am going to try your sketch today sometime, thanks!

When I connect the GPS to the serial ports(14-19) on the Mega, will I still be able to use the gps even when not connected to my computer? The plan is to make this a mobile device.

I will try that other sketch you provided today sometime and get back about how that works. Thanks again, really appreciate it.

When I connect the GPS to the serial ports(14-19) on the Mega, will I still be able to use the gps even when not connected to my computer? The plan is to make this a mobile device.

Yes, if the Mega is still connected to the GPS.

The USB connection to your PC uses pins 0 & 1 for Serial, so those are the only pins that are "disconnected" when you go mobile. The Arduino won't even notice.

I connected the TX from the GPS to pin 14, and RX to pin 15. So now I can just get rid of the " SoftwareSerial(TX,RX)" line in the beginning of my code since they are in the serial ports now?

Well, I can’t really see your code… :-/ If you are talking about the sketch I provided, then you should have this at the top:

#include <SPI.h> 

#include "NMEAGPS.h"

HardwareSerial & gps_port = Serial3; // an "alias"
NMEAGPS          gps;

Notice I deleted the NeoSWSerial include, and changed the gps_port line.

Using pins 14 and 15 corresponds to Serial3, as shown above. However, Arduino pin 14 (TX3), should go to the GPS RX pin, and Arduino pin 15 (RX3) should go to the GPS TX pin.

Cheers,
/dev