I have been fighting this seemingly random issue on my Fastrax GPS UP501 module not accepting my commands. I have tested this directly connected(via a breadboard circuit) to my Uno R3, on an AF gps shield, via my MicroView OLED and finally connected to my Uno via a Sparkfun uSD shield with a connector/circuit on the proto space. At first i thought it was a physical connection issue but for it to happen randomly in all the different configurations makes me think otherwise.
General overview: I am sending 2 commands, RMCONLY and UPDATE 10HZ as seen in the code below. I have the GPS module running at the default 9600bps(when i kicked it up i was getting garbage on the serial monitor and SD card). I would say about 75% of the time i get the RMC data at 10HZ just fine. If i reset the Arduino it always keeps the RMC/10HZ setting and spits data out how i would expect. The issue seems to happen when its first powered up with a 9v battery pack or reconnected via USB to program/debug. It doesn't matter how many times i reset the board it spits out all NMEA data. When i check my SD card i am getting 1HZ updates but double printing the data. In order to get the RMC/10HZ to work i have to unplug and power the board up a few times before it finally seems to take.
What i would like to know is: Am i doing something wrong in the sketch? Should I be passing other commands, adding a delay in there or something else? I don't currently have any "wait for good data" functions in place but i plan to add them. I would assume i could maybe ask for the current setting from the GPS module and if its not RMC and 10hz to resent the commands back to gpsSerial. I just can't seem to figure out why its random.
Thanks for any and all insight!!
#include <SPI.h>
#include <SdFat.h>
#include <TinyGPS.h>
//#include <SoftwareSerial.h>
#include <gSoftSerial.h>
long lat, lon;
unsigned long fix_age, date, time, speed, altitude, course;
float CorrectedSpeed, CorrectedLon, CorrectedLat;
const int chipSelect = 8;
//#define PMTK_SET_NMEA_BAUDRATE_38400 "$PMTK251,38400*1F" // Set Baud Rate to 38400
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29" // only RMC data
File logfile;
gSoftSerial gpsSerial (2,3); // create gps sensor connection
TinyGPS gps; // create gps object
SdFat SD; // create SD object
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
gpsSerial.begin(9600);
gpsSerial.println(PMTK_SET_NMEA_OUTPUT_RMCONLY); // turn on only RMC
gpsSerial.println(PMTK_SET_NMEA_UPDATE_10HZ); // turn on 10Hz
while (!Serial) {
; // wait for serial port to connect.
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
char filename[15];
strcpy(filename, "data_00.txt");
for (uint8_t i=0; i<100; i++) {
filename[5] = '0' + i/10;
filename[6] = '0' + i%10;
if (!SD.exists(filename)) {
break;
}
}
logfile = SD.open(filename, FILE_WRITE);
if(!logfile) {
Serial.print("Couldnt create ");
Serial.println(filename);
while (1) {}
}
Serial.print("Writing to ");
Serial.println(filename);
logfile.println("latitude, longitude, speed, time");
}
void loop() {
while(gpsSerial.available()>0){ // check for gps data
// char c = gpsSerial.read(); // read gps data into char c
// Serial.print(c); // pring NMEA RMC strings to the Serial Monitor, this is here to figure if its passing all NMEA sentences or just RMC for debug
if (gps.encode(gpsSerial.read())){
gps.get_position(&lat, &lon, &fix_age); // get GPS lat, lon and fix age variables
gps.get_datetime(&date, &time, &fix_age); // get GPS date, time and fix age, when i tried to omit the date variable i had bad results
speed = gps.speed(); // get speed value in 100th of a knot from TinyGPS
CorrectedSpeed = speed * 0.0115; // convert speed to mph
CorrectedLon = lon * 1E-6; // Convert Longitude to a normal value for GPS Visualizer
CorrectedLat = lat * 1E-6; // Convert Latitude to a normal value for GPS Visualizer
Serial.print(((float)CorrectedLat),8);Serial.print(",");Serial.print(((float)CorrectedLon), 8);Serial.print(",");Serial.println(time); // print data to serial monitor for debug
logfile.print(((float)CorrectedLat),8);logfile.print(","); // print CorrectedLat to SD with 8 decimal places
logfile.print(((float)CorrectedLon),8);logfile.print(","); // print CorrectedLon to SD with 8 decimal places
logfile.print(CorrectedSpeed);logfile.print(","); // print CorrectedSpeed to SD
logfile.println(time); // print time string from RMC, no conversion yet
logfile.flush(); // flush to push the data to the SD without having to close it
}
}
}